makaron-cli 0.13.1 → 0.13.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.
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/README.md +6 -0
- package/bin/makaron.mjs +126 -19
- package/package.json +1 -1
- package/skills/makaron/SKILL.md +6 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "makaron-cli",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.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.13.
|
|
3
|
+
"version": "0.13.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/README.md
CHANGED
|
@@ -48,6 +48,12 @@ export MAKARON_API_KEY=mk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
|
48
48
|
|
|
49
49
|
Verify: `npx makaron-cli list` should show projects.
|
|
50
50
|
|
|
51
|
+
Check the current credit balance and subscription:
|
|
52
|
+
```bash
|
|
53
|
+
npx makaron-cli credits
|
|
54
|
+
npx makaron-cli credits --json
|
|
55
|
+
```
|
|
56
|
+
|
|
51
57
|
### Let a human claim your account
|
|
52
58
|
|
|
53
59
|
After registering, generate a link for a human to link your API key to their account:
|
package/bin/makaron.mjs
CHANGED
|
@@ -28,6 +28,7 @@ const NPM_PACKAGE_NAME = 'makaron-cli';
|
|
|
28
28
|
const UPDATE_CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;
|
|
29
29
|
const UPDATE_CHECK_TIMEOUT_MS = 400;
|
|
30
30
|
const AGENT_MODELS = ['auto', 'gpt-5.6-terra', 'gpt-5.6-sol', 'gpt-5.6-luna', 'grok-4.5', 'deepseek-v4-pro'];
|
|
31
|
+
const AGENT_WAIT_TIMEOUT_SECONDS = Math.max(900, Number(process.env.MAKARON_AGENT_WAIT_TIMEOUT_SECONDS || 10_800));
|
|
31
32
|
|
|
32
33
|
// Public anon key (safe to embed — only enables auth, not data access)
|
|
33
34
|
const SUPABASE_URL = 'https://sdyrtztrjgmmpnirswxt.supabase.co';
|
|
@@ -363,6 +364,8 @@ async function streamAgent(baseUrl, headers, projectId, prompt, opts = {}) {
|
|
|
363
364
|
...(opts.videoModel ? { videoModel: opts.videoModel } : {}),
|
|
364
365
|
...(opts.videoResolution ? { videoResolution: opts.videoResolution } : {}),
|
|
365
366
|
...(opts.agentModel && opts.agentModel !== 'auto' ? { agentModel: opts.agentModel } : {}),
|
|
367
|
+
...(opts.uploadedVideoCount ? { uploadedVideoCount: opts.uploadedVideoCount } : {}),
|
|
368
|
+
...(opts.turnMediaCount ? { turnMediaCount: opts.turnMediaCount } : {}),
|
|
366
369
|
}),
|
|
367
370
|
signal: controller.signal,
|
|
368
371
|
});
|
|
@@ -476,6 +479,8 @@ async function submitRun(baseUrl, headers, projectId, prompt, opts = {}) {
|
|
|
476
479
|
if (opts.currentSnapshotIndex != null) body.currentSnapshotIndex = opts.currentSnapshotIndex;
|
|
477
480
|
if (opts.isNsfw) body.isNsfw = opts.isNsfw;
|
|
478
481
|
if (opts.audioAttachments?.length) body.audioAttachments = opts.audioAttachments;
|
|
482
|
+
if (opts.uploadedVideoCount) body.uploadedVideoCount = opts.uploadedVideoCount;
|
|
483
|
+
if (opts.turnMediaCount) body.turnMediaCount = opts.turnMediaCount;
|
|
479
484
|
|
|
480
485
|
const res = await fetch(`${baseUrl}/api/agent/run`, {
|
|
481
486
|
method: 'POST',
|
|
@@ -519,7 +524,7 @@ async function pollRun(baseUrl, headers, runId, opts = {}) {
|
|
|
519
524
|
try {
|
|
520
525
|
const res = await fetch(`${baseUrl}/api/agent/run/${runId}?${params}`, { headers });
|
|
521
526
|
if (!res.ok) {
|
|
522
|
-
if (elapsed >
|
|
527
|
+
if (elapsed > AGENT_WAIT_TIMEOUT_SECONDS) { process.stderr.write(`\n❌ Timeout after ${elapsed}s\n`); process.exit(1); }
|
|
523
528
|
continue;
|
|
524
529
|
}
|
|
525
530
|
data = await res.json();
|
|
@@ -569,6 +574,13 @@ async function pollRun(baseUrl, headers, runId, opts = {}) {
|
|
|
569
574
|
case 'music_task':
|
|
570
575
|
process.stderr.write(`\n🎵 Music submitted: ${ev.data?.taskId}\n`);
|
|
571
576
|
break;
|
|
577
|
+
case 'studio_run': {
|
|
578
|
+
const stage = ev.data?.currentStage || ev.data?.current_stage || 'complete';
|
|
579
|
+
const recipe = ev.data?.recipe || 'studio';
|
|
580
|
+
const status = ev.data?.status || 'running';
|
|
581
|
+
process.stderr.write(`\nStudio Run: ${recipe} / ${stage} / ${status}\n`);
|
|
582
|
+
break;
|
|
583
|
+
}
|
|
572
584
|
case 'error':
|
|
573
585
|
process.stderr.write(`\n❌ Error: ${ev.data?.message}\n`);
|
|
574
586
|
break;
|
|
@@ -580,6 +592,7 @@ async function pollRun(baseUrl, headers, runId, opts = {}) {
|
|
|
580
592
|
|
|
581
593
|
// Check terminal status
|
|
582
594
|
if (data.status === 'completed' || data.status === 'failed' || data.status === 'aborted') {
|
|
595
|
+
normalizeRunResponse(data);
|
|
583
596
|
if (printedText && !json) process.stdout.write('\n');
|
|
584
597
|
if (data.status === 'completed' && exportCompositions) {
|
|
585
598
|
data = await exportAnimatedCompositionsFromRun(baseUrl, headers, data, {
|
|
@@ -611,7 +624,7 @@ async function pollRun(baseUrl, headers, runId, opts = {}) {
|
|
|
611
624
|
process.stderr.write(`🔗 ${APP_URL}/projects/${data.projectId}\n`);
|
|
612
625
|
}
|
|
613
626
|
|
|
614
|
-
if (data.status === 'failed') process.exit(1);
|
|
627
|
+
if (data.status === 'failed' || data.status === 'aborted') process.exit(1);
|
|
615
628
|
return data;
|
|
616
629
|
}
|
|
617
630
|
}
|
|
@@ -620,11 +633,15 @@ async function pollRun(baseUrl, headers, runId, opts = {}) {
|
|
|
620
633
|
// ─── Pick Helper ────────────────────────────────────────────────────────────
|
|
621
634
|
|
|
622
635
|
function applyPick(data, field) {
|
|
636
|
+
const videoUrls = [...new Set([
|
|
637
|
+
...(data.output || []).filter(o => o.type === 'video' && o.url).map(o => o.url),
|
|
638
|
+
...(data.result?.videos || []).filter(v => v.videoUrl).map(v => v.videoUrl),
|
|
639
|
+
])];
|
|
623
640
|
switch (field) {
|
|
624
641
|
case 'first_image_url': return data.output?.find(o => o.type === 'image')?.url || null;
|
|
625
642
|
case 'image_urls': return (data.output || []).filter(o => o.type === 'image' && o.url).map(o => o.url);
|
|
626
|
-
case 'first_video_url': return
|
|
627
|
-
case 'video_urls': return
|
|
643
|
+
case 'first_video_url': return videoUrls[0] || null;
|
|
644
|
+
case 'video_urls': return videoUrls;
|
|
628
645
|
case 'first_design_url': return data.output?.find(o => o.type === 'design')?.url || null;
|
|
629
646
|
case 'design_urls': return (data.output || []).filter(o => o.type === 'design' && o.url).map(o => o.url);
|
|
630
647
|
case 'first_music_url': return data.output?.find(o => o.type === 'music' && o.url)?.url || null;
|
|
@@ -635,6 +652,8 @@ function applyPick(data, field) {
|
|
|
635
652
|
description: action.description,
|
|
636
653
|
source: action.source,
|
|
637
654
|
}));
|
|
655
|
+
case 'studio_run': return [...(data.output || [])].reverse().find(o => o.type === 'studio_run') || null;
|
|
656
|
+
case 'studio_recipe': return [...(data.output || [])].reverse().find(o => o.type === 'studio_run')?.recipe || null;
|
|
638
657
|
case 'project_url': return data.project_url || data.projectUrl || null;
|
|
639
658
|
case 'output': return data.output || [];
|
|
640
659
|
case 'text': return data.output?.find(o => o.type === 'text')?.content || null;
|
|
@@ -656,7 +675,7 @@ async function watchRun(baseUrl, headers, runId, opts = {}) {
|
|
|
656
675
|
try {
|
|
657
676
|
const res = await fetch(`${baseUrl}/api/agent/run/${runId}`, { headers });
|
|
658
677
|
if (!res.ok) {
|
|
659
|
-
if (elapsed >
|
|
678
|
+
if (elapsed > AGENT_WAIT_TIMEOUT_SECONDS) { process.stderr.write(`Timeout after ${elapsed}s\n`); process.exit(2); }
|
|
660
679
|
await new Promise(r => setTimeout(r, interval));
|
|
661
680
|
continue;
|
|
662
681
|
}
|
|
@@ -1042,6 +1061,33 @@ async function fetchMarketplaceSkills(baseUrl, opts = {}) {
|
|
|
1042
1061
|
return skills.map(normalizeMarketplaceSkill);
|
|
1043
1062
|
}
|
|
1044
1063
|
|
|
1064
|
+
async function fetchBuiltInSkills(baseUrl) {
|
|
1065
|
+
const res = await fetch(`${baseUrl}/api/skills?include=internal`);
|
|
1066
|
+
if (!res.ok) {
|
|
1067
|
+
process.stderr.write(`Error ${res.status}: ${await res.text()}\n`);
|
|
1068
|
+
process.exit(1);
|
|
1069
|
+
}
|
|
1070
|
+
const data = await res.json();
|
|
1071
|
+
return (data.skills || []).filter(skill => skill.builtIn);
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
function printBuiltInSkills(skills) {
|
|
1075
|
+
if (!skills.length) {
|
|
1076
|
+
console.log('No built-in skills found.');
|
|
1077
|
+
return;
|
|
1078
|
+
}
|
|
1079
|
+
console.log(`Built-in skills: ${skills.length}\n`);
|
|
1080
|
+
for (const skill of skills) {
|
|
1081
|
+
const recipe = skill.studioRunRecipe ? ` [Studio Run: ${skill.studioRunRecipe}]` : '';
|
|
1082
|
+
const source = skill.sourceMediaRequired ? ' [source media required]' : '';
|
|
1083
|
+
const adapter = skill.sourceProject === 'openmontage'
|
|
1084
|
+
? ` [OpenMontage: ${skill.supportLevel || 'adapted'}${skill.canonicalSkill && skill.canonicalSkill !== skill.name ? ` -> ${skill.canonicalSkill}` : ''}]`
|
|
1085
|
+
: '';
|
|
1086
|
+
console.log(` ${skill.name}${recipe}${source}${adapter}`);
|
|
1087
|
+
if (skill.description) console.log(` ${String(skill.description).replace(/\s+/g, ' ').trim()}`);
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1045
1091
|
function marketplaceSearchText(skill) {
|
|
1046
1092
|
const localized = [...localizedValues(skill.labels), ...localizedValues(skill.prompts)];
|
|
1047
1093
|
return [
|
|
@@ -1554,6 +1600,7 @@ Commands:
|
|
|
1554
1600
|
register --verify --challenge-id <id> --answer <n> Verify and save API key
|
|
1555
1601
|
claim Get claim URL for human to link account
|
|
1556
1602
|
login Log in to Makaron (human interactive)
|
|
1603
|
+
credits Show current credit balance
|
|
1557
1604
|
list (ls) List all projects
|
|
1558
1605
|
project media <projectId> --json List timeline media for a project
|
|
1559
1606
|
create --image <file> Create project from local image
|
|
@@ -1561,7 +1608,7 @@ Commands:
|
|
|
1561
1608
|
create --title "name" Create empty project (text-to-image)
|
|
1562
1609
|
|
|
1563
1610
|
chat --project <id> "message" Chat (non-blocking, polls for result)
|
|
1564
|
-
chat --project <id> --skill <id> Use
|
|
1611
|
+
chat --project <id> --skill <id> Use a built-in or marketplace skill
|
|
1565
1612
|
chat --project <id> --video <file> Attach video to conversation
|
|
1566
1613
|
chat --project <id> --audio <file> Attach song/beat/voice reference
|
|
1567
1614
|
chat --project <id> -b "message" Background: submit and print runId
|
|
@@ -1578,7 +1625,7 @@ Commands:
|
|
|
1578
1625
|
Export editable Remotion composition to MP4
|
|
1579
1626
|
responses list --project <id> List runs for a project
|
|
1580
1627
|
abort <runId> Abort a running Agent
|
|
1581
|
-
skills list|search|show|install Browse and
|
|
1628
|
+
skills list|search|show|install Browse built-in and marketplace skills
|
|
1582
1629
|
|
|
1583
1630
|
edit [--image <file>] "prompt" AI image edit / text-to-image
|
|
1584
1631
|
analyze --video <file|url> Analyze video content
|
|
@@ -1677,6 +1724,8 @@ function printHelp(topic, subtopic) {
|
|
|
1677
1724
|
`);
|
|
1678
1725
|
} else if (topic === 'list' || topic === 'ls') {
|
|
1679
1726
|
console.log('Usage: makaron list');
|
|
1727
|
+
} else if (topic === 'credits' || topic === 'credit' || topic === 'balance') {
|
|
1728
|
+
console.log('Usage: makaron credits [--json]');
|
|
1680
1729
|
} else if (topic === 'project' || topic === 'projects') {
|
|
1681
1730
|
if (subtopic === 'media') console.log('Usage: makaron project media <projectId> [--json]');
|
|
1682
1731
|
else console.log(`Project commands:
|
|
@@ -1689,13 +1738,17 @@ function printHelp(topic, subtopic) {
|
|
|
1689
1738
|
} else if (topic === 'install-skill') {
|
|
1690
1739
|
console.log('Usage: makaron install-skill [--global] [--agent <agent>] [--yes]');
|
|
1691
1740
|
} else if (topic === 'skills') {
|
|
1692
|
-
if (subtopic === 'list') console.log('Usage: makaron skills list [--json]');
|
|
1741
|
+
if (subtopic === 'list') console.log('Usage: makaron skills list [--built-in] [--json]');
|
|
1693
1742
|
else if (subtopic === 'search') console.log('Usage: makaron skills search <query> [--json]');
|
|
1694
1743
|
else if (subtopic === 'show') console.log('Usage: makaron skills show <marketplace-id|label> [--json]');
|
|
1695
1744
|
else if (subtopic === 'install') console.log('Usage: makaron skills install <marketplace-id|label> [--json]');
|
|
1696
|
-
else console.log(`Skill
|
|
1745
|
+
else console.log(`Skill commands:
|
|
1746
|
+
skills list --built-in List all built-in Makaron skills and Studio Run recipes
|
|
1747
|
+
skills list --built-in --openmontage
|
|
1748
|
+
List OpenMontage-native adapters only
|
|
1697
1749
|
skills list List marketplace skills
|
|
1698
1750
|
skills search <query> Search marketplace skills
|
|
1751
|
+
skills show <id|label> --built-in Show a built-in skill
|
|
1699
1752
|
skills show <id|label> Show a marketplace skill
|
|
1700
1753
|
skills install <id|label> Install a marketplace skill to your workspace
|
|
1701
1754
|
|
|
@@ -1783,6 +1836,29 @@ if (!command || command === '--help' || command === '-h' || command === 'help')
|
|
|
1783
1836
|
installAgentSkill(args.slice(1));
|
|
1784
1837
|
} else if (command === 'login') {
|
|
1785
1838
|
await login();
|
|
1839
|
+
} else if (command === 'credits' || command === 'credit' || command === 'balance') {
|
|
1840
|
+
const { headers, baseUrl } = getAuth();
|
|
1841
|
+
const res = await fetch(`${baseUrl}/api/billing/credits`, { headers });
|
|
1842
|
+
const data = await res.json().catch(() => null);
|
|
1843
|
+
if (!res.ok || !data) {
|
|
1844
|
+
const message = data?.error || data?.message || (res.ok ? 'Invalid response' : `HTTP ${res.status}`);
|
|
1845
|
+
process.stderr.write(`Failed to get credits: ${message}\n`);
|
|
1846
|
+
process.exit(1);
|
|
1847
|
+
}
|
|
1848
|
+
if (args.includes('--json')) {
|
|
1849
|
+
console.log(JSON.stringify(data));
|
|
1850
|
+
} else {
|
|
1851
|
+
console.log(`Credits: ${data.balance ?? 0}`);
|
|
1852
|
+
console.log(`Lifetime purchased: ${data.lifetimePurchased ?? 0}`);
|
|
1853
|
+
console.log(`Lifetime used: ${data.lifetimeUsed ?? 0}`);
|
|
1854
|
+
if (data.subscription) {
|
|
1855
|
+
const plan = data.subscription.planId || 'unknown';
|
|
1856
|
+
const status = data.subscription.status ? ` (${data.subscription.status})` : '';
|
|
1857
|
+
console.log(`Subscription: ${plan}${status}`);
|
|
1858
|
+
} else {
|
|
1859
|
+
console.log('Subscription: none');
|
|
1860
|
+
}
|
|
1861
|
+
}
|
|
1786
1862
|
} else if (command === 'create') {
|
|
1787
1863
|
const { headers, baseUrl } = getAuth();
|
|
1788
1864
|
const opts = { images: [], imageUrls: [] };
|
|
@@ -1888,6 +1964,9 @@ if (!command || command === '--help' || command === '-h' || command === 'help')
|
|
|
1888
1964
|
process.exit(1);
|
|
1889
1965
|
}
|
|
1890
1966
|
|
|
1967
|
+
let uploadedTurnMediaCount = 0;
|
|
1968
|
+
let uploadedTurnVideoCount = 0;
|
|
1969
|
+
|
|
1891
1970
|
// --project auto: create a new project (with images/videos if provided)
|
|
1892
1971
|
if (!projectId || projectId === 'auto') {
|
|
1893
1972
|
// Create an empty project first, then attach media by URL. Local images use
|
|
@@ -1925,6 +2004,7 @@ if (!command || command === '--help' || command === '-h' || command === 'help')
|
|
|
1925
2004
|
process.exit(1);
|
|
1926
2005
|
}
|
|
1927
2006
|
process.stderr.write(`📤 Added ${addedCount} image(s) to project\n`);
|
|
2007
|
+
uploadedTurnMediaCount += addedCount;
|
|
1928
2008
|
} else {
|
|
1929
2009
|
process.stderr.write(`❌ Failed to add images: ${await res.text()}\n`);
|
|
1930
2010
|
process.exit(1);
|
|
@@ -2016,19 +2096,25 @@ if (!command || command === '--help' || command === '-h' || command === 'help')
|
|
|
2016
2096
|
const data = await res.json();
|
|
2017
2097
|
const videoSnaps = (data.snapshots || []).filter(s => s.type === 'video');
|
|
2018
2098
|
process.stderr.write(`📹 Added ${videoSnaps.length} video(s) to timeline\n`);
|
|
2099
|
+
uploadedTurnVideoCount += videoSnaps.length;
|
|
2100
|
+
uploadedTurnMediaCount += videoSnaps.length;
|
|
2019
2101
|
} else {
|
|
2020
2102
|
process.stderr.write(`⚠️ Failed to add videos: ${await res.text()}\n`);
|
|
2021
2103
|
}
|
|
2022
2104
|
}
|
|
2023
2105
|
|
|
2024
|
-
// Inject hint so Agent knows videos are available
|
|
2025
|
-
const hint = `[User uploaded ${chatVideos.length === 1 ? 'a video' : `${chatVideos.length} videos`}. Use analyze_video to understand the content.]`;
|
|
2026
|
-
finalPrompt = `${finalPrompt}\n\n${hint}`;
|
|
2027
2106
|
}
|
|
2028
2107
|
|
|
2029
2108
|
if (useStream) {
|
|
2030
2109
|
// Legacy SSE mode
|
|
2031
|
-
const { results } = await streamAgent(baseUrl, headers, projectId, finalPrompt, {
|
|
2110
|
+
const { results } = await streamAgent(baseUrl, headers, projectId, finalPrompt, {
|
|
2111
|
+
videoModel,
|
|
2112
|
+
videoResolution,
|
|
2113
|
+
preferredModel,
|
|
2114
|
+
agentModel,
|
|
2115
|
+
uploadedVideoCount: uploadedTurnVideoCount,
|
|
2116
|
+
turnMediaCount: uploadedTurnMediaCount,
|
|
2117
|
+
});
|
|
2032
2118
|
process.stderr.write('\n━━━ Results ━━━\n');
|
|
2033
2119
|
for (const img of results.images) process.stderr.write(`🖼️ Image: ${img.imageUrl}\n`);
|
|
2034
2120
|
for (const d of results.designs) process.stderr.write(`🎨 ${d.desc}\n`);
|
|
@@ -2037,7 +2123,15 @@ if (!command || command === '--help' || command === '-h' || command === 'help')
|
|
|
2037
2123
|
for (const task of results.musicTasks) await pollMusic(baseUrl, headers, task.taskId);
|
|
2038
2124
|
} else {
|
|
2039
2125
|
// Default: fire-and-forget + poll
|
|
2040
|
-
const { runId } = await submitRun(baseUrl, headers, projectId, finalPrompt, {
|
|
2126
|
+
const { runId } = await submitRun(baseUrl, headers, projectId, finalPrompt, {
|
|
2127
|
+
videoModel,
|
|
2128
|
+
videoResolution,
|
|
2129
|
+
preferredModel,
|
|
2130
|
+
agentModel,
|
|
2131
|
+
audioAttachments,
|
|
2132
|
+
uploadedVideoCount: uploadedTurnVideoCount,
|
|
2133
|
+
turnMediaCount: uploadedTurnMediaCount,
|
|
2134
|
+
});
|
|
2041
2135
|
if (background) {
|
|
2042
2136
|
// Just print runId and exit
|
|
2043
2137
|
if (jsonOutput) {
|
|
@@ -2225,8 +2319,13 @@ if (!command || command === '--help' || command === '-h' || command === 'help')
|
|
|
2225
2319
|
const jsonOutput = args.includes('--json');
|
|
2226
2320
|
|
|
2227
2321
|
if (sub === 'list') {
|
|
2228
|
-
const
|
|
2322
|
+
const builtIn = args.includes('--built-in');
|
|
2323
|
+
let skills = builtIn ? await fetchBuiltInSkills(baseUrl) : await fetchMarketplaceSkills(baseUrl);
|
|
2324
|
+
if (builtIn && args.includes('--openmontage')) {
|
|
2325
|
+
skills = skills.filter(skill => skill.sourceProject === 'openmontage');
|
|
2326
|
+
}
|
|
2229
2327
|
if (jsonOutput) console.log(JSON.stringify({ skills }, null, 2));
|
|
2328
|
+
else if (builtIn) printBuiltInSkills(skills);
|
|
2230
2329
|
else printMarketplaceSkills(skills);
|
|
2231
2330
|
} else if (sub === 'search') {
|
|
2232
2331
|
const query = args.filter((arg, index) => index > 1 && arg !== '--json').join(' ').trim();
|
|
@@ -2243,11 +2342,15 @@ if (!command || command === '--help' || command === '-h' || command === 'help')
|
|
|
2243
2342
|
else printMarketplaceSkills(skills);
|
|
2244
2343
|
} else if (sub === 'show') {
|
|
2245
2344
|
const identifier = args[2];
|
|
2246
|
-
if (!identifier) { console.error('Usage: makaron skills show <
|
|
2247
|
-
const
|
|
2248
|
-
const
|
|
2345
|
+
if (!identifier) { console.error('Usage: makaron skills show <id|label> [--built-in] [--json]'); process.exit(1); }
|
|
2346
|
+
const builtIn = args.includes('--built-in');
|
|
2347
|
+
const skills = builtIn ? await fetchBuiltInSkills(baseUrl) : await fetchMarketplaceSkills(baseUrl);
|
|
2348
|
+
const skill = builtIn
|
|
2349
|
+
? skills.find(candidate => candidate.name === identifier || candidate.label?.toLowerCase() === identifier.toLowerCase())
|
|
2350
|
+
: findMarketplaceSkill(skills, identifier);
|
|
2249
2351
|
if (!skill) { console.error(`Skill not found: ${identifier}`); process.exit(1); }
|
|
2250
2352
|
if (jsonOutput) console.log(JSON.stringify(skill, null, 2));
|
|
2353
|
+
else if (builtIn) printBuiltInSkills([skill]);
|
|
2251
2354
|
else printMarketplaceSkill(skill);
|
|
2252
2355
|
} else if (sub === 'install') {
|
|
2253
2356
|
const identifier = args[2];
|
|
@@ -2260,9 +2363,13 @@ if (!command || command === '--help' || command === '-h' || command === 'help')
|
|
|
2260
2363
|
if (jsonOutput) console.log(JSON.stringify({ ...data, marketplaceId: skill.id, label: skill.label }, null, 2));
|
|
2261
2364
|
else console.log(data.skillName);
|
|
2262
2365
|
} else {
|
|
2263
|
-
console.log(`Skill
|
|
2366
|
+
console.log(`Skill commands:
|
|
2367
|
+
skills list --built-in List all built-in Makaron skills and Studio Run recipes
|
|
2368
|
+
skills list --built-in --openmontage
|
|
2369
|
+
List OpenMontage-native adapters only
|
|
2264
2370
|
skills list List marketplace skills
|
|
2265
2371
|
skills search <query> Search marketplace skills
|
|
2372
|
+
skills show <id|label> --built-in Show a built-in skill
|
|
2266
2373
|
skills show <id|label> Show a marketplace skill
|
|
2267
2374
|
skills install <id|label> Install a marketplace skill to your workspace
|
|
2268
2375
|
`);
|
package/package.json
CHANGED
package/skills/makaron/SKILL.md
CHANGED
|
@@ -44,6 +44,12 @@ export MAKARON_API_KEY=mk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
|
44
44
|
|
|
45
45
|
Verify: `npx makaron-cli list` should show projects.
|
|
46
46
|
|
|
47
|
+
Check the current credit balance and subscription:
|
|
48
|
+
```bash
|
|
49
|
+
npx makaron-cli credits
|
|
50
|
+
npx makaron-cli credits --json
|
|
51
|
+
```
|
|
52
|
+
|
|
47
53
|
## Core Workflow
|
|
48
54
|
|
|
49
55
|
```bash
|