hermoso 0.1.435 → 0.1.436

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.
@@ -1256,7 +1256,7 @@ export const neutralNote = (t) => {
1256
1256
  // sweeps and drift watches queued for later (measured on a fresh local account: one `agentidle` "nudge", queued for
1257
1257
  // tomorrow, would have shown as "1 render in progress"). Mirrors server.js JOB_TYPES_HIDDEN_FROM_V1, and the check
1258
1258
  // fails if that list gains a type this one lacks. A job queued for LATER is not in progress either.
1259
- export const PANEL_HIDDEN_JOB_TYPES = Object.freeze(['purge', 'agentidle', 'agentsetupmail', 'uploadretention', 'miniappretention', 'connectordrift', 'falwatch', 'faceassetsweep', 'searchvis', 'mcpcanary', 'welcomeads', 'lifecycleedu', 'connhealth', 'chargednothing', 'emailfeedback']);
1259
+ export const PANEL_HIDDEN_JOB_TYPES = Object.freeze(['fallate', 'purge', 'agentidle', 'agentsetupmail', 'uploadretention', 'miniappretention', 'connectordrift', 'falwatch', 'faceassetsweep', 'searchvis', 'mcpcanary', 'welcomeads', 'lifecycleedu', 'connhealth', 'chargednothing', 'emailfeedback']);
1260
1260
  const ageText = (h) => (h == null || !Number.isFinite(+h) ? '' : +h < 1 ? 'just now' : +h < 48 ? `${Math.round(+h)}h ago` : `${Math.round(+h / 24)}d ago`);
1261
1261
  const VIDEO_RE = /\.(mp4|webm|mov|m4v)([?#]|$)/i;
1262
1262
  const clip = (s, n) => { const t = String(s ?? '').replace(/\s+/g, ' ').trim(); return t.length > n ? t.slice(0, n - 1) + '…' : t; };
package/mcp/tools.mjs CHANGED
@@ -4602,7 +4602,7 @@ function buildTools(rawServer, opts = {}, sink = null) {
4602
4602
  const cfg = await apiGet('/api/billing/config');
4603
4603
  const plans = (cfg.plans || []).filter(p => p.priceUsd > 0 && !p.legacy && !p.cohort).map(p => ({ id: p.id, name: p.name, priceUsd: p.priceUsd, credits: p.credits, noMarkup: !!p.noMarkup, makes: p.makes || null }));
4604
4604
  if (!plan) {
4605
- const lines = plans.map(p => `• ${p.id} — ${p.name}: $${p.priceUsd}/mo · ${p.credits.toLocaleString()} credits/mo${p.makes?.videoAds ? ` (about ${p.makes.videoAds} ${p.makes.videoSeconds}s video ads or ${p.makes.images} images)` : ''}${p.noMarkup ? ' · no markup on models' : ''}`).join('\n') || '(no plans configured)';
4605
+ const lines = plans.map(p => `• ${p.id} — ${p.name}: $${p.priceUsd}/mo · ${p.credits.toLocaleString()} credits/mo${p.makes?.videoAds ? ` (about ${p.makes.videoAds} ${p.makes.videoSeconds}-second videos or ${p.makes.images} images a month)` : ''}${p.noMarkup ? ' · no markup on models' : ''}`).join('\n') || '(no plans configured)';
4606
4606
  return ok(`Subscription plans (monthly):\n${lines}\n${cfg.memberPricing?.note || ''}\n\nCall upgrade_plan again with plan="<id>" (admin only). Downgrades + changes for existing subscribers are made in the app.`, { plans });
4607
4607
  }
4608
4608
  const d = await apiPost('/api/billing/plan-link', { planId: plan, period, ...(confirm && quote_token ? { confirm: true, quoteToken: quote_token } : {}) });
@@ -21430,10 +21430,10 @@ function memoryNoteVerdict(text) {
21430
21430
  title: 'Draft profile',
21431
21431
  description: 'Fill in a profile (a business brand or a creator) from a website domain, a free-text description, or a social handle, into a {name, products, logo, …} object you can pass to plan_ad / generate. 0 credits. IMPORTANT: a domain can resolve to a DIFFERENT company than intended (e.g. bala.com is an engineering firm, not the Bala fitness brand at shopbala.com). Before spending any credits on research or renders, VERIFY the returned `name` (and `summary`) match the brand the user meant; if it looks wrong, re-draft with the correct domain or a description (pass save:false until confirmed) — this tool cannot ask the user, so the caller owns that check.',
21432
21432
  inputSchema: {
21433
- domain: z.string().optional().describe('a website to scrape'),
21433
+ domain: z.string().optional().describe('a website to scrape, or a social link (profile, YouTube channel or one post) to draft from the account it names'),
21434
21434
  description: z.string().optional().describe('a free-text brand description (no website)'),
21435
- socialHandle: z.string().optional().describe('a social handle to draft from (influencers/creators) — pair with platform'),
21436
- platform: z.string().optional().describe('platform for socialHandle (instagram/tiktok/…)'),
21435
+ socialHandle: z.string().optional().describe('a social handle (creators); needs platform, never guessed'),
21436
+ platform: z.string().optional().describe('socialHandle platform: instagram/tiktok/youtube/twitter/threads'),
21437
21437
  save: z.boolean().optional().describe('save onto the active profile (like Studio onboarding) so plan_ad/create use it automatically. Default: saves only when NO brand is saved yet; pass true to REPLACE the saved profile (the drafted fields overwrite the saved ones), false to never save'),
21438
21438
  },
21439
21439
  outputSchema: {
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "hermoso",
3
- "version": "0.1.435",
3
+ "version": "0.1.436",
4
4
  "mcpName": "io.github.hermoso-ai/hermoso",
5
- "description": "AI marketing agent and AI ad generator, run from your own AI agent. 922 tools. No markup on models. 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, Telegram and Google Business Profile. 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.",
5
+ "description": "AI marketing agent and AI ad generator, run from your own AI agent. 922 tools. No markup on models. Publishing, scheduling, ad campaign management, comments, DMs and analytics are free on every plan. 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, Telegram and Google Business Profile. 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",
7
7
  "bin": {
8
8
  "hermoso": "bin/hermoso.mjs"
@@ -12,7 +12,7 @@
12
12
  "prepublishOnly": "node ../tools/publish-preflight.mjs"
13
13
  },
14
14
  "dependencies": {
15
- "@modelcontextprotocol/sdk": "^1.29.0"
15
+ "@modelcontextprotocol/sdk": "^1.32.1"
16
16
  },
17
17
  "keywords": [
18
18
  "ad-generator",