makaron-cli 0.10.0 → 0.11.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.
- package/.claude-plugin/plugin.json +2 -2
- package/.codex-plugin/plugin.json +5 -5
- package/README.md +17 -0
- package/bin/makaron.mjs +217 -3
- package/package.json +1 -1
- package/skills/makaron/SKILL.md +26 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "makaron-cli",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "AI image editing, video generation,
|
|
3
|
+
"version": "0.11.0",
|
|
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",
|
|
7
7
|
"url": "https://www.makaron.app"
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "makaron-cli",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "AI image editing, video generation,
|
|
3
|
+
"version": "0.11.0",
|
|
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",
|
|
7
|
-
"longDescription": "makaron.app is for humans. makaron-cli is for AI agents. Talk to Makaron Agent from the terminal — create projects
|
|
7
|
+
"longDescription": "makaron.app is for humans. makaron-cli is for AI agents. Talk to Makaron Agent from the terminal — list, search, show, and install marketplace skills; create projects; edit images; generate videos; and compose music. Zero dependencies, single file, works with npx. Agents can self-register to get an API key without human intervention.",
|
|
8
8
|
"author": {
|
|
9
9
|
"name": "Makaron AI",
|
|
10
10
|
"url": "https://www.makaron.app"
|
|
@@ -12,9 +12,9 @@
|
|
|
12
12
|
"homepage": "https://www.makaron.app/agent",
|
|
13
13
|
"repository": "https://github.com/vegekyd/ai-image-editor",
|
|
14
14
|
"license": "MIT",
|
|
15
|
-
"keywords": ["ai", "image-editing", "video", "music", "agent", "creative"],
|
|
15
|
+
"keywords": ["ai", "image-editing", "video", "music", "agent", "creative", "skills"],
|
|
16
16
|
"category": "Creative Tools",
|
|
17
|
-
"capabilities": ["image-editing", "video-generation", "music-creation", "text-to-image"],
|
|
17
|
+
"capabilities": ["image-editing", "video-generation", "music-creation", "text-to-image", "marketplace-skills"],
|
|
18
18
|
"skills": "./skills/",
|
|
19
19
|
"websiteURL": "https://www.makaron.app",
|
|
20
20
|
"brandColor": "#d946ef"
|
package/README.md
CHANGED
|
@@ -107,6 +107,23 @@ Returns immediately:
|
|
|
107
107
|
| Add music | `npx makaron-cli chat --project <id> "add calm piano background music"` |
|
|
108
108
|
| Create motion design | `npx makaron-cli chat --project <id> "make an animated Instagram story with this image"` |
|
|
109
109
|
|
|
110
|
+
### Marketplace skills
|
|
111
|
+
|
|
112
|
+
External users can browse, install, and use marketplace skills with only `MAKARON_API_KEY`:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
npx makaron-cli skills list
|
|
116
|
+
npx makaron-cli skills search "football"
|
|
117
|
+
npx makaron-cli skills search "足球"
|
|
118
|
+
npx makaron-cli skills show <marketplace-id-or-label>
|
|
119
|
+
npx makaron-cli skills install <marketplace-id-or-label>
|
|
120
|
+
|
|
121
|
+
# chat auto-installs matched marketplace skills before starting the run
|
|
122
|
+
npx makaron-cli chat --project auto --image selfie.jpg --skill <marketplace-id-or-label> -b "make this with the selected skill"
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
`--skill` accepts an installed skill name, a marketplace UUID, or a unique marketplace label. If a marketplace skill is matched, the CLI installs or reuses it and sends `[Active skill: <installed-skill-name>]` to Makaron Agent. Ordinary users do not need admin commands, and the CLI intentionally does not expose skill deletion.
|
|
126
|
+
|
|
110
127
|
### With additional images (existing project)
|
|
111
128
|
|
|
112
129
|
```bash
|
package/bin/makaron.mjs
CHANGED
|
@@ -792,6 +792,155 @@ function timeSince(date) {
|
|
|
792
792
|
return `${Math.floor(s / 86400)}d ago`;
|
|
793
793
|
}
|
|
794
794
|
|
|
795
|
+
// ─── Skill Marketplace ──────────────────────────────────────────────────────
|
|
796
|
+
|
|
797
|
+
function getSkillLabel(skill) {
|
|
798
|
+
return skill.labels?.en || skill.labels?.zh || skill.label || skill.name || skill.id;
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
function slugifySkill(value) {
|
|
802
|
+
return String(value || '')
|
|
803
|
+
.toLowerCase()
|
|
804
|
+
.normalize('NFKD')
|
|
805
|
+
.replace(/[\u0300-\u036f]/g, '')
|
|
806
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
807
|
+
.replace(/^-+|-+$/g, '');
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
function normalizeMarketplaceSkill(skill) {
|
|
811
|
+
return {
|
|
812
|
+
...skill,
|
|
813
|
+
label: getSkillLabel(skill),
|
|
814
|
+
skillPath: skill.skillPath || skill.skill_path || null,
|
|
815
|
+
hasSkill: Boolean(skill.skillPath || skill.skill_path),
|
|
816
|
+
};
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
async function fetchMarketplaceSkills(baseUrl, opts = {}) {
|
|
820
|
+
let res;
|
|
821
|
+
try {
|
|
822
|
+
res = await fetch(`${baseUrl}/api/home-skills`);
|
|
823
|
+
} catch (err) {
|
|
824
|
+
if (opts.optional) return null;
|
|
825
|
+
process.stderr.write(`Failed to load marketplace skills: ${err.message || err}\n`);
|
|
826
|
+
process.exit(1);
|
|
827
|
+
}
|
|
828
|
+
if (!res.ok) {
|
|
829
|
+
if (opts.optional) return null;
|
|
830
|
+
process.stderr.write(`Error ${res.status}: ${await res.text()}\n`);
|
|
831
|
+
process.exit(1);
|
|
832
|
+
}
|
|
833
|
+
const data = await res.json();
|
|
834
|
+
const skills = Array.isArray(data) ? data : (data.skills || []);
|
|
835
|
+
return skills.map(normalizeMarketplaceSkill);
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
function marketplaceSearchText(skill) {
|
|
839
|
+
return [
|
|
840
|
+
skill.id,
|
|
841
|
+
skill.label,
|
|
842
|
+
skill.labels?.en,
|
|
843
|
+
skill.labels?.zh,
|
|
844
|
+
skill.prompt,
|
|
845
|
+
slugifySkill(skill.label),
|
|
846
|
+
slugifySkill(skill.labels?.en),
|
|
847
|
+
slugifySkill(skill.labels?.zh),
|
|
848
|
+
].filter(Boolean).join(' ').toLowerCase();
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
function marketplaceSkillTokens(skill) {
|
|
852
|
+
return [
|
|
853
|
+
skill.id,
|
|
854
|
+
skill.label,
|
|
855
|
+
skill.labels?.en,
|
|
856
|
+
skill.labels?.zh,
|
|
857
|
+
skill.prompt,
|
|
858
|
+
].filter(Boolean).map(value => String(value).toLowerCase());
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
function findMarketplaceSkill(skills, identifier) {
|
|
862
|
+
const raw = String(identifier || '').trim();
|
|
863
|
+
if (!raw) return null;
|
|
864
|
+
const lower = raw.toLowerCase();
|
|
865
|
+
const slug = slugifySkill(raw);
|
|
866
|
+
const exact = skills.filter(skill => {
|
|
867
|
+
const labels = Object.values(skill.labels || {}).map(v => String(v).toLowerCase());
|
|
868
|
+
const slugMatches = slug
|
|
869
|
+
? slugifySkill(getSkillLabel(skill)) === slug ||
|
|
870
|
+
Object.values(skill.labels || {}).some(v => slugifySkill(v) === slug)
|
|
871
|
+
: false;
|
|
872
|
+
return skill.id === raw ||
|
|
873
|
+
skill.id?.toLowerCase() === lower ||
|
|
874
|
+
getSkillLabel(skill).toLowerCase() === lower ||
|
|
875
|
+
labels.includes(lower) ||
|
|
876
|
+
slugMatches;
|
|
877
|
+
});
|
|
878
|
+
if (exact.length === 1) return exact[0];
|
|
879
|
+
if (exact.length > 1) {
|
|
880
|
+
process.stderr.write(`Multiple marketplace skills match "${raw}". Use an id:\n`);
|
|
881
|
+
exact.forEach(skill => process.stderr.write(` ${skill.id} ${skill.label}\n`));
|
|
882
|
+
process.exit(1);
|
|
883
|
+
}
|
|
884
|
+
const prefix = skills.filter(skill => skill.id?.startsWith(raw));
|
|
885
|
+
if (prefix.length === 1) return prefix[0];
|
|
886
|
+
return null;
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
function printMarketplaceSkills(skills) {
|
|
890
|
+
if (!skills.length) {
|
|
891
|
+
console.log('No marketplace skills found.');
|
|
892
|
+
return;
|
|
893
|
+
}
|
|
894
|
+
console.log(`📦 ${skills.length} marketplace skills\n`);
|
|
895
|
+
for (const skill of skills) {
|
|
896
|
+
const kind = skill.hasSkill ? 'skill' : 'prompt';
|
|
897
|
+
console.log(` ${skill.id} ${skill.label} [${kind}]`);
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
function printMarketplaceSkill(skill) {
|
|
902
|
+
console.log(`${skill.label}`);
|
|
903
|
+
console.log(`ID: ${skill.id}`);
|
|
904
|
+
console.log(`Type: ${skill.hasSkill ? 'installable skill' : 'prompt template'}`);
|
|
905
|
+
if (skill.labels?.zh && skill.labels.zh !== skill.label) console.log(`ZH: ${skill.labels.zh}`);
|
|
906
|
+
if (skill.prompt) console.log(`Prompt: ${skill.prompt}`);
|
|
907
|
+
if (skill.image) console.log(`Cover: ${skill.image}`);
|
|
908
|
+
if (skill.hasSkill) console.log(`Install: makaron skills install ${skill.id}`);
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
async function installMarketplaceSkill(baseUrl, headers, skill, opts = {}) {
|
|
912
|
+
if (!skill.hasSkill) {
|
|
913
|
+
process.stderr.write(`"${skill.label}" is a prompt-only marketplace item and has no installable skill package.\n`);
|
|
914
|
+
process.exit(1);
|
|
915
|
+
}
|
|
916
|
+
if (!opts.quiet) process.stderr.write(`📦 Installing skill: ${skill.label}\n`);
|
|
917
|
+
const res = await fetch(`${baseUrl}/api/skills`, {
|
|
918
|
+
method: 'POST',
|
|
919
|
+
headers: { 'Content-Type': 'application/json', ...headers },
|
|
920
|
+
body: JSON.stringify({ skillPath: skill.skillPath, homeSkillId: skill.id }),
|
|
921
|
+
});
|
|
922
|
+
const data = await res.json().catch(() => ({}));
|
|
923
|
+
if (!res.ok || !data.success) {
|
|
924
|
+
process.stderr.write(`Install failed: ${data.error || res.status}\n`);
|
|
925
|
+
process.exit(1);
|
|
926
|
+
}
|
|
927
|
+
if (!opts.quiet) {
|
|
928
|
+
const suffix = data.alreadyInstalled ? 'already installed' : 'installed';
|
|
929
|
+
process.stderr.write(`✅ Skill ${suffix}: ${data.skillName}\n`);
|
|
930
|
+
}
|
|
931
|
+
return data;
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
async function resolveChatSkill(baseUrl, headers, activeSkill) {
|
|
935
|
+
if (!activeSkill) return undefined;
|
|
936
|
+
const skills = await fetchMarketplaceSkills(baseUrl, { optional: true });
|
|
937
|
+
if (!skills) return activeSkill;
|
|
938
|
+
const marketplaceSkill = findMarketplaceSkill(skills, activeSkill);
|
|
939
|
+
if (!marketplaceSkill) return activeSkill;
|
|
940
|
+
const result = await installMarketplaceSkill(baseUrl, headers, marketplaceSkill);
|
|
941
|
+
return result.skillName;
|
|
942
|
+
}
|
|
943
|
+
|
|
795
944
|
// ─── MCP Tool Caller ─────────────────────────────────────────────────────────
|
|
796
945
|
|
|
797
946
|
async function callMcpTool(baseUrl, headers, toolName, args) {
|
|
@@ -1068,6 +1217,7 @@ Commands:
|
|
|
1068
1217
|
responses get <runId> --wait Poll until completed
|
|
1069
1218
|
responses list --project <id> List runs for a project
|
|
1070
1219
|
abort <runId> Abort a running Agent
|
|
1220
|
+
skills list|search|show|install Browse and install marketplace skills
|
|
1071
1221
|
|
|
1072
1222
|
edit [--image <file>] "prompt" AI image edit / text-to-image
|
|
1073
1223
|
analyze --video <file|url> Analyze video content
|
|
@@ -1109,6 +1259,20 @@ function printHelp(topic, subtopic) {
|
|
|
1109
1259
|
`);
|
|
1110
1260
|
} else if (topic === 'abort') {
|
|
1111
1261
|
console.log('Usage: makaron abort <runId>');
|
|
1262
|
+
} else if (topic === 'skills') {
|
|
1263
|
+
if (subtopic === 'list') console.log('Usage: makaron skills list [--json]');
|
|
1264
|
+
else if (subtopic === 'search') console.log('Usage: makaron skills search <query> [--json]');
|
|
1265
|
+
else if (subtopic === 'show') console.log('Usage: makaron skills show <marketplace-id|label> [--json]');
|
|
1266
|
+
else if (subtopic === 'install') console.log('Usage: makaron skills install <marketplace-id|label> [--json]');
|
|
1267
|
+
else console.log(`Skill marketplace commands:
|
|
1268
|
+
skills list List marketplace skills
|
|
1269
|
+
skills search <query> Search marketplace skills
|
|
1270
|
+
skills show <id|label> Show a marketplace skill
|
|
1271
|
+
skills install <id|label> Install a marketplace skill to your workspace
|
|
1272
|
+
|
|
1273
|
+
Use with chat:
|
|
1274
|
+
makaron chat --project auto --skill <id|label> "your request"
|
|
1275
|
+
`);
|
|
1112
1276
|
} else if (topic === 'edit') {
|
|
1113
1277
|
console.log('Usage: makaron edit [--image <file|url>] [--model gemini|qwen|openai] [--skill enhance|creative|wild|captions] [--ref <file>] [--out <file>] "prompt"');
|
|
1114
1278
|
} else if (topic === 'analyze') {
|
|
@@ -1206,6 +1370,7 @@ if (!command || command === '--help' || command === '-h' || command === 'help')
|
|
|
1206
1370
|
else if (args[i] === '--image' && args[i + 1]) chatImages.push(args[++i]);
|
|
1207
1371
|
else if (args[i] === '--video' && args[i + 1]) chatVideos.push(args[++i]);
|
|
1208
1372
|
else if (args[i] === '--skill' && args[i + 1]) activeSkill = args[++i];
|
|
1373
|
+
else if (args[i].startsWith('--skill=')) activeSkill = args[i].slice('--skill='.length);
|
|
1209
1374
|
else if (args[i] === '--stream') useStream = true;
|
|
1210
1375
|
else if (args[i] === '--background' || args[i] === '-b') background = true;
|
|
1211
1376
|
else if (args[i] === '--json') jsonOutput = true;
|
|
@@ -1297,8 +1462,10 @@ if (!command || command === '--help' || command === '-h' || command === 'help')
|
|
|
1297
1462
|
}
|
|
1298
1463
|
}
|
|
1299
1464
|
|
|
1465
|
+
const resolvedSkill = await resolveChatSkill(baseUrl, headers, activeSkill);
|
|
1466
|
+
|
|
1300
1467
|
// Upload videos to project timeline (via /api/projects/create with videoUrls)
|
|
1301
|
-
let finalPrompt =
|
|
1468
|
+
let finalPrompt = resolvedSkill ? `[Active skill: ${resolvedSkill}]\n${prompt}` : prompt;
|
|
1302
1469
|
if (chatVideos.length > 0) {
|
|
1303
1470
|
// Upload local files via signed URL (no size limit, works with API key auth)
|
|
1304
1471
|
const uploadedVideoUrls = [...prevalidatedVideoUrlList];
|
|
@@ -1376,10 +1543,9 @@ if (!command || command === '--help' || command === '-h' || command === 'help')
|
|
|
1376
1543
|
if (sub === 'get') {
|
|
1377
1544
|
const runId = args[2];
|
|
1378
1545
|
if (!runId) { console.error('Usage: makaron responses get <runId> [--wait] [--json] [--pick <field>]'); process.exit(1); }
|
|
1379
|
-
let wait = false,
|
|
1546
|
+
let wait = false, pick = null;
|
|
1380
1547
|
for (let i = 3; i < args.length; i++) {
|
|
1381
1548
|
if (args[i] === '--wait') wait = true;
|
|
1382
|
-
if (args[i] === '--json') jsonOutput = true;
|
|
1383
1549
|
if (args[i] === '--pick' && args[i + 1]) pick = args[++i];
|
|
1384
1550
|
}
|
|
1385
1551
|
|
|
@@ -1439,6 +1605,54 @@ if (!command || command === '--help' || command === '-h' || command === 'help')
|
|
|
1439
1605
|
} else if (command === 'list' || command === 'ls') {
|
|
1440
1606
|
const { headers, baseUrl } = getAuth();
|
|
1441
1607
|
await listProjects(baseUrl, headers);
|
|
1608
|
+
} else if (command === 'skills') {
|
|
1609
|
+
const sub = args[1] || 'list';
|
|
1610
|
+
const baseUrl = process.env.MAKARON_URL || DEFAULT_URL;
|
|
1611
|
+
const jsonOutput = args.includes('--json');
|
|
1612
|
+
|
|
1613
|
+
if (sub === 'list') {
|
|
1614
|
+
const skills = await fetchMarketplaceSkills(baseUrl);
|
|
1615
|
+
if (jsonOutput) console.log(JSON.stringify({ skills }, null, 2));
|
|
1616
|
+
else printMarketplaceSkills(skills);
|
|
1617
|
+
} else if (sub === 'search') {
|
|
1618
|
+
const query = args.filter((arg, index) => index > 1 && arg !== '--json').join(' ').trim();
|
|
1619
|
+
if (!query) { console.error('Usage: makaron skills search <query> [--json]'); process.exit(1); }
|
|
1620
|
+
const lowerQuery = query.toLowerCase();
|
|
1621
|
+
const slugQuery = slugifySkill(query);
|
|
1622
|
+
const skills = (await fetchMarketplaceSkills(baseUrl))
|
|
1623
|
+
.filter(skill => {
|
|
1624
|
+
const rawMatch = marketplaceSkillTokens(skill).some(token => token.includes(lowerQuery));
|
|
1625
|
+
const slugMatch = slugQuery ? marketplaceSearchText(skill).includes(slugQuery) : false;
|
|
1626
|
+
return rawMatch || slugMatch;
|
|
1627
|
+
});
|
|
1628
|
+
if (jsonOutput) console.log(JSON.stringify({ skills }, null, 2));
|
|
1629
|
+
else printMarketplaceSkills(skills);
|
|
1630
|
+
} else if (sub === 'show') {
|
|
1631
|
+
const identifier = args[2];
|
|
1632
|
+
if (!identifier) { console.error('Usage: makaron skills show <marketplace-id|label> [--json]'); process.exit(1); }
|
|
1633
|
+
const skills = await fetchMarketplaceSkills(baseUrl);
|
|
1634
|
+
const skill = findMarketplaceSkill(skills, identifier);
|
|
1635
|
+
if (!skill) { console.error(`Skill not found: ${identifier}`); process.exit(1); }
|
|
1636
|
+
if (jsonOutput) console.log(JSON.stringify(skill, null, 2));
|
|
1637
|
+
else printMarketplaceSkill(skill);
|
|
1638
|
+
} else if (sub === 'install') {
|
|
1639
|
+
const identifier = args[2];
|
|
1640
|
+
if (!identifier) { console.error('Usage: makaron skills install <marketplace-id|label> [--json]'); process.exit(1); }
|
|
1641
|
+
const { headers, baseUrl: authedBaseUrl } = getAuth();
|
|
1642
|
+
const skills = await fetchMarketplaceSkills(authedBaseUrl);
|
|
1643
|
+
const skill = findMarketplaceSkill(skills, identifier);
|
|
1644
|
+
if (!skill) { console.error(`Skill not found: ${identifier}`); process.exit(1); }
|
|
1645
|
+
const data = await installMarketplaceSkill(authedBaseUrl, headers, skill, { quiet: jsonOutput });
|
|
1646
|
+
if (jsonOutput) console.log(JSON.stringify({ ...data, marketplaceId: skill.id, label: skill.label }, null, 2));
|
|
1647
|
+
else console.log(data.skillName);
|
|
1648
|
+
} else {
|
|
1649
|
+
console.log(`Skill marketplace commands:
|
|
1650
|
+
skills list List marketplace skills
|
|
1651
|
+
skills search <query> Search marketplace skills
|
|
1652
|
+
skills show <id|label> Show a marketplace skill
|
|
1653
|
+
skills install <id|label> Install a marketplace skill to your workspace
|
|
1654
|
+
`);
|
|
1655
|
+
}
|
|
1442
1656
|
} else if (command === 'project' || command === 'projects') {
|
|
1443
1657
|
const { headers, baseUrl } = getAuth();
|
|
1444
1658
|
const sub = args[1];
|
package/package.json
CHANGED
package/skills/makaron/SKILL.md
CHANGED
|
@@ -96,6 +96,32 @@ Returns immediately:
|
|
|
96
96
|
| Add music | `npx makaron-cli chat --project <id> "add calm piano background music"` |
|
|
97
97
|
| Create motion design | `npx makaron-cli chat --project <id> "make an animated Instagram story with this image"` |
|
|
98
98
|
|
|
99
|
+
### Marketplace skills
|
|
100
|
+
|
|
101
|
+
Use marketplace skills when the user asks for a named Makaron effect, template, or skill such as "Football Captain", "足球队长", "World Cup MVP", or a marketplace UUID.
|
|
102
|
+
|
|
103
|
+
External users only need `MAKARON_API_KEY`; no admin permissions are required for listing, searching, showing, installing, or using marketplace skills.
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
# Browse public marketplace skills
|
|
107
|
+
npx makaron-cli skills list
|
|
108
|
+
npx makaron-cli skills search "football"
|
|
109
|
+
npx makaron-cli skills search "足球"
|
|
110
|
+
npx makaron-cli skills show <marketplace-id-or-label>
|
|
111
|
+
|
|
112
|
+
# Install a marketplace skill into the API key owner's workspace
|
|
113
|
+
npx makaron-cli skills install <marketplace-id-or-label>
|
|
114
|
+
|
|
115
|
+
# Use a marketplace skill. If the skill is not installed yet, chat auto-installs it,
|
|
116
|
+
# then injects the installed skill name into the agent run.
|
|
117
|
+
npx makaron-cli chat --project auto \
|
|
118
|
+
--image selfie.jpg \
|
|
119
|
+
--skill <marketplace-id-or-label> \
|
|
120
|
+
-b "make this with the selected skill"
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
`--skill` accepts an installed skill name, a marketplace UUID, or a unique marketplace label. If a marketplace skill is matched, the CLI installs or reuses it and sends `[Active skill: <installed-skill-name>]` to Makaron Agent. Do not call admin skill commands for ordinary users. There is intentionally no user-facing CLI delete command for marketplace skills.
|
|
124
|
+
|
|
99
125
|
### With additional images (existing project)
|
|
100
126
|
|
|
101
127
|
```bash
|