@renoise/video-maker 0.1.3 → 0.2.1
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/.claude-plugin/marketplace.json +15 -0
- package/.claude-plugin/plugin.json +21 -3
- package/README.md +25 -30
- package/hooks/check-api-key.sh +28 -0
- package/hooks/hooks.json +12 -0
- package/hooks/session-start.sh +30 -7
- package/openclaw.plugin.json +5 -3
- package/package.json +4 -9
- package/skills/director/SKILL.md +4 -7
- package/skills/file-upload/SKILL.md +79 -0
- package/skills/file-upload/scripts/upload.mjs +103 -0
- package/skills/gemini-gen/SKILL.md +236 -0
- package/skills/gemini-gen/scripts/gemini.mjs +220 -0
- package/skills/renoise-gen/SKILL.md +3 -1
- package/skills/renoise-gen/references/api-endpoints.md +37 -33
- package/skills/short-film-editor/SKILL.md +23 -24
- package/skills/short-film-editor/references/continuity-guide.md +2 -2
- package/skills/tiktok-content-maker/SKILL.md +78 -81
- package/skills/tiktok-content-maker/examples/dress-demo.md +42 -42
- package/skills/tiktok-content-maker/references/ecom-prompt-guide.md +157 -152
- package/skills/video-download/SKILL.md +1 -1
- package/lib/gemini.ts +0 -49
- package/skills/short-film-editor/scripts/generate-storyboard-html.ts +0 -714
- package/skills/tiktok-content-maker/scripts/analyze-images.ts +0 -122
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env npx tsx
|
|
2
|
-
/**
|
|
3
|
-
* Analyze product + model images using Gemini for ecommerce video scripting.
|
|
4
|
-
* Usage: npx tsx analyze-images.ts <product_image> [model_image]
|
|
5
|
-
* Model image is optional — if omitted, only product analysis is returned.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import fs from 'fs/promises'
|
|
9
|
-
import path from 'path'
|
|
10
|
-
import { getGeminiClient, fileToInlinePart } from '../../../lib/gemini.js'
|
|
11
|
-
|
|
12
|
-
const PROMPT_WITH_MODEL = `You are an expert ecommerce video director and product analyst. Analyze these two images:
|
|
13
|
-
|
|
14
|
-
Image 1: Product photo
|
|
15
|
-
Image 2: Model/person photo
|
|
16
|
-
|
|
17
|
-
Return a JSON object with exactly this structure (no markdown, no code fences, pure JSON only):
|
|
18
|
-
|
|
19
|
-
{
|
|
20
|
-
"product": {
|
|
21
|
-
"type": "product category (e.g. dress, sneaker, lipstick)",
|
|
22
|
-
"color": "main colors",
|
|
23
|
-
"material": "fabric/material description",
|
|
24
|
-
"highlights": "key visual features and design details",
|
|
25
|
-
"brand_tone": "brand positioning vibe (e.g. luxury, streetwear, minimalist)"
|
|
26
|
-
},
|
|
27
|
-
"model": {
|
|
28
|
-
"gender": "male/female",
|
|
29
|
-
"age_range": "estimated age range",
|
|
30
|
-
"hair": "hair style and color description",
|
|
31
|
-
"outfit": "what the model is wearing",
|
|
32
|
-
"vibe": "overall style/aesthetic (e.g. elegant, sporty, casual chic)"
|
|
33
|
-
},
|
|
34
|
-
"scene_suggestions": [
|
|
35
|
-
"scene 1 description with specific location and lighting",
|
|
36
|
-
"scene 2 description with specific location and lighting",
|
|
37
|
-
"scene 3 description with specific location and lighting"
|
|
38
|
-
],
|
|
39
|
-
"selling_points": [
|
|
40
|
-
"selling point 1 — specific and compelling",
|
|
41
|
-
"selling point 2 — specific and compelling",
|
|
42
|
-
"selling point 3 — specific and compelling"
|
|
43
|
-
]
|
|
44
|
-
}`
|
|
45
|
-
|
|
46
|
-
const PROMPT_PRODUCT_ONLY = `You are an expert ecommerce video director and product analyst. Analyze this product image.
|
|
47
|
-
|
|
48
|
-
Return a JSON object with exactly this structure (no markdown, no code fences, pure JSON only):
|
|
49
|
-
|
|
50
|
-
{
|
|
51
|
-
"product": {
|
|
52
|
-
"type": "product category (e.g. dress, sneaker, lipstick)",
|
|
53
|
-
"color": "main colors",
|
|
54
|
-
"material": "fabric/material description",
|
|
55
|
-
"highlights": "key visual features and design details",
|
|
56
|
-
"brand_tone": "brand positioning vibe (e.g. luxury, streetwear, minimalist)"
|
|
57
|
-
},
|
|
58
|
-
"scene_suggestions": [
|
|
59
|
-
"scene 1 description with specific location and lighting",
|
|
60
|
-
"scene 2 description with specific location and lighting",
|
|
61
|
-
"scene 3 description with specific location and lighting"
|
|
62
|
-
],
|
|
63
|
-
"selling_points": [
|
|
64
|
-
"selling point 1 — specific and compelling",
|
|
65
|
-
"selling point 2 — specific and compelling",
|
|
66
|
-
"selling point 3 — specific and compelling"
|
|
67
|
-
]
|
|
68
|
-
}`
|
|
69
|
-
|
|
70
|
-
async function main() {
|
|
71
|
-
const [productImage, modelImage] = process.argv.slice(2)
|
|
72
|
-
if (!productImage) {
|
|
73
|
-
console.error('Usage: analyze-images.ts <product_image> [model_image]')
|
|
74
|
-
process.exit(1)
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// Validate files exist
|
|
78
|
-
await fs.access(productImage).catch(() => {
|
|
79
|
-
console.error(`ERROR: Product image not found: ${productImage}`)
|
|
80
|
-
process.exit(1)
|
|
81
|
-
})
|
|
82
|
-
if (modelImage) {
|
|
83
|
-
await fs.access(modelImage).catch(() => {
|
|
84
|
-
console.error(`ERROR: Model image not found: ${modelImage}`)
|
|
85
|
-
process.exit(1)
|
|
86
|
-
})
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const genAI = getGeminiClient()
|
|
90
|
-
const model = genAI.getGenerativeModel({
|
|
91
|
-
model: process.env.GEMINI_MODEL ?? 'gemini-3.1-flash',
|
|
92
|
-
generationConfig: {
|
|
93
|
-
temperature: 0.3,
|
|
94
|
-
maxOutputTokens: 2048,
|
|
95
|
-
},
|
|
96
|
-
})
|
|
97
|
-
|
|
98
|
-
const productPart = await fileToInlinePart(productImage)
|
|
99
|
-
|
|
100
|
-
const parts: Array<{ text: string } | Awaited<ReturnType<typeof fileToInlinePart>>> = modelImage
|
|
101
|
-
? [{ text: PROMPT_WITH_MODEL }, productPart, await fileToInlinePart(modelImage)]
|
|
102
|
-
: [{ text: PROMPT_PRODUCT_ONLY }, productPart]
|
|
103
|
-
|
|
104
|
-
const result = await model.generateContent(parts)
|
|
105
|
-
|
|
106
|
-
const text = result.response.text()
|
|
107
|
-
|
|
108
|
-
// Try to parse and pretty-print as JSON
|
|
109
|
-
const cleaned = text.replace(/^```json\n?/, '').replace(/\n?```$/, '').trim()
|
|
110
|
-
try {
|
|
111
|
-
const parsed = JSON.parse(cleaned)
|
|
112
|
-
console.log(JSON.stringify(parsed, null, 2))
|
|
113
|
-
} catch {
|
|
114
|
-
// If not valid JSON, output raw text
|
|
115
|
-
console.log(text)
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
main().catch((err) => {
|
|
120
|
-
console.error('ERROR:', err.message)
|
|
121
|
-
process.exit(1)
|
|
122
|
-
})
|