hermoso 0.1.389 → 0.1.391
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/mcp/tool-cost.mjs +3 -0
- package/mcp/tools.mjs +7 -6
- package/package.json +1 -1
package/mcp/tool-cost.mjs
CHANGED
|
@@ -43,6 +43,9 @@ export const CREATE_FREE_READS = Object.freeze([
|
|
|
43
43
|
'get_job', 'list_library', 'fetch_asset', 'list_skills', 'get_skill',
|
|
44
44
|
'list_product_photos', 'fetch_app_screens', 'list_hooks', 'list_templates', 'face_check',
|
|
45
45
|
'list_meta_posts', 'list_published_posts', 'post_performance', 'diagnose_posts', 'backfill_posts',
|
|
46
|
+
// The product catalog (2026-10-06): a store read or write, and a product page read with curl and parsed locally (no
|
|
47
|
+
// model; POST /api/products answers creditsUsed: 0). Each says "Free" / "0 credits" in its own description.
|
|
48
|
+
'list_products', 'add_product', 'refresh_products', 'update_product', 'remove_product',
|
|
46
49
|
]);
|
|
47
50
|
// Reads inside `research`. `find_competitors` says "0 credits" in its own description (it is the discovery model,
|
|
48
51
|
// billed to us, not a paid ad-data call); the watch tools only write and read a stored preference — the weekly
|
package/mcp/tools.mjs
CHANGED
|
@@ -19445,15 +19445,16 @@ function memoryNoteVerdict(text) {
|
|
|
19445
19445
|
})));
|
|
19446
19446
|
server.registerTool('update_brand', {
|
|
19447
19447
|
title: 'Update profile fields',
|
|
19448
|
-
description: 'Patch SPECIFIC fields of the active profile (name, domain, sells, summary, category, audience, positioning, voice, style, goal,
|
|
19448
|
+
description: 'Patch SPECIFIC fields of the active profile (name, domain, sells, summary, category, audience, positioning, voice, style, goal, logos, and how the brand and product names are pronounced) WITHOUT overwriting the rest — a read-modify-write on the saved brand. Use for “change our voice to playful”, “we sell to dentists now”. To onboard a brand from scratch, use draft_brand. If no brand is saved yet and you only INFERRED one from what the user is making, ask them to confirm it is their brand before saving it (they may be working for a client or just trying things). Only pass the fields you’re changing.',
|
|
19449
19449
|
inputSchema: { ...STORE_BRAND,
|
|
19450
19450
|
name: z.string().optional(), domain: z.string().optional().describe('website domain'), sells: z.string().optional().describe('what the brand sells'),
|
|
19451
19451
|
summary: z.string().optional().describe('one-line description'), category: z.string().optional(), audience: z.string().optional(),
|
|
19452
19452
|
positioning: z.string().optional(), voice: z.string().optional().describe('brand voice/tone'), style: z.string().optional().describe('visual style — palette, typography, aesthetic'), goal: z.string().optional().describe('current marketing goal'),
|
|
19453
19453
|
pronounce: z.string().optional().describe('how the brand NAME is said aloud, as a simple respelling with the stressed syllable in capitals (e.g. "KOH-dee-ak"). Videos use it as a delivery note beside the spoken line; set it when a render mispronounced the name.'),
|
|
19454
19454
|
pronunciations: z.record(z.string()).optional().describe('how PRODUCT names are said aloud, e.g. {"Power Cakes": "POW-er cakes"}. Merged into the saved ones; an empty string removes one.'),
|
|
19455
|
-
logo: z.string().optional()
|
|
19456
|
-
logoLight: z.string().optional().describe('
|
|
19455
|
+
logo: z.string().optional(),
|
|
19456
|
+
logoLight: z.string().optional().describe('for dark pictures; "none" removes'),
|
|
19457
|
+
logoDark: z.string().optional().describe('for light pictures'),
|
|
19457
19458
|
},
|
|
19458
19459
|
outputSchema: { ok: z.boolean().optional(), updated: z.array(z.string()).optional(), brand: z.any().optional() },
|
|
19459
19460
|
annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: false },
|
|
@@ -19469,11 +19470,11 @@ function memoryNoteVerdict(text) {
|
|
|
19469
19470
|
}
|
|
19470
19471
|
// THE LOGO FILES (2026-10-06): the logo, and the optional light version laid on when the original would not read on a
|
|
19471
19472
|
// dark or busy background. A local path is uploaded first (toRef); only a raster file is kept (an SVG cannot be laid on).
|
|
19472
|
-
for (const k of ['logo', 'logoLight']) {
|
|
19473
|
+
for (const k of ['logo', 'logoLight', 'logoDark']) {
|
|
19473
19474
|
if (a[k] == null || !String(a[k]).trim()) continue;
|
|
19474
|
-
if (k
|
|
19475
|
+
if (k !== 'logo' && /^(none|remove|off)$/i.test(String(a[k]).trim())) { patch[k] = ''; continue; }
|
|
19475
19476
|
const ref = await toRef(String(a[k]).trim());
|
|
19476
|
-
if (!ref || !/^(https?:\/\/|data:image\/(png|jpe?g|webp|gif);base64,)/i.test(ref) || /\.svg(\?|$)/i.test(ref)) return { content: [{ type: 'text', text: `The ${k === 'logo' ? 'logo' : 'light logo'} must be a PNG, JPEG or WebP image (a URL or a local file). Nothing was changed.` }], isError: true };
|
|
19477
|
+
if (!ref || !/^(https?:\/\/|data:image\/(png|jpe?g|webp|gif);base64,)/i.test(ref) || /\.svg(\?|$)/i.test(ref)) return { content: [{ type: 'text', text: `The ${k === 'logo' ? 'logo' : k === 'logoLight' ? 'light logo' : 'dark logo'} must be a PNG, JPEG or WebP image (a URL or a local file). Nothing was changed.` }], isError: true };
|
|
19477
19478
|
patch[k] = ref;
|
|
19478
19479
|
}
|
|
19479
19480
|
if (!Object.keys(patch).length) return { content: [{ type: 'text', text: 'Pass at least one brand field to change.' }], isError: true };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hermoso",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.391",
|
|
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",
|