hermoso 0.1.393 → 0.1.395
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/bin/hermoso.mjs +20 -0
- package/mcp/tools.mjs +1 -1
- package/package.json +1 -1
- package/skills/hermoso-generate/SKILL.md +1 -1
package/bin/hermoso.mjs
CHANGED
|
@@ -238,6 +238,26 @@ async function main() {
|
|
|
238
238
|
const rows = inv.filter((t) => (!wantGroup || t.group === wantGroup)
|
|
239
239
|
&& (!q || t.name.includes(q) || t.description.toLowerCase().includes(q) || (t.title || '').toLowerCase().includes(q)))
|
|
240
240
|
.sort((a, b) => order(a.group) - order(b.group) || a.name.localeCompare(b.name));
|
|
241
|
+
// A PHRASE IS SEARCHED BY MEANING WHEN NO TOOL CONTAINS IT LITERALLY (2026-10-06). `--search` is a substring
|
|
242
|
+
// grep, so "switch autopilot to auto-publish" and "when someone comments guide send them a dm" found NOTHING
|
|
243
|
+
// while set_post_refill and save_dm_automation do exactly that. The words go to find_tools — the same ranked
|
|
244
|
+
// search (synonyms, stems, typos) the hosted connector uses — and its rows are printed instead of a dead end.
|
|
245
|
+
if (!rows.length && q && /\s/.test(q.trim())) {
|
|
246
|
+
const { client, close } = await reg.openRegistry();
|
|
247
|
+
try {
|
|
248
|
+
const r = await client.callTool({ name: 'find_tools', arguments: { query: q, limit: 8, ...(wantGroup ? { group: wantGroup } : {}) } }, undefined, { timeout: cliCallTimeoutMs(process.env.HERMOSO_CALL_TIMEOUT_MS) });
|
|
249
|
+
const hits = (r.structuredContent?.tools || []).map((t) => t.name);
|
|
250
|
+
if (hits.length) {
|
|
251
|
+
if (flags.names) return console.log(hits.join('\n'));
|
|
252
|
+
if (flags.json === true) return console.log(JSON.stringify(hits.map((n) => inv.find((t) => t.name === n)).filter(Boolean), null, 2));
|
|
253
|
+
const byName = new Map(inv.map((t) => [t.name, t]));
|
|
254
|
+
console.log(`No tool contains "${q}" word for word; closest by meaning:`);
|
|
255
|
+
for (const n of hits) { const t = byName.get(n); console.log(` ${n}${t ? ` (${t.group}) ${String(t.title || t.description || '').split(/(?<=[.!?])\s/)[0].slice(0, 110)}` : ''}`); }
|
|
256
|
+
console.log(`\nRead one with: hermoso tools <name>`);
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
} finally { await close(); }
|
|
260
|
+
}
|
|
241
261
|
if (flags.json === true) return console.log(JSON.stringify(rows, null, 2));
|
|
242
262
|
if (flags.names) return console.log(rows.map((t) => t.name).join('\n'));
|
|
243
263
|
if (!rows.length) return console.log(`No tool matches${wantGroup ? ` in ${wantGroup}` : ''}${q ? ` "${q}"` : ''}. Try: hermoso tools`);
|
package/mcp/tools.mjs
CHANGED
|
@@ -315,7 +315,7 @@ export const MCP_INSTRUCTIONS = [
|
|
|
315
315
|
// instead of a render, once after being told in terms to pass an image and run generate_video. A "do X first" that
|
|
316
316
|
// is not actually required is a trap in an instruction an agent reads before acting, and this one was not
|
|
317
317
|
// required: `model` is OPTIONAL on generate_image, generate_video and render_ad, and an unnamed render resolves to
|
|
318
|
-
// GEN_MODELS.<kind>[0] in workImage/workVideo, which is the catalog's `best: true` row (nano-banana-
|
|
318
|
+
// GEN_MODELS.<kind>[0] in workImage/workVideo, which is the catalog's `best: true` row (nano-banana-2.1 for image since 2026-10-06)
|
|
319
319
|
// and, for video, model-belt.mjs's AUTO_VIDEO_DEFAULT (seedance-2.5, also `video[0]`). The prose below says "the
|
|
320
320
|
// server's own default" rather than "the best row" on purpose: hermoso_capabilities' own _pickLine states as a RULE
|
|
321
321
|
// that neither `best` nor the longest-clip row decides where an unnamed ask lands, and two shipped sentences that
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hermoso",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.395",
|
|
4
4
|
"mcpName": "io.github.hermoso-ai/hermoso",
|
|
5
5
|
"description": "Marketing on autopilot, run from your own AI agent. 906 tools. Publishing, scheduling, ad campaign management, comments, DMs and analytics cost no credits on every plan; credits are only for generating creative and for Ad Spy research. AD PLATFORMS: Meta, Google Ads, TikTok Ads, LinkedIn Ads, Reddit Ads, X Ads, Pinterest Ads, Snapchat Ads, Microsoft Advertising, Apple Search Ads, ChatGPT Ads and AppLovin Ads, plus product feeds in Google Merchant Center. PUBLISHING AND SCHEDULING: Facebook, Instagram, Threads, TikTok, YouTube, X, LinkedIn, Pinterest, Bluesky and Telegram. INSTAGRAM DM AUTOMATIONS: a keyword comment, a DM, a story reply or an ig.me link gets an automatic private reply from the brand. AD RESEARCH: the Meta, Google and LinkedIn ad libraries plus organic TikTok, Instagram, YouTube, Threads and Reddit. ANALYTICS: Google Analytics 4, Google Search Console and every connected platform's own post and campaign insights. Also brand onboarding, 50+ image and video generation models, ad scoring, competitor teardowns, Google Drive and OneDrive, a CLI and installable Claude skills.",
|
|
6
6
|
"type": "module",
|
|
@@ -21,7 +21,7 @@ You drive the **Hermoso CLI** (`hermoso`) to render images and videos. Always re
|
|
|
21
21
|
|
|
22
22
|
## Procedure
|
|
23
23
|
1. **Always run `hermoso capabilities` first.** It lists the valid image/video **model ids**, their credit costs, aspect ratios, video durations, and the recipe ids. Never guess a model id.
|
|
24
|
-
2. Pick a **high-quality default** (quality over cost is the house rule): for images prefer the model marked `★best` (e.g. `nano-banana-
|
|
24
|
+
2. Pick a **high-quality default** (quality over cost is the house rule): for images prefer the model marked `★best` (e.g. `nano-banana-2.1`); for product composites pass the real product image with `--ref`. For video, use a featured model and a sensible duration.
|
|
25
25
|
3. Generate:
|
|
26
26
|
- Image: `hermoso generate image --prompt "<full prompt incl. any on-image text>" [--ref ./product.png] [--model <id>] [--aspect 1:1]`
|
|
27
27
|
- Video: `hermoso generate video --prompt "<shot description>" [--ref ./frame.png] [--duration 8] [--aspect 9:16] [--model <id>] [--tts "<voiceover>"] [--voice Rachel] --wait`
|