cue-ai 0.9.2 → 0.9.4
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/CHANGELOG.md +4 -3
- package/README.md +154 -394
- package/bin/cue-learnings +30 -4
- package/bin/cue-review-progress +0 -0
- package/bin/cue-review-watch +0 -0
- package/dist/cue.js +4328 -3108
- package/package.json +1 -1
- package/plugins/cue/commands/cue-switch.md +1 -1
- package/plugins/cue/commands/cue.md +1 -1
- package/profiles/backend/profile.yaml +4 -0
- package/profiles/browser/profile.yaml +4 -0
- package/profiles/career/profile.yaml +2 -13
- package/profiles/commerce/profile.yaml +0 -2
- package/profiles/coolify/profile.yaml +0 -1
- package/profiles/core/profile.yaml +78 -11
- package/profiles/dash-merge-test/profile.yaml +6 -1
- package/profiles/designer/profile.yaml +9 -1
- package/profiles/dropshipping/profile.yaml +69 -0
- package/profiles/frontend/profile.yaml +4 -0
- package/profiles/google-ads/profile.yaml +34 -0
- package/profiles/google-analytics/profile.yaml +34 -0
- package/profiles/google-drive/profile.yaml +34 -0
- package/profiles/gstack/profile.yaml +117 -29
- package/profiles/marketing/profile.yaml +0 -1
- package/profiles/media/README.md +70 -0
- package/profiles/media/profile.yaml +104 -0
- package/profiles/nano-banana/profile.yaml +52 -0
- package/profiles/ops/profile.yaml +1 -2
- package/profiles/secops/profile.yaml +3 -0
- package/profiles/skill-writer/profile.yaml +15 -0
- package/profiles/video/profile.yaml +3 -0
- package/profiles/web-frontend-base/profile.yaml +6 -0
- package/profiles/webshop/profile.yaml +0 -1
- package/profiles/webshop-google/profile.yaml +1 -0
- package/profiles/x-growth-bot/profile.yaml +2 -0
- package/resources/icons/generate-icons.py +2 -128
- package/resources/mcps/configs/claude.sanitized.json +88 -20
- package/resources/mcps/configs/claude_runtime.sanitized.json +40 -1
- package/resources/mcps/configs/codex.sanitized.json +29 -0
- package/resources/skills/skills/career/job-hunter/LICENSE +21 -0
- package/resources/skills/skills/career/job-hunter/README.md +323 -0
- package/resources/skills/skills/career/job-hunter/SKILL.md +91 -0
- package/resources/skills/skills/career/job-hunter/agents/README.md +96 -0
- package/resources/skills/skills/career/job-hunter/agents/apply-assessment-prep.md +195 -0
- package/resources/skills/skills/career/job-hunter/agents/apply-ats-scan.md +155 -0
- package/resources/skills/skills/career/job-hunter/agents/apply-bias-audit.md +224 -0
- package/resources/skills/skills/career/job-hunter/agents/apply-cover-letter.md +69 -0
- package/resources/skills/skills/career/job-hunter/agents/apply-decode-jd.md +117 -0
- package/resources/skills/skills/career/job-hunter/agents/apply-fit-score.md +183 -0
- package/resources/skills/skills/career/job-hunter/agents/apply-linkedin-audit.md +74 -0
- package/resources/skills/skills/career/job-hunter/agents/apply-linkedin-scrape.md +255 -0
- package/resources/skills/skills/career/job-hunter/agents/apply-portfolio-brief.md +123 -0
- package/resources/skills/skills/career/job-hunter/agents/apply-reality-check.md +164 -0
- package/resources/skills/skills/career/job-hunter/agents/apply-reference-prep.md +150 -0
- package/resources/skills/skills/career/job-hunter/agents/apply-rejection-analysis.md +172 -0
- package/resources/skills/skills/career/job-hunter/agents/apply-resume.md +70 -0
- package/resources/skills/skills/career/job-hunter/agents/apply-skills-gap-filler.md +109 -0
- package/resources/skills/skills/career/job-hunter/agents/career-internal.md +94 -0
- package/resources/skills/skills/career/job-hunter/agents/career-linkedin-content.md +173 -0
- package/resources/skills/skills/career/job-hunter/agents/career-linkedin-scanner.md +262 -0
- package/resources/skills/skills/career/job-hunter/agents/career-network-message.md +108 -0
- package/resources/skills/skills/career/job-hunter/agents/career-promote.md +102 -0
- package/resources/skills/skills/career/job-hunter/agents/career-review.md +71 -0
- package/resources/skills/skills/career/job-hunter/agents/interview-debrief.md +117 -0
- package/resources/skills/skills/career/job-hunter/agents/interview-mock.md +171 -0
- package/resources/skills/skills/career/job-hunter/agents/interview-panel-decoder.md +152 -0
- package/resources/skills/skills/career/job-hunter/agents/interview-prep.md +184 -0
- package/resources/skills/skills/career/job-hunter/agents/interview-question-bank.md +133 -0
- package/resources/skills/skills/career/job-hunter/agents/interview-research.md +148 -0
- package/resources/skills/skills/career/job-hunter/agents/offer-compare.md +117 -0
- package/resources/skills/skills/career/job-hunter/agents/offer-counteroffer.md +144 -0
- package/resources/skills/skills/career/job-hunter/agents/offer-deadline-manager.md +148 -0
- package/resources/skills/skills/career/job-hunter/agents/offer-negotiate.md +126 -0
- package/resources/skills/skills/career/job-hunter/agents/offer-schedule.md +99 -0
- package/resources/skills/skills/career/job-hunter/agents/offer-thankyou.md +80 -0
- package/resources/skills/skills/career/job-hunter/agents/search-company-research.md +146 -0
- package/resources/skills/skills/career/job-hunter/agents/search-follow-up.md +129 -0
- package/resources/skills/skills/career/job-hunter/agents/search-ghost-job-detector.md +152 -0
- package/resources/skills/skills/career/job-hunter/agents/search-inbox-scan.md +193 -0
- package/resources/skills/skills/career/job-hunter/agents/search-interview-scorecard.md +164 -0
- package/resources/skills/skills/career/job-hunter/agents/search-jobs.md +149 -0
- package/resources/skills/skills/career/job-hunter/agents/search-momentum-check.md +194 -0
- package/resources/skills/skills/career/job-hunter/agents/search-outreach.md +85 -0
- package/resources/skills/skills/career/job-hunter/agents/search-referral-finder.md +124 -0
- package/resources/skills/skills/career/job-hunter/agents/search-salary.md +96 -0
- package/resources/skills/skills/career/job-hunter/agents/search-send-email.md +109 -0
- package/resources/skills/skills/career/job-hunter/agents/search-tracker-update.md +127 -0
- package/resources/skills/skills/career/job-hunter/inputs/README.md +26 -0
- package/resources/skills/skills/career/job-hunter/inputs/apply-linkedin-url.txt +8 -0
- package/resources/skills/skills/career/job-hunter/inputs/interview-context.md +24 -0
- package/resources/skills/skills/career/job-hunter/inputs/job-description.md +20 -0
- package/resources/skills/skills/career/job-hunter/inputs/job-search-criteria.md +36 -0
- package/resources/skills/skills/career/job-hunter/inputs/my-linkedin.md +24 -0
- package/resources/skills/skills/career/job-hunter/inputs/my-resume.md +28 -0
- package/resources/skills/skills/career/job-hunter/inputs/search-outreach-target.md +24 -0
- package/resources/skills/skills/career/job-hunter/rules/README.md +37 -0
- package/resources/skills/skills/career/job-hunter/rules/writing-rules.md +81 -0
- package/resources/skills/skills/design/banana/SKILL.md +375 -0
- package/resources/skills/skills/design/banana/references/cost-tracking.md +47 -0
- package/resources/skills/skills/design/banana/references/gemini-models.md +236 -0
- package/resources/skills/skills/design/banana/references/mcp-tools.md +145 -0
- package/resources/skills/skills/design/banana/references/post-processing.md +192 -0
- package/resources/skills/skills/design/banana/references/presets.md +69 -0
- package/resources/skills/skills/design/banana/references/prompt-engineering.md +481 -0
- package/resources/skills/skills/design/banana/scripts/batch.py +97 -0
- package/resources/skills/skills/design/banana/scripts/cost_tracker.py +191 -0
- package/resources/skills/skills/design/banana/scripts/edit.py +159 -0
- package/resources/skills/skills/design/banana/scripts/generate.py +168 -0
- package/resources/skills/skills/design/banana/scripts/presets.py +154 -0
- package/resources/skills/skills/design/banana/scripts/setup_mcp.py +151 -0
- package/resources/skills/skills/design/banana/scripts/validate_setup.py +133 -0
- package/resources/skills/skills/gstack/ship/SKILL.md +13 -0
- package/resources/skills/skills/media/3d-logo-animation/SKILL.md +59 -0
- package/resources/skills/skills/media/action-figure-generator/SKILL.md +48 -0
- package/resources/skills/skills/media/ad-creative/SKILL.md +79 -0
- package/resources/skills/skills/media/ai-clipping/SKILL.md +194 -0
- package/resources/skills/skills/media/ai-clipping/scripts/run-ai-clipping.sh +200 -0
- package/resources/skills/skills/media/ai-fight-scene/SKILL.md +132 -0
- package/resources/skills/skills/media/amazon-product-listing/SKILL.md +68 -0
- package/resources/skills/skills/media/animal-video-generator/SKILL.md +59 -0
- package/resources/skills/skills/media/award-ceremony-video/SKILL.md +87 -0
- package/resources/skills/skills/media/blog-header/SKILL.md +61 -0
- package/resources/skills/skills/media/brand-kit/SKILL.md +72 -0
- package/resources/skills/skills/media/brochures/SKILL.md +65 -0
- package/resources/skills/skills/media/cartoon-dance-animation/SKILL.md +62 -0
- package/resources/skills/skills/media/character-story-video/SKILL.md +84 -0
- package/resources/skills/skills/media/chibi-collage-effect/SKILL.md +63 -0
- package/resources/skills/skills/media/cinema-director/SKILL.md +93 -0
- package/resources/skills/skills/media/cinema-director/scripts/generate-film.sh +78 -0
- package/resources/skills/skills/media/color-analysis-board/SKILL.md +71 -0
- package/resources/skills/skills/media/core-edit/SKILL.md +48 -0
- package/resources/skills/skills/media/core-edit/edit-image.sh +54 -0
- package/resources/skills/skills/media/core-edit/enhance-image.sh +191 -0
- package/resources/skills/skills/media/core-edit/lipsync.sh +144 -0
- package/resources/skills/skills/media/core-edit/video-effects.sh +193 -0
- package/resources/skills/skills/media/core-media/SKILL.md +49 -0
- package/resources/skills/skills/media/core-media/create-music.sh +169 -0
- package/resources/skills/skills/media/core-media/generate-image.sh +161 -0
- package/resources/skills/skills/media/core-media/generate-video.sh +137 -0
- package/resources/skills/skills/media/core-media/image-to-video.sh +228 -0
- package/resources/skills/skills/media/core-media/schema_data.json +18708 -0
- package/resources/skills/skills/media/core-media/upload.sh +41 -0
- package/resources/skills/skills/media/core-platform/SKILL.md +41 -0
- package/resources/skills/skills/media/core-platform/check-result.sh +37 -0
- package/resources/skills/skills/media/core-platform/setup.sh +31 -0
- package/resources/skills/skills/media/couple-grid-creator/SKILL.md +47 -0
- package/resources/skills/skills/media/design-guide/SKILL.md +73 -0
- package/resources/skills/skills/media/drone-style-video/SKILL.md +61 -0
- package/resources/skills/skills/media/fashion-try-on/SKILL.md +61 -0
- package/resources/skills/skills/media/floor-plan-rendering/SKILL.md +56 -0
- package/resources/skills/skills/media/freeze-effect-video/SKILL.md +100 -0
- package/resources/skills/skills/media/giant-product-showcase/SKILL.md +61 -0
- package/resources/skills/skills/media/instagram-post/SKILL.md +58 -0
- package/resources/skills/skills/media/interior-design/SKILL.md +61 -0
- package/resources/skills/skills/media/interior-design-visualizer/SKILL.md +57 -0
- package/resources/skills/skills/media/jewelry-product-video/SKILL.md +61 -0
- package/resources/skills/skills/media/kdenlive/SKILL.md +106 -0
- package/resources/skills/skills/media/kdenlive/scripts/assemble.sh +57 -0
- package/resources/skills/skills/media/kdenlive/scripts/common.sh +30 -0
- package/resources/skills/skills/media/kdenlive/scripts/inspect.sh +19 -0
- package/resources/skills/skills/media/kdenlive/scripts/reframe.sh +22 -0
- package/resources/skills/skills/media/kdenlive/scripts/render.sh +16 -0
- package/resources/skills/skills/media/kdenlive/scripts/title-card.sh +25 -0
- package/resources/skills/skills/media/keyboard-art-maker/SKILL.md +44 -0
- package/resources/skills/skills/media/logo-branding/SKILL.md +70 -0
- package/resources/skills/skills/media/logo-creator/SKILL.md +80 -0
- package/resources/skills/skills/media/logo-creator/scripts/create-logo.sh +38 -0
- package/resources/skills/skills/media/logo-generator/SKILL.md +56 -0
- package/resources/skills/skills/media/multi-angle-reshoot/SKILL.md +70 -0
- package/resources/skills/skills/media/multi-angle-shots/SKILL.md +73 -0
- package/resources/skills/skills/media/music-video/SKILL.md +61 -0
- package/resources/skills/skills/media/nano-banana/SKILL.md +80 -0
- package/resources/skills/skills/media/nano-banana/scripts/generate-nano-art.sh +54 -0
- package/resources/skills/skills/media/one-shot-video/SKILL.md +56 -0
- package/resources/skills/skills/media/photo-pack-generator/SKILL.md +205 -0
- package/resources/skills/skills/media/photo-pack-generator/scripts/generate-pack.sh +241 -0
- package/resources/skills/skills/media/product-ad-cinematic/SKILL.md +78 -0
- package/resources/skills/skills/media/product-campaign/SKILL.md +76 -0
- package/resources/skills/skills/media/product-showcase-video/SKILL.md +60 -0
- package/resources/skills/skills/media/product-video-ad-maker/SKILL.md +59 -0
- package/resources/skills/skills/media/rednote-cover/SKILL.md +57 -0
- package/resources/skills/skills/media/seedance-2/SKILL.md +632 -0
- package/resources/skills/skills/media/seedance-2/scripts/generate-seedance.sh +701 -0
- package/resources/skills/skills/media/selfie-with-celebrities/SKILL.md +64 -0
- package/resources/skills/skills/media/social-media-video/SKILL.md +277 -0
- package/resources/skills/skills/media/social-media-video/scripts/run-social-video.sh +316 -0
- package/resources/skills/skills/media/social-pack/SKILL.md +58 -0
- package/resources/skills/skills/media/storyboard/SKILL.md +57 -0
- package/resources/skills/skills/media/storyboard-to-cooking-video/SKILL.md +143 -0
- package/resources/skills/skills/media/talking-baby-video/SKILL.md +57 -0
- package/resources/skills/skills/media/ugc-ads-workflow/SKILL.md +70 -0
- package/resources/skills/skills/media/ugc-lifestyle-try-on/SKILL.md +65 -0
- package/resources/skills/skills/media/ugc-video-factory/SKILL.md +134 -0
- package/resources/skills/skills/media/ui-design/SKILL.md +81 -0
- package/resources/skills/skills/media/ui-design/scripts/generate-mockup.sh +49 -0
- package/resources/skills/skills/media/url-to-design/SKILL.md +61 -0
- package/resources/skills/skills/media/workflow/SKILL.md +197 -0
- package/resources/skills/skills/media/workflow/scripts/discover-workflow.sh +18 -0
- package/resources/skills/skills/media/workflow/scripts/generate-workflow.sh +33 -0
- package/resources/skills/skills/media/workflow/scripts/interactive-run.sh +16 -0
- package/resources/skills/skills/media/workflow/scripts/list-workflows.sh +20 -0
- package/resources/skills/skills/media/workflow/scripts/run-workflow.sh +34 -0
- package/resources/skills/skills/media/youtube-shorts/SKILL.md +173 -0
- package/resources/skills/skills/media/youtube-shorts/scripts/run-youtube-shorts.sh +141 -0
- package/resources/skills/skills/media/youtube-thumbnail/SKILL.md +66 -0
- package/resources/skills/skills/meta/cue-developer/references/architecture.md +2 -2
- package/resources/skills/skills/meta/cue-usage/SKILL.md +1 -1
- package/resources/skills/skills/meta/profile-fit-monitor/SKILL.md +2 -2
- package/resources/skills/skills/meta/profile-optimizer/SKILL.md +1 -1
- package/resources/skills/skills/meta/profile-suggest/SKILL.md +7 -7
- package/resources/skills/skills/meta/profile-summon/SKILL.md +159 -0
- package/resources/skills/skills/meta/profile-summon/evals/evals.json +53 -0
- package/resources/skills/skills/meta/save-profile/SKILL.md +1 -1
- package/resources/skills/skills/meta/skill-reviewer/SKILL.md +3 -0
- package/resources/skills/skills/meta/skill-reviewer/references/tdd-for-skills.md +55 -0
- package/resources/skills/skills/research/find-skills/SKILL.md +1 -1
- package/resources/skills/skills/review/code-review-deep/SKILL.md +20 -0
- package/resources/skills/skills/security/trivy-scan/SKILL.md +139 -0
- package/resources/skills/skills/security/trivy-scan/scripts/ensure-trivy.sh +21 -0
- package/resources/skills/skills/tools/ccusage/SKILL.md +142 -0
- package/src/commands/_index.ts +8 -0
- package/src/commands/ai.ts +2 -2
- package/src/commands/auto-detect.test.ts +74 -0
- package/src/commands/auto-detect.ts +9 -7
- package/src/commands/cli.test.ts +20 -4
- package/src/commands/cli.ts +36 -20
- package/src/commands/create-profile.ts +2 -2
- package/src/commands/debug.ts +2 -2
- package/src/commands/discover.ts +14 -4
- package/src/commands/export-docker.ts +1 -1
- package/src/commands/features-batch1.test.ts +1 -1
- package/src/commands/gates.ts +1 -1
- package/src/commands/import-profile.ts +1 -1
- package/src/commands/init.ts +15 -11
- package/src/commands/install.test.ts +192 -0
- package/src/commands/install.ts +610 -0
- package/src/commands/launch-handoff.e2e.test.ts +33 -1
- package/src/commands/launch.e2e.test.ts +15 -10
- package/src/commands/launch.ts +73 -116
- package/src/commands/materialize.ts +2 -2
- package/src/commands/prune.ts +1 -1
- package/src/commands/security-audit.ts +1 -1
- package/src/commands/shell.ts +7 -7
- package/src/commands/skill-report.ts +1 -1
- package/src/commands/skills.ts +3 -3
- package/src/commands/snapshot.ts +2 -2
- package/src/commands/summon.test.ts +116 -0
- package/src/commands/summon.ts +338 -0
- package/src/commands/trigger-gaps.ts +1 -1
- package/src/commands/use.ts +47 -3
- package/src/commands/watch-live.ts +5 -5
- package/src/commands/watch.ts +8 -8
- package/src/index.ts +2 -0
- package/src/lib/active-sessions.test.ts +3 -3
- package/src/lib/active-sessions.ts +4 -4
- package/src/lib/auto-detect.test.ts +172 -8
- package/src/lib/auto-detect.ts +191 -136
- package/src/lib/codex-persona-parity.test.ts +58 -0
- package/src/lib/companion-detect.test.ts +43 -1
- package/src/lib/companion-detect.ts +35 -0
- package/src/lib/credentials-sync.test.ts +121 -1
- package/src/lib/credentials-sync.ts +95 -1
- package/src/lib/cwd-resolver.test.ts +8 -8
- package/src/lib/cwd-resolver.ts +2 -2
- package/src/lib/dashboard-merge.test.ts +9 -4
- package/src/lib/dashboard-server.ts +1 -1
- package/src/lib/picker.test.ts +1 -1
- package/src/lib/picker.ts +5 -5
- package/src/lib/profile-merge.test.ts +8 -0
- package/src/lib/profile-names.test.ts +3 -3
- package/src/lib/runtime-install.ts +166 -0
- package/src/lib/runtime-materializer.test.ts +137 -0
- package/src/lib/runtime-materializer.ts +105 -2
- package/src/lib/skill-router.test.ts +38 -0
- package/src/lib/skill-router.ts +65 -4
- package/profiles/eu-tender-research/README.md +0 -48
- package/profiles/eu-tender-research/logo.png +0 -0
- package/profiles/eu-tender-research/profile.yaml +0 -108
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Setup script for Banana Claude MCP server in Claude Code.
|
|
4
|
+
|
|
5
|
+
Configures @ycse/nanobanana-mcp in Claude Code's settings.json
|
|
6
|
+
with the user's Google AI API key.
|
|
7
|
+
|
|
8
|
+
Usage:
|
|
9
|
+
python3 setup_mcp.py # Interactive (prompts for key)
|
|
10
|
+
python3 setup_mcp.py --key YOUR_KEY # Non-interactive
|
|
11
|
+
python3 setup_mcp.py --check # Verify existing setup
|
|
12
|
+
python3 setup_mcp.py --remove # Remove MCP config
|
|
13
|
+
python3 setup_mcp.py --help # Show usage
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
import json
|
|
17
|
+
import sys
|
|
18
|
+
import os
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
|
|
21
|
+
SETTINGS_PATH = Path.home() / ".claude" / "settings.json"
|
|
22
|
+
MCP_NAME = "nanobanana-mcp"
|
|
23
|
+
MCP_PACKAGE = "@ycse/nanobanana-mcp"
|
|
24
|
+
DEFAULT_MODEL = "gemini-3.1-flash-image-preview"
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def load_settings() -> dict:
|
|
28
|
+
"""Load Claude Code settings.json."""
|
|
29
|
+
if not SETTINGS_PATH.exists():
|
|
30
|
+
return {}
|
|
31
|
+
with open(SETTINGS_PATH, "r") as f:
|
|
32
|
+
return json.load(f)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def save_settings(settings: dict) -> None:
|
|
36
|
+
"""Save Claude Code settings.json."""
|
|
37
|
+
SETTINGS_PATH.parent.mkdir(parents=True, exist_ok=True)
|
|
38
|
+
with open(SETTINGS_PATH, "w") as f:
|
|
39
|
+
json.dump(settings, f, indent=2)
|
|
40
|
+
print(f"Settings saved to {SETTINGS_PATH}")
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def check_setup() -> bool:
|
|
44
|
+
"""Check if MCP is already configured."""
|
|
45
|
+
settings = load_settings()
|
|
46
|
+
servers = settings.get("mcpServers", {})
|
|
47
|
+
if MCP_NAME in servers:
|
|
48
|
+
env = servers[MCP_NAME].get("env", {})
|
|
49
|
+
key = env.get("GOOGLE_AI_API_KEY", "")
|
|
50
|
+
masked = key[:8] + "..." + key[-4:] if len(key) > 12 else "(not set)"
|
|
51
|
+
print(f"MCP server '{MCP_NAME}' is configured.")
|
|
52
|
+
print(f" Package: {MCP_PACKAGE}")
|
|
53
|
+
print(f" API Key: {masked}")
|
|
54
|
+
print(f" Model: {env.get('NANOBANANA_MODEL', DEFAULT_MODEL)}")
|
|
55
|
+
return True
|
|
56
|
+
print(f"MCP server '{MCP_NAME}' is NOT configured.")
|
|
57
|
+
return False
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def remove_mcp() -> None:
|
|
61
|
+
"""Remove MCP configuration."""
|
|
62
|
+
settings = load_settings()
|
|
63
|
+
servers = settings.get("mcpServers", {})
|
|
64
|
+
if MCP_NAME in servers:
|
|
65
|
+
del servers[MCP_NAME]
|
|
66
|
+
settings["mcpServers"] = servers
|
|
67
|
+
save_settings(settings)
|
|
68
|
+
print(f"Removed '{MCP_NAME}' from Claude Code settings.")
|
|
69
|
+
else:
|
|
70
|
+
print(f"'{MCP_NAME}' not found in settings.")
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def setup_mcp(api_key: str) -> None:
|
|
74
|
+
"""Configure MCP server in Claude Code settings."""
|
|
75
|
+
if not api_key or not api_key.strip():
|
|
76
|
+
print("Error: API key cannot be empty.")
|
|
77
|
+
sys.exit(1)
|
|
78
|
+
|
|
79
|
+
api_key = api_key.strip()
|
|
80
|
+
settings = load_settings()
|
|
81
|
+
|
|
82
|
+
if "mcpServers" not in settings:
|
|
83
|
+
settings["mcpServers"] = {}
|
|
84
|
+
|
|
85
|
+
settings["mcpServers"][MCP_NAME] = {
|
|
86
|
+
"command": "npx",
|
|
87
|
+
"args": ["-y", MCP_PACKAGE],
|
|
88
|
+
"env": {
|
|
89
|
+
"GOOGLE_AI_API_KEY": api_key,
|
|
90
|
+
"NANOBANANA_MODEL": DEFAULT_MODEL,
|
|
91
|
+
},
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
save_settings(settings)
|
|
95
|
+
print(f"\nMCP server '{MCP_NAME}' configured successfully!")
|
|
96
|
+
print(f" Package: {MCP_PACKAGE}")
|
|
97
|
+
print(f" Model: {DEFAULT_MODEL}")
|
|
98
|
+
print(f"\nRestart Claude Code for changes to take effect.")
|
|
99
|
+
print(f"Generated images will be saved to: ~/Documents/nanobanana_generated/")
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def main() -> None:
|
|
103
|
+
args = sys.argv[1:]
|
|
104
|
+
|
|
105
|
+
if "--help" in args or "-h" in args:
|
|
106
|
+
print("Usage: python3 setup_mcp.py [OPTIONS]")
|
|
107
|
+
print()
|
|
108
|
+
print("Options:")
|
|
109
|
+
print(" --key KEY Provide API key non-interactively")
|
|
110
|
+
print(" --check Verify existing setup")
|
|
111
|
+
print(" --remove Remove MCP configuration")
|
|
112
|
+
print(" --help, -h Show this help message")
|
|
113
|
+
print()
|
|
114
|
+
print("Get a free API key at: https://aistudio.google.com/apikey")
|
|
115
|
+
sys.exit(0)
|
|
116
|
+
|
|
117
|
+
if "--check" in args:
|
|
118
|
+
check_setup()
|
|
119
|
+
return
|
|
120
|
+
|
|
121
|
+
if "--remove" in args:
|
|
122
|
+
remove_mcp()
|
|
123
|
+
return
|
|
124
|
+
|
|
125
|
+
# Get API key
|
|
126
|
+
api_key = None
|
|
127
|
+
for i, arg in enumerate(args):
|
|
128
|
+
if arg == "--key" and i + 1 < len(args):
|
|
129
|
+
api_key = args[i + 1]
|
|
130
|
+
break
|
|
131
|
+
|
|
132
|
+
if not api_key:
|
|
133
|
+
# Check environment
|
|
134
|
+
api_key = os.environ.get("GOOGLE_AI_API_KEY")
|
|
135
|
+
|
|
136
|
+
if not api_key:
|
|
137
|
+
print("Banana Claude -- MCP Setup")
|
|
138
|
+
print("=" * 40)
|
|
139
|
+
print(f"\nGet your free API key at: https://aistudio.google.com/apikey")
|
|
140
|
+
print()
|
|
141
|
+
try:
|
|
142
|
+
api_key = input("Enter your Google AI API key: ")
|
|
143
|
+
except (EOFError, KeyboardInterrupt):
|
|
144
|
+
print("\nError: No input received. Provide a key with --key or set GOOGLE_AI_API_KEY env var.")
|
|
145
|
+
sys.exit(1)
|
|
146
|
+
|
|
147
|
+
setup_mcp(api_key)
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
if __name__ == "__main__":
|
|
151
|
+
main()
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Validate that the Banana Claude MCP server is properly configured.
|
|
4
|
+
|
|
5
|
+
Checks:
|
|
6
|
+
1. Claude Code settings.json has the MCP entry
|
|
7
|
+
2. API key is present
|
|
8
|
+
3. Node.js/npx is available
|
|
9
|
+
4. Output directory exists or can be created
|
|
10
|
+
|
|
11
|
+
Usage:
|
|
12
|
+
python3 validate_setup.py
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
import json
|
|
16
|
+
import shutil
|
|
17
|
+
import sys
|
|
18
|
+
from pathlib import Path
|
|
19
|
+
|
|
20
|
+
SETTINGS_PATH = Path.home() / ".claude" / "settings.json"
|
|
21
|
+
MCP_NAME = "nanobanana-mcp"
|
|
22
|
+
OUTPUT_DIR = Path.home() / "Documents" / "nanobanana_generated"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def check(label: str, passed: bool, detail: str = "") -> bool:
|
|
26
|
+
status = "PASS" if passed else "FAIL"
|
|
27
|
+
msg = f" [{status}] {label}"
|
|
28
|
+
if detail:
|
|
29
|
+
msg += f" -- {detail}"
|
|
30
|
+
print(msg)
|
|
31
|
+
return passed
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def main() -> int:
|
|
35
|
+
print("Banana Claude -- Setup Validation")
|
|
36
|
+
print("=" * 40)
|
|
37
|
+
results = []
|
|
38
|
+
|
|
39
|
+
# 1. Settings file exists
|
|
40
|
+
results.append(check(
|
|
41
|
+
"Claude Code settings.json exists",
|
|
42
|
+
SETTINGS_PATH.exists(),
|
|
43
|
+
str(SETTINGS_PATH),
|
|
44
|
+
))
|
|
45
|
+
|
|
46
|
+
if not SETTINGS_PATH.exists():
|
|
47
|
+
print("\nCannot continue without settings.json.")
|
|
48
|
+
return 1
|
|
49
|
+
|
|
50
|
+
# 2. Load and parse settings
|
|
51
|
+
try:
|
|
52
|
+
with open(SETTINGS_PATH) as f:
|
|
53
|
+
settings = json.load(f)
|
|
54
|
+
results.append(check("settings.json is valid JSON", True))
|
|
55
|
+
except json.JSONDecodeError as e:
|
|
56
|
+
results.append(check("settings.json is valid JSON", False, str(e)))
|
|
57
|
+
return 1
|
|
58
|
+
|
|
59
|
+
# 3. MCP entry exists
|
|
60
|
+
servers = settings.get("mcpServers", {})
|
|
61
|
+
has_mcp = MCP_NAME in servers
|
|
62
|
+
results.append(check(f"MCP server '{MCP_NAME}' configured", has_mcp))
|
|
63
|
+
|
|
64
|
+
if has_mcp:
|
|
65
|
+
mcp = servers[MCP_NAME]
|
|
66
|
+
|
|
67
|
+
# 4. Command is npx
|
|
68
|
+
results.append(check(
|
|
69
|
+
"Command is 'npx'",
|
|
70
|
+
mcp.get("command") == "npx",
|
|
71
|
+
mcp.get("command", "(missing)"),
|
|
72
|
+
))
|
|
73
|
+
|
|
74
|
+
# 5. Package is correct
|
|
75
|
+
args = mcp.get("args", [])
|
|
76
|
+
has_pkg = "@ycse/nanobanana-mcp" in args
|
|
77
|
+
results.append(check(
|
|
78
|
+
"Package is @ycse/nanobanana-mcp",
|
|
79
|
+
has_pkg,
|
|
80
|
+
str(args),
|
|
81
|
+
))
|
|
82
|
+
|
|
83
|
+
# 6. API key present
|
|
84
|
+
env = mcp.get("env", {})
|
|
85
|
+
key = env.get("GOOGLE_AI_API_KEY", "")
|
|
86
|
+
results.append(check(
|
|
87
|
+
"GOOGLE_AI_API_KEY is set",
|
|
88
|
+
bool(key),
|
|
89
|
+
f"{key[:8]}...{key[-4:]}" if len(key) > 12 else "(empty or short)",
|
|
90
|
+
))
|
|
91
|
+
|
|
92
|
+
# 7. Model configured
|
|
93
|
+
model = env.get("NANOBANANA_MODEL", "")
|
|
94
|
+
results.append(check(
|
|
95
|
+
"NANOBANANA_MODEL is set",
|
|
96
|
+
bool(model),
|
|
97
|
+
model or "(not set, will use package default)",
|
|
98
|
+
))
|
|
99
|
+
|
|
100
|
+
# 8. Node.js/npx available
|
|
101
|
+
has_npx = shutil.which("npx") is not None
|
|
102
|
+
results.append(check(
|
|
103
|
+
"npx is available in PATH",
|
|
104
|
+
has_npx,
|
|
105
|
+
shutil.which("npx") or "not found",
|
|
106
|
+
))
|
|
107
|
+
|
|
108
|
+
# 9. Output directory
|
|
109
|
+
if OUTPUT_DIR.exists():
|
|
110
|
+
results.append(check("Output directory exists", True, str(OUTPUT_DIR)))
|
|
111
|
+
else:
|
|
112
|
+
try:
|
|
113
|
+
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
|
|
114
|
+
results.append(check("Output directory created", True, str(OUTPUT_DIR)))
|
|
115
|
+
except OSError as e:
|
|
116
|
+
results.append(check("Output directory writable", False, str(e)))
|
|
117
|
+
|
|
118
|
+
# Summary
|
|
119
|
+
passed = sum(1 for r in results if r)
|
|
120
|
+
total = len(results)
|
|
121
|
+
print(f"\n{'=' * 40}")
|
|
122
|
+
print(f"Results: {passed}/{total} checks passed")
|
|
123
|
+
|
|
124
|
+
if passed == total:
|
|
125
|
+
print("Status: Ready to generate images!")
|
|
126
|
+
return 0
|
|
127
|
+
else:
|
|
128
|
+
print("Status: Some checks failed. Fix the issues above.")
|
|
129
|
+
return 1
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
if __name__ == "__main__":
|
|
133
|
+
sys.exit(main())
|
|
@@ -1154,6 +1154,19 @@ Before reviewing code quality, check: **did they build what was requested — no
|
|
|
1154
1154
|
|
|
1155
1155
|
Review the diff for structural issues that tests don't catch.
|
|
1156
1156
|
|
|
1157
|
+
0. **Supply-chain gate (Trivy, always first).** Run the `security/trivy-scan`
|
|
1158
|
+
gate before the manual review. Code review does not catch a known CVE in a
|
|
1159
|
+
transitive dependency, a committed secret, or a Dockerfile/IaC misconfig.
|
|
1160
|
+
|
|
1161
|
+
```bash
|
|
1162
|
+
trivy fs --scanners vuln,secret,misconfig --severity HIGH,CRITICAL --exit-code 1 --no-progress --skip-dirs "**/node_modules" --skip-dirs "**/_cache" --skip-dirs "**/dist" --skip-dirs "**/.next" --skip-dirs "**/vendor" .
|
|
1163
|
+
```
|
|
1164
|
+
|
|
1165
|
+
Exit 1 (HIGH/CRITICAL) is a **P0 ship blocker**: report the rows +
|
|
1166
|
+
remediation and STOP, same as a critical review finding. Trivy missing →
|
|
1167
|
+
install via `security/trivy-scan`'s `scripts/ensure-trivy.sh`; a gate that
|
|
1168
|
+
could not run is a block, not a silent pass. Exit 0 → continue.
|
|
1169
|
+
|
|
1157
1170
|
1. Read `.claude/skills/review/checklist.md`. If the file cannot be read, **STOP** and report the error.
|
|
1158
1171
|
|
|
1159
1172
|
2. Run `git diff origin/<base>` to get the full diff (scoped to feature changes against the freshly-fetched base branch).
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
---
|
|
2
|
+
slug: muapi-3d-logo-animation
|
|
3
|
+
name: muapi-3d-logo-animation
|
|
4
|
+
version: "1.0.0"
|
|
5
|
+
description: Transform a 2D logo into a premium 3D version and animate it with professional cinematic effects.
|
|
6
|
+
acceptLicenseTerms: true
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# 3D Logo Animation
|
|
11
|
+
|
|
12
|
+
**Transform a 2D logo into a premium 3D version and animate it with professional cinematic effects.**
|
|
13
|
+
|
|
14
|
+
## Inputs
|
|
15
|
+
|
|
16
|
+
| Name | Type | Required | Default | Description |
|
|
17
|
+
|:---|:---|:---|:---|:---|
|
|
18
|
+
| `logo_image` | image_url | yes | — | A clear 2D image of the logo to be converted to 3D. |
|
|
19
|
+
| `material_style` | text | no | glossy glass and chrome | The material style for the 3D logo (e.g., gold, matte plastic, holographic). |
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
## Steps
|
|
23
|
+
|
|
24
|
+
### Phase A — 3D Logo Transformation
|
|
25
|
+
|
|
26
|
+
If `{{logo_image}}` is not provided, ask the user to upload their logo.
|
|
27
|
+
|
|
28
|
+
Once the logo is available, submit the plan with ONE step to convert it to 3D:
|
|
29
|
+
|
|
30
|
+
1. **3D Logo Generation** — `muapi image edit` (model=`nano-banana-2-edit`):
|
|
31
|
+
- Reference Image: `{{logo_image}}`
|
|
32
|
+
- Prompt: `Transform this 2D logo into a premium, high-quality 3D version. The logo should have depth and be made of {{material_style}}. Smooth edges, realistic reflections, and professional studio lighting. The logo is centered on a clean, minimal, out-of-focus background. High-end graphic design aesthetic, 8k resolution.`
|
|
33
|
+
- Aspect ratio: 1:1 or 4:3
|
|
34
|
+
|
|
35
|
+
Present the 3D logo to the user for approval.
|
|
36
|
+
|
|
37
|
+
### Phase B — Cinematic Logo Animation
|
|
38
|
+
|
|
39
|
+
Once the 3D logo is ready, submit the plan to animate it:
|
|
40
|
+
|
|
41
|
+
1. **Logo Animation** — `muapi video from-image` (model=`veo3.1-fast-image-to-video`):
|
|
42
|
+
- Reference Image: The 3D logo from Phase A.
|
|
43
|
+
- Prompt: `A professional cinematic logo reveal animation. The 3D logo rotates slowly with dynamic light sweeps reflecting off its {{material_style}} surface. Subtle camera movement, particle effects in the background, high-quality motion graphics style.`
|
|
44
|
+
- Aspect ratio: 16:9 or 1:1
|
|
45
|
+
|
|
46
|
+
After generation, present the final 3D logo animation to the user.
|
|
47
|
+
|
|
48
|
+
## Trigger Keywords
|
|
49
|
+
|
|
50
|
+
`3d logo`, `logo animation`, `2d to 3d logo`, `animated logo`, `cinematic logo`
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Notes for the Executing Agent
|
|
56
|
+
|
|
57
|
+
- This recipe is LLM-orchestrated: read each phase, gather any missing inputs from the user, then call `muapi` CLI commands. Use `muapi auth configure` first if `MUAPI_API_KEY` is unset.
|
|
58
|
+
- For model IDs without a CLI alias yet, fall back to the raw endpoint via `curl -X POST https://api.muapi.ai/api/v1/<endpoint> -H "x-api-key: $MUAPI_API_KEY" -H 'content-type: application/json' -d '{...}'` and poll with `muapi predict wait <request_id>`.
|
|
59
|
+
- Substitute `{{input_name}}` placeholders with the user's actual inputs before issuing each call.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
---
|
|
2
|
+
slug: muapi-action-figure-generator
|
|
3
|
+
name: muapi-action-figure-generator
|
|
4
|
+
version: "1.0.0"
|
|
5
|
+
description: Convert a photo of a person into a custom 3D action figure, complete with collectible toy packaging.
|
|
6
|
+
acceptLicenseTerms: true
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# Action Figure Generator
|
|
11
|
+
|
|
12
|
+
**Convert a photo of a person into a custom 3D action figure, complete with collectible toy packaging.**
|
|
13
|
+
|
|
14
|
+
## Inputs
|
|
15
|
+
|
|
16
|
+
| Name | Type | Required | Default | Description |
|
|
17
|
+
|:---|:---|:---|:---|:---|
|
|
18
|
+
| `user_image` | image_url | yes | — | A clear photo of the person to be turned into an action figure. |
|
|
19
|
+
| `toy_theme` | text | no | superhero | The theme of the action figure (e.g. superhero, doctor, explorer, sci-fi). |
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
## Steps
|
|
23
|
+
|
|
24
|
+
### Phase A — Action Figure Creation
|
|
25
|
+
|
|
26
|
+
If `{{user_image}}` is not provided, ask the user to upload their photo.
|
|
27
|
+
|
|
28
|
+
Once the photo is available, submit the plan with ONE step to generate the action figure:
|
|
29
|
+
|
|
30
|
+
1. **Action Figure Generation** — `muapi image edit` (model=`nano-banana-2-edit`):
|
|
31
|
+
- Reference Image: `{{user_image}}`
|
|
32
|
+
- Prompt: `A high-quality 3D stylized action figure based on the person in the input image. The action figure should maintain the person's likeness (face, hairstyle, skin tone) but be rendered as a plastic toy with visible joints and a semi-glossy finish. The character is dressed in a {{toy_theme}} outfit. The figure is displayed inside its original collectible cardboard and plastic blister packaging. The packaging has the person's name printed on it and features clean, modern graphic design. Soft studio lighting, realistic plastic textures, 8k resolution, cinematic look.`
|
|
33
|
+
- Aspect ratio: 1:1 or 4:5
|
|
34
|
+
|
|
35
|
+
Present the generated action figure to the user. You can also suggest creating different themes (e.g., changing the character from a doctor to a space explorer).
|
|
36
|
+
|
|
37
|
+
## Trigger Keywords
|
|
38
|
+
|
|
39
|
+
`action figure`, `custom toy`, `toy packaging`, `character toy`, `collectible figure`
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Notes for the Executing Agent
|
|
45
|
+
|
|
46
|
+
- This recipe is LLM-orchestrated: read each phase, gather any missing inputs from the user, then call `muapi` CLI commands. Use `muapi auth configure` first if `MUAPI_API_KEY` is unset.
|
|
47
|
+
- For model IDs without a CLI alias yet, fall back to the raw endpoint via `curl -X POST https://api.muapi.ai/api/v1/<endpoint> -H "x-api-key: $MUAPI_API_KEY" -H 'content-type: application/json' -d '{...}'` and poll with `muapi predict wait <request_id>`.
|
|
48
|
+
- Substitute `{{input_name}}` placeholders with the user's actual inputs before issuing each call.
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
---
|
|
2
|
+
slug: muapi-ad-creative
|
|
3
|
+
name: muapi-ad-creative
|
|
4
|
+
version: "1.0.0"
|
|
5
|
+
description: Generate a high-converting ad creative set — hero image, ad copy variations, and platform-optimized crops for Meta, Google Display, and LinkedIn.
|
|
6
|
+
acceptLicenseTerms: true
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# Ad Creative Set
|
|
11
|
+
|
|
12
|
+
**Generate a high-converting ad creative set — hero image, ad copy variations, and platform-optimized crops for Meta, Google Display, and LinkedIn.**
|
|
13
|
+
|
|
14
|
+
## Inputs
|
|
15
|
+
|
|
16
|
+
| Name | Type | Required | Default | Description |
|
|
17
|
+
|:---|:---|:---|:---|:---|
|
|
18
|
+
| `product_or_service` | text | yes | — | What is being advertised (e.g. "SaaS project management tool for remote teams"). |
|
|
19
|
+
| `target_audience` | text | yes | — | Who the ad is for (e.g. "startup founders aged 25–40, tech-savvy"). |
|
|
20
|
+
| `campaign_goal` | text | no | awareness | Campaign objective — "awareness", "consideration", or "conversion". |
|
|
21
|
+
| `tone` | text | no | professional, clean, modern | Creative tone and visual style (e.g. "bold and disruptive", "luxury minimal", "friendly and approachable"). |
|
|
22
|
+
| `product_image` | image_url | no | — | Optional product or brand image URL already in the session. |
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
## Steps
|
|
26
|
+
|
|
27
|
+
This skill has TWO phases. Phase A creates the hero concept for approval; Phase B fans out to platform formats.
|
|
28
|
+
|
|
29
|
+
### Phase A — Hero image + Ad copy
|
|
30
|
+
|
|
31
|
+
Submit ONE the plan with:
|
|
32
|
+
|
|
33
|
+
1. **Hero image** — `muapi image generate` (model=nano-banana-pro) or `muapi image edit` (model=nano-banana-pro-edit) if `{{product_image}}` is provided:
|
|
34
|
+
- Aspect ratio: 1:1 (universal starting point).
|
|
35
|
+
- Prompt must capture: product/service benefit, target audience lifestyle cue, campaign tone.
|
|
36
|
+
- Style: `{{tone}}, advertising photography, clean background, product focus, ultra detailed, commercial quality`.
|
|
37
|
+
- Tier: quality.
|
|
38
|
+
|
|
39
|
+
After the plan executes, present the hero asset and 3 ad copy variations:
|
|
40
|
+
- **Variation A** — Problem-aware hook: "Tired of X? [Product] fixes that."
|
|
41
|
+
- **Variation B** — Benefit-led: "[Feature] → [Outcome] for [Audience]."
|
|
42
|
+
- **Variation C** — Social proof / urgency: "X teams already use [Product]."
|
|
43
|
+
Each variation includes: Headline (6 words max), Body (20–30 words), CTA button text.
|
|
44
|
+
|
|
45
|
+
Ask which copy variation to use for Phase B. Wait for user confirmation.
|
|
46
|
+
|
|
47
|
+
### Phase B — Platform crops
|
|
48
|
+
|
|
49
|
+
Once the user picks a copy direction, submit a SECOND the plan with parallel crops:
|
|
50
|
+
|
|
51
|
+
1. `muapi image edit` → 1:1 (Facebook/Instagram feed, 1080×1080)
|
|
52
|
+
2. `muapi image edit` → 9:16 (Story/Reels, 1080×1920)
|
|
53
|
+
3. `muapi image edit` → 1.91:1 (Facebook feed wide, 1200×628)
|
|
54
|
+
4. `muapi image edit` → 1:1 (LinkedIn feed, same as FB)
|
|
55
|
+
|
|
56
|
+
For each crop:
|
|
57
|
+
- Prompt: "Reframe for [platform] ad format. Keep product/subject centered and uncropped. Maintain original palette and tone. Leave headroom/footroom for text overlays."
|
|
58
|
+
- All crops run in parallel.
|
|
59
|
+
|
|
60
|
+
Return one asset per format with the recommended copy overlay placement for each.
|
|
61
|
+
|
|
62
|
+
## Notes
|
|
63
|
+
- If `campaign_goal` is "conversion", emphasize urgency and direct CTA in copy.
|
|
64
|
+
- If `campaign_goal` is "awareness", prioritize visual impact over text density.
|
|
65
|
+
- Reference `product_image` via `$nX.url` syntax in Phase B nodes to ensure consistency.
|
|
66
|
+
- Do NOT auto-confirm Phase B without user picking a copy variation.
|
|
67
|
+
|
|
68
|
+
## Trigger Keywords
|
|
69
|
+
|
|
70
|
+
`ad creative`, `advertisement`, `facebook ad`, `meta ad`, `google ad`, `linkedin ad`, `paid ad`, `ad banner`, `display ad`
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Notes for the Executing Agent
|
|
76
|
+
|
|
77
|
+
- This recipe is LLM-orchestrated: read each phase, gather any missing inputs from the user, then call `muapi` CLI commands. Use `muapi auth configure` first if `MUAPI_API_KEY` is unset.
|
|
78
|
+
- For model IDs without a CLI alias yet, fall back to the raw endpoint via `curl -X POST https://api.muapi.ai/api/v1/<endpoint> -H "x-api-key: $MUAPI_API_KEY" -H 'content-type: application/json' -d '{...}'` and poll with `muapi predict wait <request_id>`.
|
|
79
|
+
- Substitute `{{input_name}}` placeholders with the user's actual inputs before issuing each call.
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
---
|
|
2
|
+
slug: muapi-ai-clipping
|
|
3
|
+
name: muapi-ai-clipping
|
|
4
|
+
version: "1.0.0"
|
|
5
|
+
description: Turn a long video into N viral-ready short clips with a single managed API call. Wraps muapi.ai's `/ai-clipping` endpoint, which handles transcription, highlight ranking through a virality framework (hook / emotional peak / opinion bomb / revelation / conflict / quotable / story peak / practical value), overlap dedupe, and vertical face-tracking auto-crop server-side. No local Whisper, no local LLM, no GPU.
|
|
6
|
+
acceptLicenseTerms: true
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# AI Clipping
|
|
10
|
+
|
|
11
|
+
**One API call: long video in → ranked vertical short clips out.**
|
|
12
|
+
|
|
13
|
+
Each clip ships with a viral score (0–100), an opening hook line, a one-sentence "why it works" reason, and a hosted mp4 URL.
|
|
14
|
+
|
|
15
|
+
Underlying API: https://muapi.ai/playground/ai-clipping
|
|
16
|
+
Reference implementation (open source): https://github.com/SamurAIGPT/AI-Youtube-Shorts-Generator
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## When to Use
|
|
21
|
+
|
|
22
|
+
- Auto-clip a podcast, interview, lecture, vlog, or stream into TikTok / Reels / Shorts.
|
|
23
|
+
- Extract the best 30–75s moments from any hosted video URL.
|
|
24
|
+
- Get face-tracked vertical (9:16), square (1:1), or portrait (4:5) crops without running ffmpeg locally.
|
|
25
|
+
|
|
26
|
+
If you only need raw timestamps for your own renderer, set `--coords-only` to skip cropping and just get the highlight ranges.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Agent Execution Protocol
|
|
31
|
+
|
|
32
|
+
### Step 1 — Collect Inputs
|
|
33
|
+
|
|
34
|
+
| Input | Required | Default | Notes |
|
|
35
|
+
|:---|:---|:---|:---|
|
|
36
|
+
| `--video` | yes | — | Hosted mp4 URL, or local file path (auto-uploaded), or YouTube URL (if backend supports it) |
|
|
37
|
+
| `--num-clips` | no | `3` | Number of highlights to extract |
|
|
38
|
+
| `--aspect-ratio` | no | `9:16` | `9:16` \| `1:1` \| `4:5` |
|
|
39
|
+
| `--coords-only` | no | off | Return just the highlight time ranges, skip cropping |
|
|
40
|
+
|
|
41
|
+
If the user gave only a video URL, run with defaults — don't block on questions.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
### Step 2 — Verify Prerequisites
|
|
46
|
+
|
|
47
|
+
- `muapi-cli` installed and authed (`muapi auth configure`)
|
|
48
|
+
- `MUAPI_API_KEY` available (env var or `muapi auth status` passes)
|
|
49
|
+
|
|
50
|
+
That's it. No `ffmpeg`, no Python, no Whisper install, no LLM keys. Everything runs server-side.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
### Step 3 — Run the Skill
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
bash library/edit/ai-clipping/scripts/run-ai-clipping.sh \
|
|
58
|
+
--video "https://example.com/podcast.mp4" \
|
|
59
|
+
--num-clips 5 \
|
|
60
|
+
--aspect-ratio 9:16 \
|
|
61
|
+
--view
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
The script:
|
|
65
|
+
1. Resolves `--video` to a hosted URL (uploads local files via `muapi upload file` if needed).
|
|
66
|
+
2. Calls `muapi edit clipping` with the supported parameters.
|
|
67
|
+
3. Polls until the job is done (or returns the `request_id` immediately under `--async`).
|
|
68
|
+
4. Prints a ranked summary and, if `--output-json` is set, writes the full result.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## What Happens Server-Side
|
|
73
|
+
|
|
74
|
+
The `/ai-clipping` endpoint internally runs the full pipeline so the agent doesn't have to:
|
|
75
|
+
|
|
76
|
+
- **Transcribe** with Whisper.
|
|
77
|
+
- **Classify content type** (podcast / interview / tutorial / vlog / lecture / monologue).
|
|
78
|
+
- **Rank highlights** through the virality framework:
|
|
79
|
+
- **Hook moments** — strong opening line that stops the scroll
|
|
80
|
+
- **Emotional peaks** — laughter, anger, vulnerability, awe
|
|
81
|
+
- **Opinion bombs** — spicy, contrarian, debate-bait takes
|
|
82
|
+
- **Revelation moments** — "wait, what?" reframes
|
|
83
|
+
- **Conflict** — disagreement, tension, callouts
|
|
84
|
+
- **Quotable lines** — tight, screenshot-worthy phrasing
|
|
85
|
+
- **Story peaks** — climax of a narrative arc
|
|
86
|
+
- **Practical value** — actionable insight a viewer will save
|
|
87
|
+
- **Dedupe** overlapping candidates by score.
|
|
88
|
+
- **Top-N select** and **face-track auto-crop** to the requested aspect ratio.
|
|
89
|
+
|
|
90
|
+
This is why the skill is small: the heavy lifting is on the API.
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Quick Invocation Patterns
|
|
95
|
+
|
|
96
|
+
**Defaults — three 9:16 clips:**
|
|
97
|
+
```bash
|
|
98
|
+
bash run-ai-clipping.sh --video "https://example.com/long.mp4"
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**Podcast — more clips, view in player:**
|
|
102
|
+
```bash
|
|
103
|
+
bash run-ai-clipping.sh --video "<URL>" --num-clips 8 --view
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
**Square clips for Instagram feed:**
|
|
107
|
+
```bash
|
|
108
|
+
bash run-ai-clipping.sh --video "<URL>" --aspect-ratio 1:1 --num-clips 3
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**Just the timestamps (build your own renderer):**
|
|
112
|
+
```bash
|
|
113
|
+
bash run-ai-clipping.sh --video "<URL>" --coords-only --output-json result.json
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
**Async submit (returns request_id, poll later):**
|
|
117
|
+
```bash
|
|
118
|
+
REQUEST_ID=$(bash run-ai-clipping.sh --video "<URL>" --async --output-json - | jq -r '.request_id')
|
|
119
|
+
muapi predict wait "$REQUEST_ID" --download ./outputs
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
**Local file:**
|
|
123
|
+
```bash
|
|
124
|
+
bash run-ai-clipping.sh --video ./recording.mp4 --num-clips 5 --view
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
**Batch — `urls.txt` with one URL per line:**
|
|
128
|
+
```bash
|
|
129
|
+
xargs -a urls.txt -I{} bash run-ai-clipping.sh --video "{}"
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## Aspect Ratio Picker
|
|
135
|
+
|
|
136
|
+
| Platform | Ratio | Sweet-spot duration |
|
|
137
|
+
|:---|:---|:---|
|
|
138
|
+
| TikTok / Reels / YouTube Shorts | `9:16` | 30–75s |
|
|
139
|
+
| Instagram Feed | `1:1` | 15–45s |
|
|
140
|
+
| Pinterest / portrait | `4:5` | 30–60s |
|
|
141
|
+
|
|
142
|
+
Default to `9:16` unless the platform is specified.
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## Output Schema
|
|
147
|
+
|
|
148
|
+
```json
|
|
149
|
+
{
|
|
150
|
+
"source_video_url": "...",
|
|
151
|
+
"shorts": [
|
|
152
|
+
{
|
|
153
|
+
"title": "The one mistake that cost me $50K",
|
|
154
|
+
"start_time": 124.3,
|
|
155
|
+
"end_time": 187.6,
|
|
156
|
+
"score": 92,
|
|
157
|
+
"hook_sentence": "Nobody talks about this, but it killed my first startup...",
|
|
158
|
+
"virality_reason": "Opens with a number + regret, peaks on a contrarian lesson",
|
|
159
|
+
"clip_url": "https://.../short_1.mp4"
|
|
160
|
+
}
|
|
161
|
+
]
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
When `--coords-only` is set, each entry has `start_time`/`end_time` but no `clip_url` — render locally with ffmpeg.
|
|
166
|
+
|
|
167
|
+
When reporting back to the user, surface for each clip: rank, score, time range, title, hook, and clip URL.
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## Common Mistakes to Avoid
|
|
172
|
+
|
|
173
|
+
1. **Wrong aspect ratio for the platform** — Shorts / TikTok / Reels are `9:16`. Default to that.
|
|
174
|
+
2. **Padding to hit `num_clips`** — if the API returns fewer survivors than requested, return what you have. Don't pretend.
|
|
175
|
+
3. **Re-running on a 404'd clip URL** — the same `request_id` can be re-fetched with `muapi predict wait <id>` rather than re-clipping.
|
|
176
|
+
4. **Trying to tune Whisper / chunk size / LLM prompts** — those knobs aren't exposed; the endpoint handles them.
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## Failure Modes
|
|
181
|
+
|
|
182
|
+
- **API key missing or rejected** — surface the exact error; never fabricate a key.
|
|
183
|
+
- **Job timed out** — bump poll timeout (`--poll-timeout`) and retry.
|
|
184
|
+
- **Source URL not reachable from the backend** — upload locally with `muapi upload file <path>` first, then pass the returned URL.
|
|
185
|
+
- **Fewer clips returned than requested** — the source had fewer rankable highlights. Return what came back with a note.
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## Done Criteria
|
|
190
|
+
|
|
191
|
+
The skill is done when:
|
|
192
|
+
1. `result.shorts` has up to `num_clips` entries, each with a working `clip_url` (or `start_time`/`end_time` under `--coords-only`).
|
|
193
|
+
2. The user has been shown the ranked list (score, time range, title, hook, URL).
|
|
194
|
+
3. If `--output-json` was set, the file exists and parses.
|