agent-media-cli 1.7.1 → 1.7.3
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/README.md +28 -1
- package/dist/commands/product-acting.d.ts +9 -0
- package/dist/commands/product-acting.d.ts.map +1 -0
- package/dist/commands/product-acting.js +276 -0
- package/dist/commands/product-acting.js.map +1 -0
- package/dist/commands/update.d.ts +3 -1
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +144 -66
- package/dist/commands/update.js.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/api.d.ts +39 -0
- package/dist/lib/api.d.ts.map +1 -1
- package/dist/lib/api.js +86 -6
- package/dist/lib/api.js.map +1 -1
- package/package.json +12 -9
- package/dist/tests/commands.test.js +0 -245
package/README.md
CHANGED
|
@@ -49,6 +49,15 @@ agent-media ugc -g "A fitness tracker that monitors sleep quality" --actor naomi
|
|
|
49
49
|
|
|
50
50
|
# PIP mode (talking head + rotating B-roll overlays)
|
|
51
51
|
agent-media ugc "your script..." --actor adaeze --pip --duration 15 --sync
|
|
52
|
+
|
|
53
|
+
# Product Acting UGC from a product image URL
|
|
54
|
+
agent-media product-acting \
|
|
55
|
+
--product-image https://cdn.example.com/product.png \
|
|
56
|
+
--actor sofia \
|
|
57
|
+
--about "A premium perfume with a warm vanilla dry-down" \
|
|
58
|
+
--template product-in-hand \
|
|
59
|
+
--acting-style honest-review \
|
|
60
|
+
--sync
|
|
52
61
|
```
|
|
53
62
|
|
|
54
63
|
## UGC Flags
|
|
@@ -78,6 +87,7 @@ hormozi, minimal, bold, karaoke, clean, tiktok, neon, fire, glow, pop, aesthetic
|
|
|
78
87
|
|
|
79
88
|
```bash
|
|
80
89
|
agent-media ugc "script..." # Generate UGC video
|
|
90
|
+
agent-media product-acting --product-image https://... --actor sofia --about "..." --sync
|
|
81
91
|
agent-media actor list # Browse 200+ AI actors
|
|
82
92
|
agent-media subtitle ./video.mp4 # Add subtitles
|
|
83
93
|
agent-media status <job-id> # Check job status
|
|
@@ -88,8 +98,25 @@ agent-media subscribe # Subscribe or buy credits
|
|
|
88
98
|
agent-media apikey list # Manage API keys
|
|
89
99
|
agent-media whoami # Current user info
|
|
90
100
|
agent-media doctor # Run diagnostics
|
|
101
|
+
agent-media update # Update CLI + Claude Code skill docs
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Updates
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
# Update the global CLI package and refresh Claude Code skill docs
|
|
108
|
+
agent-media update
|
|
109
|
+
|
|
110
|
+
# Preview what would update without changing anything
|
|
111
|
+
agent-media update --check
|
|
112
|
+
|
|
113
|
+
# Update only one side when needed
|
|
114
|
+
agent-media update --cli-only
|
|
115
|
+
agent-media update --skills-only
|
|
91
116
|
```
|
|
92
117
|
|
|
118
|
+
Skill docs are refreshed from `gitroomhq/agent-media`, the same repo used by `npx add-skill gitroomhq/agent-media`.
|
|
119
|
+
|
|
93
120
|
## Pricing
|
|
94
121
|
|
|
95
122
|
| Plan | Price | Credits/month | ~10s Videos |
|
|
@@ -113,7 +140,7 @@ agent-media doctor # Run diagnostics
|
|
|
113
140
|
- [Interactive API Docs](https://agent-media.ai/docs/api-reference)
|
|
114
141
|
- [OpenAPI Spec](https://agent-media.ai/openapi.json)
|
|
115
142
|
- [Website](https://agent-media.ai)
|
|
116
|
-
- [GitHub](https://github.com/
|
|
143
|
+
- [GitHub](https://github.com/yuvalsuede/agent-media)
|
|
117
144
|
|
|
118
145
|
## License
|
|
119
146
|
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `agent-media product-acting` command.
|
|
3
|
+
*
|
|
4
|
+
* Generates a Product Acting UGC video: an AI creator presents or reacts to a
|
|
5
|
+
* product image in a selected real-world scenario.
|
|
6
|
+
*/
|
|
7
|
+
import type { Command } from 'commander';
|
|
8
|
+
export declare function registerProductActingCommand(program: Command): void;
|
|
9
|
+
//# sourceMappingURL=product-acting.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"product-acting.d.ts","sourceRoot":"","sources":["../../src/commands/product-acting.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgIzC,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAoMnE"}
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
// Copyright 2026 agent-media contributors. Apache-2.0 license.
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import { detectOutputMode, printJson, printQuiet, createSpinner, } from '../lib/output.js';
|
|
4
|
+
import { getApiKey, resolveProfileName } from '../lib/credentials.js';
|
|
5
|
+
import { AgentMediaAPI, } from '../lib/api.js';
|
|
6
|
+
import { CLIError, handleError } from '../lib/errors.js';
|
|
7
|
+
const POLL_INTERVAL_MS = 5_000;
|
|
8
|
+
const TERMINAL_STATUSES = new Set(['completed', 'failed', 'canceled']);
|
|
9
|
+
const VALID_DURATIONS = new Set([5, 10, 15]);
|
|
10
|
+
const VALID_SUBTITLE_STYLES = new Set(['hormozi', 'none']);
|
|
11
|
+
const VALID_TEMPLATES = new Set([
|
|
12
|
+
'product-in-hand',
|
|
13
|
+
'mirror-selfie',
|
|
14
|
+
'bathroom-reaction',
|
|
15
|
+
'kitchen-counter',
|
|
16
|
+
'car-selfie',
|
|
17
|
+
'couch-review',
|
|
18
|
+
'expert-interview',
|
|
19
|
+
'product-closeup',
|
|
20
|
+
]);
|
|
21
|
+
const VALID_ACTING_STYLES = new Set([
|
|
22
|
+
'raw-selfie',
|
|
23
|
+
'shocked',
|
|
24
|
+
'angry',
|
|
25
|
+
'excited',
|
|
26
|
+
'dramatic',
|
|
27
|
+
'weird-hook',
|
|
28
|
+
'casual-demo',
|
|
29
|
+
'honest-review',
|
|
30
|
+
]);
|
|
31
|
+
const WORDS_PER_SECOND = 3;
|
|
32
|
+
const STATUS_COLORS = {
|
|
33
|
+
pending: chalk.yellow,
|
|
34
|
+
submitted: chalk.blue,
|
|
35
|
+
processing: chalk.blue,
|
|
36
|
+
completed: chalk.green,
|
|
37
|
+
failed: chalk.red,
|
|
38
|
+
canceled: chalk.dim,
|
|
39
|
+
};
|
|
40
|
+
function formatStatus(status) {
|
|
41
|
+
const colorize = STATUS_COLORS[status] ?? chalk.white;
|
|
42
|
+
return colorize(status.toUpperCase());
|
|
43
|
+
}
|
|
44
|
+
function formatElapsed(seconds) {
|
|
45
|
+
if (seconds < 60)
|
|
46
|
+
return `${seconds}s`;
|
|
47
|
+
const mins = Math.floor(seconds / 60);
|
|
48
|
+
const secs = seconds % 60;
|
|
49
|
+
return `${mins}m ${secs}s`;
|
|
50
|
+
}
|
|
51
|
+
async function waitForJob(api, jobId, mode) {
|
|
52
|
+
const startTime = Date.now();
|
|
53
|
+
let interrupted = false;
|
|
54
|
+
const onSigint = () => {
|
|
55
|
+
interrupted = true;
|
|
56
|
+
};
|
|
57
|
+
process.on('SIGINT', onSigint);
|
|
58
|
+
const spinner = createSpinner('Building Product Acting UGC video...');
|
|
59
|
+
if (mode === 'human')
|
|
60
|
+
spinner.start();
|
|
61
|
+
try {
|
|
62
|
+
while (!interrupted) {
|
|
63
|
+
const poll = await api.pollProvider(jobId);
|
|
64
|
+
const elapsed = Math.floor((Date.now() - startTime) / 1000);
|
|
65
|
+
const status = poll.status;
|
|
66
|
+
if (mode === 'human') {
|
|
67
|
+
spinner.text = `${formatStatus(status)} elapsed ${formatElapsed(elapsed)} (Ctrl+C to stop)`;
|
|
68
|
+
}
|
|
69
|
+
if (TERMINAL_STATUSES.has(status)) {
|
|
70
|
+
const job = await api.getJob(jobId);
|
|
71
|
+
if (mode === 'human') {
|
|
72
|
+
if (status === 'completed') {
|
|
73
|
+
spinner.succeed(`Product Acting UGC video produced in ${formatElapsed(elapsed)}`);
|
|
74
|
+
}
|
|
75
|
+
else if (status === 'failed') {
|
|
76
|
+
spinner.fail(`Job failed after ${formatElapsed(elapsed)}` + (job.error_message ? `: ${job.error_message}` : ''));
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
spinner.warn(`Job canceled after ${formatElapsed(elapsed)}`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return job;
|
|
83
|
+
}
|
|
84
|
+
await new Promise((resolve) => {
|
|
85
|
+
const timer = setTimeout(resolve, POLL_INTERVAL_MS);
|
|
86
|
+
const earlyExit = () => {
|
|
87
|
+
clearTimeout(timer);
|
|
88
|
+
process.removeListener('SIGINT', earlyExit);
|
|
89
|
+
resolve();
|
|
90
|
+
};
|
|
91
|
+
process.once('SIGINT', earlyExit);
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
if (mode === 'human') {
|
|
95
|
+
spinner.stop();
|
|
96
|
+
console.log();
|
|
97
|
+
console.log(chalk.dim(' Stopped waiting.'));
|
|
98
|
+
}
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
finally {
|
|
102
|
+
process.removeListener('SIGINT', onSigint);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
export function registerProductActingCommand(program) {
|
|
106
|
+
program
|
|
107
|
+
.command('product-acting')
|
|
108
|
+
.description('Generate Product Acting UGC — AI creator presents a product image\n\n' +
|
|
109
|
+
'Examples:\n' +
|
|
110
|
+
' $ agent-media product-acting \\\n' +
|
|
111
|
+
' --product-image https://cdn.example.com/perfume.png \\\n' +
|
|
112
|
+
' --actor sarah \\\n' +
|
|
113
|
+
' --script "I did not expect this perfume to smell this expensive" \\\n' +
|
|
114
|
+
' --sync\n\n' +
|
|
115
|
+
' $ agent-media product-acting \\\n' +
|
|
116
|
+
' --product-image https://cdn.example.com/bottle.webp \\\n' +
|
|
117
|
+
' --actor marcus --product-name "Hydra Boost" \\\n' +
|
|
118
|
+
' --about "Daily electrolyte drink for gym recovery" \\\n' +
|
|
119
|
+
' --template kitchen-counter --acting-style excited --duration 10 --sync\n\n' +
|
|
120
|
+
'The product image must be a publicly accessible image URL. If --script is omitted,\n' +
|
|
121
|
+
'--about is required and the API generates a short script.')
|
|
122
|
+
.requiredOption('--product-image <url>', 'Public URL of the product image')
|
|
123
|
+
.requiredOption('--actor <slug>', 'Actor slug from `agent-media actor list`')
|
|
124
|
+
.option('--actor-variant-id <uuid>', 'Optional actor variant UUID')
|
|
125
|
+
.option('--product-name <name>', 'Product name for script/frame context')
|
|
126
|
+
.option('--about <text>', 'Product description/context. Required if --script is omitted')
|
|
127
|
+
.option('--script <text>', 'Exact script the actor should say')
|
|
128
|
+
.option('--template <name>', 'Scenario: product-in-hand, mirror-selfie, bathroom-reaction, kitchen-counter, car-selfie, couch-review, expert-interview, product-closeup', 'product-in-hand')
|
|
129
|
+
.option('--acting-style <name>', 'Acting style: raw-selfie, shocked, angry, excited, dramatic, weird-hook, casual-demo, honest-review', 'raw-selfie')
|
|
130
|
+
.option('--visual-style <text>', 'Extra visual/camera direction')
|
|
131
|
+
.option('--duration <seconds>', 'Video duration: 5, 10, or 15', '5')
|
|
132
|
+
.option('--subtitle-style <style>', 'Subtitle style: hormozi or none', 'hormozi')
|
|
133
|
+
.option('--webhook-url <url>', 'Webhook to call on completion')
|
|
134
|
+
.option('-s, --sync', 'Wait for completion and print the output URL')
|
|
135
|
+
.action(async (cmdOpts) => {
|
|
136
|
+
const globalOpts = program.opts();
|
|
137
|
+
const mode = detectOutputMode(globalOpts);
|
|
138
|
+
const profileName = resolveProfileName(globalOpts.profile);
|
|
139
|
+
const apiKey = getApiKey(profileName);
|
|
140
|
+
if (!apiKey) {
|
|
141
|
+
throw new CLIError('Not logged in.', {
|
|
142
|
+
code: 'NOT_AUTHENTICATED',
|
|
143
|
+
suggestion: "Run 'agent-media login' to authenticate.",
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
const duration = Number(cmdOpts.duration);
|
|
147
|
+
if (!VALID_DURATIONS.has(duration)) {
|
|
148
|
+
throw new CLIError(`Invalid --duration: ${cmdOpts.duration}`, {
|
|
149
|
+
code: 'VALIDATION_ERROR',
|
|
150
|
+
suggestion: 'Use 5, 10, or 15.',
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
if (!VALID_SUBTITLE_STYLES.has(cmdOpts.subtitleStyle)) {
|
|
154
|
+
throw new CLIError(`Invalid --subtitle-style: ${cmdOpts.subtitleStyle}`, {
|
|
155
|
+
code: 'VALIDATION_ERROR',
|
|
156
|
+
suggestion: 'Use hormozi or none.',
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
if (!VALID_TEMPLATES.has(cmdOpts.template)) {
|
|
160
|
+
throw new CLIError(`Invalid --template: ${cmdOpts.template}`, {
|
|
161
|
+
code: 'VALIDATION_ERROR',
|
|
162
|
+
suggestion: `Use one of: ${Array.from(VALID_TEMPLATES).join(', ')}.`,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
if (!VALID_ACTING_STYLES.has(cmdOpts.actingStyle)) {
|
|
166
|
+
throw new CLIError(`Invalid --acting-style: ${cmdOpts.actingStyle}`, {
|
|
167
|
+
code: 'VALIDATION_ERROR',
|
|
168
|
+
suggestion: `Use one of: ${Array.from(VALID_ACTING_STYLES).join(', ')}.`,
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
if (!cmdOpts.script && !cmdOpts.about) {
|
|
172
|
+
throw new CLIError('Either --script or --about is required.', {
|
|
173
|
+
code: 'VALIDATION_ERROR',
|
|
174
|
+
suggestion: 'Pass exact words with --script or product context with --about.',
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
if (cmdOpts.script) {
|
|
178
|
+
const wordCount = cmdOpts.script.trim().split(/\s+/).filter(Boolean).length;
|
|
179
|
+
const maxWords = duration * WORDS_PER_SECOND;
|
|
180
|
+
if (wordCount > maxWords) {
|
|
181
|
+
throw new CLIError(`Script too long: ${wordCount} words. Max ${maxWords} for ${duration}s.`, {
|
|
182
|
+
code: 'VALIDATION_ERROR',
|
|
183
|
+
suggestion: `Shorten the script to ≤${maxWords} words or increase --duration.`,
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
try {
|
|
188
|
+
const api = new AgentMediaAPI(apiKey);
|
|
189
|
+
const submitSpinner = createSpinner('Submitting Product Acting UGC job...');
|
|
190
|
+
if (mode === 'human')
|
|
191
|
+
submitSpinner.start();
|
|
192
|
+
const result = await api.productActingGenerate({
|
|
193
|
+
product_image_url: cmdOpts.productImage,
|
|
194
|
+
actor_slug: cmdOpts.actor,
|
|
195
|
+
actor_variant_id: cmdOpts.actorVariantId,
|
|
196
|
+
product_name: cmdOpts.productName,
|
|
197
|
+
product_description: cmdOpts.about,
|
|
198
|
+
script: cmdOpts.script,
|
|
199
|
+
template: cmdOpts.template,
|
|
200
|
+
acting_style: cmdOpts.actingStyle,
|
|
201
|
+
visual_style: cmdOpts.visualStyle,
|
|
202
|
+
duration,
|
|
203
|
+
subtitles: cmdOpts.subtitleStyle !== 'none',
|
|
204
|
+
subtitle_style: cmdOpts.subtitleStyle,
|
|
205
|
+
webhook_url: cmdOpts.webhookUrl,
|
|
206
|
+
});
|
|
207
|
+
if (mode === 'human')
|
|
208
|
+
submitSpinner.succeed('Product Acting UGC job submitted');
|
|
209
|
+
if (!cmdOpts.sync) {
|
|
210
|
+
switch (mode) {
|
|
211
|
+
case 'json':
|
|
212
|
+
printJson(result);
|
|
213
|
+
break;
|
|
214
|
+
case 'quiet':
|
|
215
|
+
printQuiet(result.job_id);
|
|
216
|
+
break;
|
|
217
|
+
default:
|
|
218
|
+
console.log();
|
|
219
|
+
console.log(` ${chalk.bold('Job ID:')} ${chalk.cyan(result.job_id)}`);
|
|
220
|
+
console.log(` ${chalk.bold('Actor:')} ${result.actor_slug}`);
|
|
221
|
+
console.log(` ${chalk.bold('Subtitles:')} ${result.subtitle_style}`);
|
|
222
|
+
console.log(` ${chalk.bold('Credits:')} ${result.credits_deducted} deducted`);
|
|
223
|
+
console.log();
|
|
224
|
+
console.log(chalk.dim(` Run 'agent-media status ${result.job_id}' to check progress`));
|
|
225
|
+
console.log(chalk.dim(` Or re-run with --sync to wait for completion`));
|
|
226
|
+
console.log();
|
|
227
|
+
}
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
if (mode === 'human') {
|
|
231
|
+
console.log();
|
|
232
|
+
console.log(` ${chalk.bold('Job ID:')} ${chalk.cyan(result.job_id)}`);
|
|
233
|
+
console.log(` ${chalk.bold('Actor:')} ${result.actor_slug}`);
|
|
234
|
+
console.log(` ${chalk.bold('Credits:')} ${result.credits_deducted} deducted`);
|
|
235
|
+
console.log();
|
|
236
|
+
}
|
|
237
|
+
const finishedJob = await waitForJob(api, result.job_id, mode);
|
|
238
|
+
if (!finishedJob)
|
|
239
|
+
return;
|
|
240
|
+
if (mode === 'json') {
|
|
241
|
+
const payload = {
|
|
242
|
+
job_id: finishedJob.id,
|
|
243
|
+
status: finishedJob.status,
|
|
244
|
+
actor_slug: result.actor_slug,
|
|
245
|
+
credits_deducted: result.credits_deducted,
|
|
246
|
+
};
|
|
247
|
+
if (finishedJob.status === 'failed') {
|
|
248
|
+
payload['error'] = finishedJob.error_message ?? 'Unknown error';
|
|
249
|
+
}
|
|
250
|
+
if (finishedJob.output_media_url) {
|
|
251
|
+
payload['output_url'] = finishedJob.output_media_url;
|
|
252
|
+
}
|
|
253
|
+
printJson(payload);
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
if (mode === 'quiet') {
|
|
257
|
+
printQuiet(finishedJob.output_media_url ?? finishedJob.id);
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
if (finishedJob.status === 'completed' && finishedJob.output_media_url) {
|
|
261
|
+
console.log();
|
|
262
|
+
console.log(` ${chalk.bold('URL:')} ${chalk.cyan(finishedJob.output_media_url)}`);
|
|
263
|
+
console.log();
|
|
264
|
+
}
|
|
265
|
+
else if (finishedJob.status !== 'completed') {
|
|
266
|
+
console.log();
|
|
267
|
+
console.log(chalk.yellow(' No output — Product Acting UGC job did not complete successfully.'));
|
|
268
|
+
console.log();
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
catch (error) {
|
|
272
|
+
handleError(error);
|
|
273
|
+
}
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
//# sourceMappingURL=product-acting.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"product-acting.js","sourceRoot":"","sources":["../../src/commands/product-acting.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,10 +3,12 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Checks the npm registry for the latest published version of the
|
|
5
5
|
* agent-media package, compares it against the locally installed version,
|
|
6
|
-
*
|
|
6
|
+
* installs the update, and refreshes the Claude Code skill docs.
|
|
7
7
|
*
|
|
8
8
|
* Flags:
|
|
9
9
|
* --check Check-only mode (do not prompt or install).
|
|
10
|
+
* --cli-only Update only the CLI package.
|
|
11
|
+
* --skills-only Update only the Claude Code skill docs.
|
|
10
12
|
*/
|
|
11
13
|
import type { Command } from 'commander';
|
|
12
14
|
export declare function registerUpdateCommand(program: Command): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AAEA
|
|
1
|
+
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkKzC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAwK5D"}
|
package/dist/commands/update.js
CHANGED
|
@@ -8,8 +8,19 @@ const require = createRequire(import.meta.url);
|
|
|
8
8
|
const pkg = require('../../package.json');
|
|
9
9
|
/** npm registry URL for the package. */
|
|
10
10
|
const REGISTRY_URL = `https://registry.npmjs.org/${pkg.name}/latest`;
|
|
11
|
+
/** Canonical Claude Code skill repo installed by the public docs. */
|
|
12
|
+
const SKILL_REPO = 'gitroomhq/agent-media';
|
|
11
13
|
/** Timeout for the registry fetch (5 seconds). */
|
|
12
14
|
const FETCH_TIMEOUT_MS = 5_000;
|
|
15
|
+
function commandErrorMessage(error) {
|
|
16
|
+
if (error instanceof Error) {
|
|
17
|
+
const maybeExecError = error;
|
|
18
|
+
const stderr = maybeExecError.stderr?.toString().trim();
|
|
19
|
+
const stdout = maybeExecError.stdout?.toString().trim();
|
|
20
|
+
return stderr || stdout || error.message;
|
|
21
|
+
}
|
|
22
|
+
return String(error);
|
|
23
|
+
}
|
|
13
24
|
/**
|
|
14
25
|
* Compare two semver strings. Returns:
|
|
15
26
|
* -1 if a < b, 0 if equal, 1 if a > b.
|
|
@@ -110,97 +121,164 @@ function buildInstallCommand(pm, version) {
|
|
|
110
121
|
return `npm install -g ${spec}`;
|
|
111
122
|
}
|
|
112
123
|
}
|
|
124
|
+
function buildSkillUpdateCommand() {
|
|
125
|
+
return `npx --yes add-skill ${SKILL_REPO}`;
|
|
126
|
+
}
|
|
113
127
|
export function registerUpdateCommand(program) {
|
|
114
128
|
program
|
|
115
129
|
.command('update')
|
|
116
|
-
.description('
|
|
130
|
+
.description('Update the CLI and Claude Code skill docs')
|
|
117
131
|
.option('--check', 'Check only, do not install')
|
|
132
|
+
.option('--cli-only', 'Update only the global CLI package')
|
|
133
|
+
.option('--skills-only', 'Update only the Claude Code skill docs')
|
|
118
134
|
.action(async (cmdOpts) => {
|
|
119
135
|
const globalOpts = program.opts();
|
|
120
136
|
const mode = detectOutputMode(globalOpts);
|
|
121
137
|
const checkOnly = cmdOpts.check ?? false;
|
|
138
|
+
const cliOnly = cmdOpts.cliOnly ?? false;
|
|
139
|
+
const skillsOnly = cmdOpts.skillsOnly ?? false;
|
|
140
|
+
if (cliOnly && skillsOnly) {
|
|
141
|
+
handleError(new CLIError('Choose either --cli-only or --skills-only, not both.', {
|
|
142
|
+
code: 'UPDATE_INVALID_FLAGS',
|
|
143
|
+
suggestion: 'Run either agent-media update --cli-only or agent-media update --skills-only.',
|
|
144
|
+
}));
|
|
145
|
+
}
|
|
146
|
+
const shouldUpdateCli = !skillsOnly;
|
|
147
|
+
const shouldUpdateSkills = !cliOnly;
|
|
122
148
|
try {
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
149
|
+
const pm = detectPackageManager();
|
|
150
|
+
const skillUpdateCommand = buildSkillUpdateCommand();
|
|
151
|
+
let cliState = null;
|
|
152
|
+
let skillState = null;
|
|
153
|
+
if (shouldUpdateCli) {
|
|
154
|
+
const spinner = createSpinner('Checking for CLI updates...');
|
|
155
|
+
if (mode === 'human')
|
|
156
|
+
spinner.start();
|
|
157
|
+
const latestVersion = await fetchLatestVersion();
|
|
158
|
+
const currentVersion = pkg.version;
|
|
159
|
+
const comparison = compareSemver(currentVersion, latestVersion);
|
|
160
|
+
if (mode === 'human')
|
|
161
|
+
spinner.stop();
|
|
162
|
+
cliState = {
|
|
163
|
+
current: currentVersion,
|
|
164
|
+
latest: latestVersion,
|
|
165
|
+
update_available: comparison < 0,
|
|
166
|
+
};
|
|
167
|
+
if (comparison < 0) {
|
|
168
|
+
const installCmd = buildInstallCommand(pm, latestVersion);
|
|
169
|
+
cliState.install_command = installCmd;
|
|
170
|
+
if (!checkOnly) {
|
|
171
|
+
if (mode === 'human') {
|
|
172
|
+
console.log();
|
|
173
|
+
console.log(chalk.bold(' CLI update available'));
|
|
174
|
+
console.log(` ${chalk.dim('Current:')} v${currentVersion}`);
|
|
175
|
+
console.log(` ${chalk.green('Latest:')} v${latestVersion}`);
|
|
176
|
+
console.log();
|
|
177
|
+
}
|
|
178
|
+
const installSpinner = createSpinner(`Updating CLI with ${pm}...`);
|
|
179
|
+
if (mode === 'human')
|
|
180
|
+
installSpinner.start();
|
|
181
|
+
try {
|
|
182
|
+
execSync(installCmd, {
|
|
183
|
+
encoding: 'utf-8',
|
|
184
|
+
stdio: 'pipe',
|
|
185
|
+
});
|
|
186
|
+
cliState.updated = true;
|
|
187
|
+
if (mode === 'human') {
|
|
188
|
+
installSpinner.succeed(`Updated agent-media CLI from v${currentVersion} to v${latestVersion}`);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
catch (installError) {
|
|
192
|
+
if (mode === 'human')
|
|
193
|
+
installSpinner.fail('CLI update failed');
|
|
194
|
+
throw new CLIError(`Failed to install CLI update: ${commandErrorMessage(installError)}`, {
|
|
195
|
+
code: 'UPDATE_INSTALL_FAILED',
|
|
196
|
+
suggestion: `Try installing manually:\n ${installCmd}`,
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
cliState.skipped = true;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
cliState.updated = false;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
if (shouldUpdateSkills) {
|
|
209
|
+
skillState = {
|
|
210
|
+
repository: SKILL_REPO,
|
|
211
|
+
update_command: skillUpdateCommand,
|
|
212
|
+
};
|
|
213
|
+
if (!checkOnly) {
|
|
214
|
+
const skillSpinner = createSpinner('Refreshing Claude Code skill docs...');
|
|
215
|
+
if (mode === 'human')
|
|
216
|
+
skillSpinner.start();
|
|
217
|
+
try {
|
|
218
|
+
execSync(skillUpdateCommand, {
|
|
219
|
+
encoding: 'utf-8',
|
|
220
|
+
stdio: 'pipe',
|
|
139
221
|
});
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
222
|
+
skillState.updated = true;
|
|
223
|
+
if (mode === 'human')
|
|
224
|
+
skillSpinner.succeed(`Refreshed skill docs from ${SKILL_REPO}`);
|
|
225
|
+
}
|
|
226
|
+
catch (skillError) {
|
|
227
|
+
if (mode === 'human')
|
|
228
|
+
skillSpinner.fail('Skill refresh failed');
|
|
229
|
+
throw new CLIError(`Failed to update Claude Code skill docs: ${commandErrorMessage(skillError)}`, {
|
|
230
|
+
code: 'SKILL_UPDATE_FAILED',
|
|
231
|
+
suggestion: `Try running manually:\n ${skillUpdateCommand}`,
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
skillState.skipped = true;
|
|
149
237
|
}
|
|
150
|
-
return;
|
|
151
238
|
}
|
|
152
|
-
// Update available
|
|
153
|
-
const pm = detectPackageManager();
|
|
154
|
-
const installCmd = buildInstallCommand(pm, latestVersion);
|
|
155
239
|
switch (mode) {
|
|
156
240
|
case 'json':
|
|
157
241
|
printJson({
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
install_command: installCmd,
|
|
242
|
+
cli: cliState,
|
|
243
|
+
skills: skillState,
|
|
244
|
+
check_only: checkOnly,
|
|
162
245
|
});
|
|
163
246
|
break;
|
|
164
247
|
case 'quiet':
|
|
165
|
-
printQuiet(
|
|
248
|
+
printQuiet([
|
|
249
|
+
cliState ? `cli:${cliState.latest}` : 'cli:skipped',
|
|
250
|
+
skillState ? `skills:${skillState.repository}` : 'skills:skipped',
|
|
251
|
+
]);
|
|
166
252
|
break;
|
|
167
|
-
default:
|
|
168
|
-
console.log();
|
|
169
|
-
console.log(chalk.bold(' Update available!'));
|
|
170
|
-
console.log();
|
|
171
|
-
console.log(` ${chalk.dim('Current:')} v${currentVersion}`);
|
|
172
|
-
console.log(` ${chalk.green('Latest:')} v${latestVersion}`);
|
|
253
|
+
default:
|
|
173
254
|
console.log();
|
|
174
255
|
if (checkOnly) {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
256
|
+
if (cliState) {
|
|
257
|
+
if (cliState.update_available) {
|
|
258
|
+
console.log(`${chalk.bold('CLI update available')}: v${cliState.current} -> v${cliState.latest}`);
|
|
259
|
+
console.log(` ${chalk.cyan(cliState.install_command)}`);
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
262
|
+
console.log(`${chalk.green('CLI up to date')}: v${cliState.current}`);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
if (skillState) {
|
|
266
|
+
console.log(`${chalk.bold('Skill refresh command')}:`);
|
|
267
|
+
console.log(` ${chalk.cyan(skillState.update_command)}`);
|
|
268
|
+
}
|
|
180
269
|
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
encoding: 'utf-8',
|
|
189
|
-
stdio: 'pipe',
|
|
190
|
-
});
|
|
191
|
-
installSpinner.succeed(`Updated agent-media from v${currentVersion} to v${latestVersion}`);
|
|
270
|
+
else {
|
|
271
|
+
if (cliState && !cliState.update_available) {
|
|
272
|
+
console.log(`${chalk.green('CLI up to date')}: v${cliState.current}`);
|
|
273
|
+
}
|
|
274
|
+
if (skillState?.updated) {
|
|
275
|
+
console.log(`${chalk.green('Skill docs refreshed')}: ${skillState.repository}`);
|
|
276
|
+
}
|
|
192
277
|
console.log();
|
|
278
|
+
console.log(chalk.dim('Restart your terminal if the CLI binary was updated.'));
|
|
193
279
|
}
|
|
194
|
-
|
|
195
|
-
installSpinner.fail('Installation failed');
|
|
196
|
-
const msg = installError instanceof Error ? installError.message : String(installError);
|
|
197
|
-
throw new CLIError(`Failed to install update: ${msg}`, {
|
|
198
|
-
code: 'UPDATE_INSTALL_FAILED',
|
|
199
|
-
suggestion: `Try installing manually:\n ${installCmd}`,
|
|
200
|
-
});
|
|
201
|
-
}
|
|
280
|
+
console.log();
|
|
202
281
|
break;
|
|
203
|
-
}
|
|
204
282
|
}
|
|
205
283
|
}
|
|
206
284
|
catch (error) {
|