@plusonelabs/cue 0.0.93 → 0.0.95
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/cue.js +10 -10
- package/bin/windows-bootstrap.ps1 +9 -9
- package/bin/windows-runtime-artifact.json +2 -2
- package/dist/cli.mjs +1088 -821
- package/dist/skills/README.md +199 -0
- package/dist/skills/_lib/credentials.py +72 -0
- package/dist/skills/activity/SKILL.md +97 -0
- package/dist/skills/assistant/SKILL.md +173 -0
- package/dist/skills/audio/SKILL.md +132 -0
- package/dist/skills/elevenlabs-tts/SKILL.md +76 -0
- package/dist/skills/elevenlabs-tts/scripts/speak.ts +226 -0
- package/dist/skills/event/SKILL.md +98 -0
- package/dist/skills/gemini-search/SKILL.md +52 -0
- package/dist/skills/gemini-search/generate.py +195 -0
- package/dist/skills/image/SKILL.md +169 -0
- package/dist/skills/like/SKILL.md +66 -0
- package/dist/skills/listen/SKILL.md +57 -0
- package/dist/skills/listen/scripts/listen.sh +74 -0
- package/dist/skills/listen/scripts/record.swift +94 -0
- package/dist/skills/markdown-to-pdf/SKILL.md +31 -0
- package/dist/skills/message/SKILL.md +136 -0
- package/dist/skills/mini-apps/SKILL.md +256 -0
- package/dist/skills/music/SKILL.md +139 -0
- package/dist/skills/nano-banana/SKILL.md +70 -0
- package/dist/skills/nano-banana/generate.py +191 -0
- package/dist/skills/news/SKILL.md +41 -0
- package/dist/skills/notify/SKILL.md +123 -0
- package/dist/skills/places/SKILL.md +215 -0
- package/dist/skills/posts/SKILL.md +440 -0
- package/dist/skills/project/SKILL.md +116 -0
- package/dist/skills/pulse/SKILL.md +106 -0
- package/dist/skills/reddit/SKILL.md +41 -0
- package/dist/skills/seeddance/SKILL.md +81 -0
- package/dist/skills/seeddance/generate.py +303 -0
- package/dist/skills/seedream/SKILL.md +86 -0
- package/dist/skills/seedream/generate.py +301 -0
- package/dist/skills/social-graph/SKILL.md +119 -0
- package/dist/skills/transcribe/SKILL.md +150 -0
- package/dist/skills/transcribe/generate.py +389 -0
- package/dist/skills/user/SKILL.md +180 -0
- package/dist/skills/veo3/SKILL.md +76 -0
- package/dist/skills/veo3/generate.py +339 -0
- package/dist/skills/video/SKILL.md +163 -0
- package/dist/skills/weather/SKILL.md +101 -0
- package/dist/skills/web-fetch/SKILL.md +43 -0
- package/dist/skills/web-search/SKILL.md +52 -0
- package/dist/skills/z-asr/SKILL.md +58 -0
- package/dist/skills/z-asr/generate.py +177 -0
- package/dist/skills/z-search/SKILL.md +57 -0
- package/dist/skills/z-search/generate.py +189 -0
- package/dist/skills/z-tts/SKILL.md +51 -0
- package/dist/skills/z-tts/generate.py +172 -0
- package/package.json +1 -1
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Veo3 - Video generation using Google's Veo 3.1 API.
|
|
4
|
+
|
|
5
|
+
Usage:
|
|
6
|
+
python generate.py "A cat walking on a beach"
|
|
7
|
+
python generate.py "prompt" --output video.mp4
|
|
8
|
+
python generate.py "prompt" --image first_frame.jpg
|
|
9
|
+
python generate.py "prompt" --image start.jpg --last-frame end.jpg
|
|
10
|
+
python generate.py "prompt" --fast # Use fast model
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import argparse
|
|
14
|
+
import base64
|
|
15
|
+
import os
|
|
16
|
+
import sys
|
|
17
|
+
import time
|
|
18
|
+
from datetime import datetime
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
|
|
21
|
+
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '_lib'))
|
|
22
|
+
from credentials import get_credential
|
|
23
|
+
|
|
24
|
+
try:
|
|
25
|
+
import httpx
|
|
26
|
+
except ImportError:
|
|
27
|
+
print("Error: httpx not installed. Run: pip install httpx")
|
|
28
|
+
sys.exit(1)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
API_URL = "https://generativelanguage.googleapis.com/v1beta"
|
|
32
|
+
DEFAULT_MODEL = "veo-3.1-generate-preview"
|
|
33
|
+
FAST_MODEL = "veo-3.1-fast-generate-001"
|
|
34
|
+
TIMEOUT = 30.0
|
|
35
|
+
POLL_INTERVAL = 10
|
|
36
|
+
MAX_POLL_TIME = 600 # 10 minutes max
|
|
37
|
+
SKILL_DIR = Path(__file__).parent
|
|
38
|
+
ARCHIVE_DIR = SKILL_DIR / "_archive"
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def load_image(image_path: Path) -> tuple[str, str]:
|
|
42
|
+
"""Load image and return base64 data and mime type."""
|
|
43
|
+
if not image_path.exists():
|
|
44
|
+
print(f"Error: Image file not found: {image_path}")
|
|
45
|
+
sys.exit(1)
|
|
46
|
+
|
|
47
|
+
image_data = image_path.read_bytes()
|
|
48
|
+
base64_data = base64.b64encode(image_data).decode("utf-8")
|
|
49
|
+
|
|
50
|
+
suffix = image_path.suffix.lower()
|
|
51
|
+
mime_map = {
|
|
52
|
+
".jpg": "image/jpeg",
|
|
53
|
+
".jpeg": "image/jpeg",
|
|
54
|
+
".png": "image/png",
|
|
55
|
+
".webp": "image/webp",
|
|
56
|
+
".gif": "image/gif",
|
|
57
|
+
}
|
|
58
|
+
mime_type = mime_map.get(suffix, "image/jpeg")
|
|
59
|
+
|
|
60
|
+
return base64_data, mime_type
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def start_video_generation(
|
|
64
|
+
prompt: str,
|
|
65
|
+
model: str = DEFAULT_MODEL,
|
|
66
|
+
aspect_ratio: str = "16:9",
|
|
67
|
+
image_path: Path | None = None,
|
|
68
|
+
last_frame_path: Path | None = None,
|
|
69
|
+
reference_images: list[Path] | None = None,
|
|
70
|
+
) -> str:
|
|
71
|
+
"""
|
|
72
|
+
Start video generation and return operation name for polling.
|
|
73
|
+
"""
|
|
74
|
+
api_key = get_credential("GEMINI_API_KEY", "veo3")
|
|
75
|
+
url = f"{API_URL}/models/{model}:predictLongRunning"
|
|
76
|
+
|
|
77
|
+
# Build the instance
|
|
78
|
+
instance: dict = {"prompt": prompt}
|
|
79
|
+
|
|
80
|
+
# Add first frame image if provided
|
|
81
|
+
if image_path:
|
|
82
|
+
base64_data, mime_type = load_image(image_path)
|
|
83
|
+
instance["image"] = {
|
|
84
|
+
"bytesBase64Encoded": base64_data,
|
|
85
|
+
"mimeType": mime_type,
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
# Add last frame for interpolation
|
|
89
|
+
if last_frame_path:
|
|
90
|
+
base64_data, mime_type = load_image(last_frame_path)
|
|
91
|
+
instance["lastFrame"] = {
|
|
92
|
+
"bytesBase64Encoded": base64_data,
|
|
93
|
+
"mimeType": mime_type,
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
# Add reference images (style/asset references)
|
|
97
|
+
if reference_images:
|
|
98
|
+
refs = []
|
|
99
|
+
for ref_path in reference_images:
|
|
100
|
+
base64_data, mime_type = load_image(ref_path)
|
|
101
|
+
refs.append({
|
|
102
|
+
"referenceImage": {
|
|
103
|
+
"bytesBase64Encoded": base64_data,
|
|
104
|
+
"mimeType": mime_type,
|
|
105
|
+
},
|
|
106
|
+
"referenceType": "REFERENCE_TYPE_ASSET",
|
|
107
|
+
})
|
|
108
|
+
instance["referenceImages"] = refs
|
|
109
|
+
|
|
110
|
+
request_body = {
|
|
111
|
+
"instances": [instance],
|
|
112
|
+
"parameters": {
|
|
113
|
+
"aspectRatio": aspect_ratio,
|
|
114
|
+
},
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
print(f"Starting video generation with {model}...")
|
|
118
|
+
print(f"Prompt: {prompt[:100]}{'...' if len(prompt) > 100 else ''}")
|
|
119
|
+
|
|
120
|
+
with httpx.Client(timeout=TIMEOUT) as client:
|
|
121
|
+
response = client.post(
|
|
122
|
+
url,
|
|
123
|
+
json=request_body,
|
|
124
|
+
headers={
|
|
125
|
+
"Content-Type": "application/json",
|
|
126
|
+
"x-goog-api-key": api_key,
|
|
127
|
+
},
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
if response.status_code != 200:
|
|
131
|
+
print(f"Error: API returned {response.status_code}")
|
|
132
|
+
print(response.text[:500])
|
|
133
|
+
sys.exit(1)
|
|
134
|
+
|
|
135
|
+
data = response.json()
|
|
136
|
+
|
|
137
|
+
operation_name = data.get("name")
|
|
138
|
+
if not operation_name:
|
|
139
|
+
print("Error: No operation name in response")
|
|
140
|
+
print(data)
|
|
141
|
+
sys.exit(1)
|
|
142
|
+
|
|
143
|
+
return operation_name
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def poll_operation(operation_name: str) -> tuple[bool, str | None, str | None]:
|
|
147
|
+
"""
|
|
148
|
+
Poll operation status.
|
|
149
|
+
|
|
150
|
+
Returns:
|
|
151
|
+
Tuple of (done, video_uri, error)
|
|
152
|
+
"""
|
|
153
|
+
api_key = get_credential("GEMINI_API_KEY", "veo3")
|
|
154
|
+
url = f"{API_URL}/{operation_name}"
|
|
155
|
+
|
|
156
|
+
with httpx.Client(timeout=TIMEOUT) as client:
|
|
157
|
+
response = client.get(
|
|
158
|
+
url,
|
|
159
|
+
headers={"x-goog-api-key": api_key},
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
if response.status_code != 200:
|
|
163
|
+
return False, None, f"Poll error: {response.status_code}"
|
|
164
|
+
|
|
165
|
+
data = response.json()
|
|
166
|
+
|
|
167
|
+
done = data.get("done", False)
|
|
168
|
+
|
|
169
|
+
if done:
|
|
170
|
+
# Check for errors
|
|
171
|
+
error = data.get("error")
|
|
172
|
+
if error:
|
|
173
|
+
return True, None, error.get("message", "Unknown error")
|
|
174
|
+
|
|
175
|
+
# Get video URI
|
|
176
|
+
response_data = data.get("response", {})
|
|
177
|
+
generated_samples = response_data.get("generateVideoResponse", {}).get(
|
|
178
|
+
"generatedSamples", []
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
if generated_samples:
|
|
182
|
+
video_uri = generated_samples[0].get("video", {}).get("uri")
|
|
183
|
+
return True, video_uri, None
|
|
184
|
+
|
|
185
|
+
return True, None, "No video in response"
|
|
186
|
+
|
|
187
|
+
return False, None, None
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
def download_video(video_uri: str) -> bytes:
|
|
191
|
+
"""Download video from URI."""
|
|
192
|
+
api_key = get_credential("GEMINI_API_KEY", "veo3")
|
|
193
|
+
|
|
194
|
+
print(f"Downloading video...")
|
|
195
|
+
|
|
196
|
+
with httpx.Client(timeout=120.0, follow_redirects=True) as client:
|
|
197
|
+
response = client.get(
|
|
198
|
+
video_uri,
|
|
199
|
+
headers={"x-goog-api-key": api_key},
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
if response.status_code != 200:
|
|
203
|
+
print(f"Error: Download failed with {response.status_code}")
|
|
204
|
+
sys.exit(1)
|
|
205
|
+
|
|
206
|
+
return response.content
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def generate_video(
|
|
210
|
+
prompt: str,
|
|
211
|
+
model: str = DEFAULT_MODEL,
|
|
212
|
+
aspect_ratio: str = "16:9",
|
|
213
|
+
image_path: Path | None = None,
|
|
214
|
+
last_frame_path: Path | None = None,
|
|
215
|
+
reference_images: list[Path] | None = None,
|
|
216
|
+
) -> bytes:
|
|
217
|
+
"""
|
|
218
|
+
Generate video and return video bytes.
|
|
219
|
+
"""
|
|
220
|
+
operation_name = start_video_generation(
|
|
221
|
+
prompt=prompt,
|
|
222
|
+
model=model,
|
|
223
|
+
aspect_ratio=aspect_ratio,
|
|
224
|
+
image_path=image_path,
|
|
225
|
+
last_frame_path=last_frame_path,
|
|
226
|
+
reference_images=reference_images,
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
print(f"Operation: {operation_name}")
|
|
230
|
+
print("Polling for completion (this may take a few minutes)...")
|
|
231
|
+
|
|
232
|
+
start_time = time.time()
|
|
233
|
+
while time.time() - start_time < MAX_POLL_TIME:
|
|
234
|
+
done, video_uri, error = poll_operation(operation_name)
|
|
235
|
+
|
|
236
|
+
if done:
|
|
237
|
+
if error:
|
|
238
|
+
print(f"Error: {error}")
|
|
239
|
+
sys.exit(1)
|
|
240
|
+
|
|
241
|
+
if video_uri:
|
|
242
|
+
return download_video(video_uri)
|
|
243
|
+
|
|
244
|
+
print("Error: No video URI in completed operation")
|
|
245
|
+
sys.exit(1)
|
|
246
|
+
|
|
247
|
+
elapsed = int(time.time() - start_time)
|
|
248
|
+
print(f" Still processing... ({elapsed}s elapsed)")
|
|
249
|
+
time.sleep(POLL_INTERVAL)
|
|
250
|
+
|
|
251
|
+
print(f"Error: Generation timed out after {MAX_POLL_TIME}s")
|
|
252
|
+
sys.exit(1)
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
def main():
|
|
256
|
+
parser = argparse.ArgumentParser(
|
|
257
|
+
description="Generate videos using Google Veo 3.1 API",
|
|
258
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
259
|
+
epilog="""
|
|
260
|
+
Examples:
|
|
261
|
+
%(prog)s "A sunset over the ocean"
|
|
262
|
+
%(prog)s "A cat walking" --output cat.mp4
|
|
263
|
+
%(prog)s "Animate this image" --image photo.jpg
|
|
264
|
+
%(prog)s "Transition between scenes" --image start.jpg --last-frame end.jpg
|
|
265
|
+
%(prog)s "prompt" --fast # Use fast model (lower quality, faster)
|
|
266
|
+
%(prog)s "prompt" --aspect-ratio 9:16 # Vertical video
|
|
267
|
+
""",
|
|
268
|
+
)
|
|
269
|
+
parser.add_argument("prompt", help="Video generation prompt")
|
|
270
|
+
parser.add_argument(
|
|
271
|
+
"--output", "-o",
|
|
272
|
+
help="Output file path (default: generated_<timestamp>.mp4)",
|
|
273
|
+
)
|
|
274
|
+
parser.add_argument(
|
|
275
|
+
"--image", "-i",
|
|
276
|
+
type=Path,
|
|
277
|
+
help="Input image as first frame (optional)",
|
|
278
|
+
)
|
|
279
|
+
parser.add_argument(
|
|
280
|
+
"--last-frame", "-l",
|
|
281
|
+
type=Path,
|
|
282
|
+
help="Last frame image for interpolation (requires --image)",
|
|
283
|
+
)
|
|
284
|
+
parser.add_argument(
|
|
285
|
+
"--reference", "-r",
|
|
286
|
+
type=Path,
|
|
287
|
+
action="append",
|
|
288
|
+
help="Reference image for style/asset (can be used multiple times)",
|
|
289
|
+
)
|
|
290
|
+
parser.add_argument(
|
|
291
|
+
"--model", "-m",
|
|
292
|
+
default=DEFAULT_MODEL,
|
|
293
|
+
help=f"Model to use (default: {DEFAULT_MODEL})",
|
|
294
|
+
)
|
|
295
|
+
parser.add_argument(
|
|
296
|
+
"--fast", "-f",
|
|
297
|
+
action="store_true",
|
|
298
|
+
help=f"Use fast model ({FAST_MODEL}) for quicker generation",
|
|
299
|
+
)
|
|
300
|
+
parser.add_argument(
|
|
301
|
+
"--aspect-ratio", "-a",
|
|
302
|
+
default="16:9",
|
|
303
|
+
choices=["16:9", "9:16", "1:1"],
|
|
304
|
+
help="Aspect ratio (default: 16:9)",
|
|
305
|
+
)
|
|
306
|
+
|
|
307
|
+
args = parser.parse_args()
|
|
308
|
+
|
|
309
|
+
# Override model if fast flag is set
|
|
310
|
+
if args.fast:
|
|
311
|
+
args.model = FAST_MODEL
|
|
312
|
+
|
|
313
|
+
# Validate last-frame requires image
|
|
314
|
+
if args.last_frame and not args.image:
|
|
315
|
+
print("Error: --last-frame requires --image to be specified")
|
|
316
|
+
sys.exit(1)
|
|
317
|
+
|
|
318
|
+
video_bytes = generate_video(
|
|
319
|
+
prompt=args.prompt,
|
|
320
|
+
model=args.model,
|
|
321
|
+
aspect_ratio=args.aspect_ratio,
|
|
322
|
+
image_path=args.image,
|
|
323
|
+
last_frame_path=args.last_frame,
|
|
324
|
+
reference_images=args.reference,
|
|
325
|
+
)
|
|
326
|
+
|
|
327
|
+
if args.output:
|
|
328
|
+
output_path = Path(args.output)
|
|
329
|
+
else:
|
|
330
|
+
ARCHIVE_DIR.mkdir(exist_ok=True)
|
|
331
|
+
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
|
332
|
+
output_path = ARCHIVE_DIR / f"generated_{timestamp}.mp4"
|
|
333
|
+
|
|
334
|
+
output_path.write_bytes(video_bytes)
|
|
335
|
+
print(f"Saved: {output_path} ({len(video_bytes):,} bytes)")
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
if __name__ == "__main__":
|
|
339
|
+
main()
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: video
|
|
3
|
+
description: Generate videos via `cue video`. Create short AI-generated videos from text descriptions using Veo 3.1.
|
|
4
|
+
category: media
|
|
5
|
+
type: context
|
|
6
|
+
metadata:
|
|
7
|
+
short-description: Generate AI videos from text
|
|
8
|
+
scope: first-party
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
Generate short videos from text descriptions using the Cue CLI.
|
|
12
|
+
|
|
13
|
+
## Requirements
|
|
14
|
+
|
|
15
|
+
- `cue` CLI installed and authenticated (`cue` then `/auth`)
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
### Generate a video
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
cue video "a cat walking through a garden"
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Videos are saved to `~/.cue/videos/` by default as MP4 files. Generation takes 1-5 minutes.
|
|
26
|
+
|
|
27
|
+
### Save to specific path
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
cue video "sunset timelapse" -o /path/to/output.mp4
|
|
31
|
+
cue video "sunset timelapse" --output /path/to/output.mp4
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Set aspect ratio
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
cue video "landscape drone shot" --aspect-ratio 16:9 # Landscape (default)
|
|
38
|
+
cue video "vertical phone video" --aspect-ratio 9:16 # Portrait/vertical
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Set duration
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
cue video "action scene" --duration 4 # 4 seconds
|
|
45
|
+
cue video "calm ocean waves" --duration 8 # 8 seconds (default)
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Duration options: 4, 6, or 8 seconds
|
|
49
|
+
|
|
50
|
+
### Set resolution
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
cue video "cinematic shot" --resolution 720p # Default
|
|
54
|
+
cue video "cinematic shot" --resolution 1080p # Higher quality
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Select model
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
cue video "quick preview" --model veo-3.1-fast-generate-preview # Faster (default)
|
|
61
|
+
cue video "final render" --model veo-3.1-generate-preview # Higher quality
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Exclude unwanted elements
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
cue video "peaceful beach" --negative-prompt "people, text, watermarks"
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Use a specific account
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
cue auth list
|
|
74
|
+
cue --profile cue:team video "team intro animation" -o /tmp/intro.mp4
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Examples
|
|
78
|
+
|
|
79
|
+
### Product showcase
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
cue video "smartphone rotating on white background, studio lighting" \
|
|
83
|
+
-o /tmp/product.mp4 --aspect-ratio 16:9 --duration 6
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Social media vertical video
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
cue video "colorful abstract shapes morphing smoothly" \
|
|
90
|
+
-o /tmp/social.mp4 --aspect-ratio 9:16
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Nature footage
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
cue video "aerial view of ocean waves crashing on rocky coastline, golden hour" \
|
|
97
|
+
-o /tmp/ocean.mp4 --duration 8 --resolution 1080p
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Animation style
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
cue video "cartoon character waving hello, vibrant colors" \
|
|
104
|
+
-o /tmp/cartoon.mp4 --negative-prompt "realistic, photographic"
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Prompt Tips
|
|
108
|
+
|
|
109
|
+
### Motion descriptions
|
|
110
|
+
|
|
111
|
+
- "walking", "running", "flying", "rotating", "panning", "zooming"
|
|
112
|
+
- "slow motion", "timelapse", "smooth transition"
|
|
113
|
+
|
|
114
|
+
### Camera movements
|
|
115
|
+
|
|
116
|
+
- "drone shot", "aerial view", "tracking shot", "close-up"
|
|
117
|
+
- "pan left to right", "zoom in slowly", "dolly forward"
|
|
118
|
+
|
|
119
|
+
### Lighting and mood
|
|
120
|
+
|
|
121
|
+
- "golden hour", "studio lighting", "neon lights", "soft diffused light"
|
|
122
|
+
- "cinematic", "dramatic", "peaceful", "energetic"
|
|
123
|
+
|
|
124
|
+
### Style modifiers
|
|
125
|
+
|
|
126
|
+
- "photorealistic", "cinematic", "animated", "stylized"
|
|
127
|
+
- "4K quality", "film grain", "vintage look"
|
|
128
|
+
|
|
129
|
+
## Output
|
|
130
|
+
|
|
131
|
+
Videos are saved as MP4 files. The command shows progress and outputs the saved path:
|
|
132
|
+
|
|
133
|
+
```
|
|
134
|
+
Generating video: "a cat walking through a garden"
|
|
135
|
+
This may take 1-5 minutes...
|
|
136
|
+
..........
|
|
137
|
+
Downloading video...
|
|
138
|
+
Video saved to: ~/.cue/videos/video-2026-02-04T10-30-45.mp4 (16:9, 8s)
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Troubleshooting
|
|
142
|
+
|
|
143
|
+
| Error | Fix |
|
|
144
|
+
| ------------------------ | ---------------------------------------------- |
|
|
145
|
+
| Not authenticated | Run `cue` then `/auth` to log in |
|
|
146
|
+
| Authentication expired | Re-authenticate with `/auth` |
|
|
147
|
+
| Generation timed out | Videos can take up to 10 minutes in some cases |
|
|
148
|
+
| Content policy violation | Modify prompt to avoid restricted content |
|
|
149
|
+
| Invalid aspect ratio | Use 16:9 (landscape) or 9:16 (portrait) |
|
|
150
|
+
| Invalid duration | Use 4, 6, or 8 seconds |
|
|
151
|
+
|
|
152
|
+
## Limitations
|
|
153
|
+
|
|
154
|
+
- Video duration: 4-8 seconds
|
|
155
|
+
- Aspect ratios: 16:9 or 9:16 only
|
|
156
|
+
- Generation time: 1-5 minutes typically
|
|
157
|
+
- No audio in generated videos
|
|
158
|
+
|
|
159
|
+
## Related
|
|
160
|
+
|
|
161
|
+
- [image skill](../image/SKILL.md) - Generate images
|
|
162
|
+
- [music skill](../music/SKILL.md) - Generate background music
|
|
163
|
+
- [audio skill](../audio/SKILL.md) - Text to speech
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: weather
|
|
3
|
+
description: Get current weather and forecasts via `cue weather`.
|
|
4
|
+
category: data
|
|
5
|
+
type: context
|
|
6
|
+
metadata:
|
|
7
|
+
short-description: Get weather conditions and forecasts
|
|
8
|
+
scope: first-party
|
|
9
|
+
supports-json-output: true
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
Get current weather and forecast data for a location.
|
|
13
|
+
|
|
14
|
+
## Requirements
|
|
15
|
+
|
|
16
|
+
- `cue` CLI installed and authenticated (`cue` then `/auth`)
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
### Current weather
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
cue weather current '{"location":"San Francisco"}'
|
|
24
|
+
cue weather current '{"lat":37.7749,"lng":-122.4194,"units":"IMPERIAL"}'
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Forecast
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
cue weather forecast '{"location":"New York","days":5}'
|
|
31
|
+
cue weather forecast '{"location":"London","hours":48,"days":3,"units":"METRIC"}'
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Query Parameters
|
|
35
|
+
|
|
36
|
+
### Common
|
|
37
|
+
|
|
38
|
+
| Field | Type | Required |
|
|
39
|
+
| ------------------- | ------ | -------- |
|
|
40
|
+
| `location` | string | No\* |
|
|
41
|
+
| `lat` / `latitude` | number | No\* |
|
|
42
|
+
| `lng` / `longitude` | number | No\* |
|
|
43
|
+
| `units` | string | No |
|
|
44
|
+
|
|
45
|
+
\*Provide either `location` OR both `lat` and `lng`.
|
|
46
|
+
|
|
47
|
+
### Forecast-specific
|
|
48
|
+
|
|
49
|
+
| Field | Type | Required | Default |
|
|
50
|
+
| ------- | ------- | -------- | ------- |
|
|
51
|
+
| `hours` | integer | No | 24 |
|
|
52
|
+
| `days` | integer | No | 7 |
|
|
53
|
+
|
|
54
|
+
## Response Format
|
|
55
|
+
|
|
56
|
+
### Current
|
|
57
|
+
|
|
58
|
+
```json
|
|
59
|
+
{
|
|
60
|
+
"location": { "lat": 37.7749, "lng": -122.4194 },
|
|
61
|
+
"location_name": "San Francisco",
|
|
62
|
+
"current": {
|
|
63
|
+
"datetime": "2026-03-04T10:00:00Z",
|
|
64
|
+
"temperature": { "degrees": 18.4, "unit": "CELSIUS" },
|
|
65
|
+
"condition": "Clear"
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Forecast
|
|
71
|
+
|
|
72
|
+
```json
|
|
73
|
+
{
|
|
74
|
+
"location": { "lat": 40.7128, "lng": -74.006 },
|
|
75
|
+
"location_name": "New York",
|
|
76
|
+
"current": { "temperature": { "degrees": 8.1, "unit": "CELSIUS" } },
|
|
77
|
+
"hourly": [
|
|
78
|
+
{
|
|
79
|
+
"datetime": "2026-03-04T09:00:00Z",
|
|
80
|
+
"temperature": { "degrees": 9.2, "unit": "CELSIUS" }
|
|
81
|
+
}
|
|
82
|
+
],
|
|
83
|
+
"daily": [
|
|
84
|
+
{
|
|
85
|
+
"date": "2026-03-04",
|
|
86
|
+
"temperature_high": { "degrees": 11.4, "unit": "CELSIUS" },
|
|
87
|
+
"temperature_low": { "degrees": 4.9, "unit": "CELSIUS" }
|
|
88
|
+
}
|
|
89
|
+
]
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Troubleshooting
|
|
94
|
+
|
|
95
|
+
| Error | Fix |
|
|
96
|
+
| ---------------------- | --------------------------------------------------------- |
|
|
97
|
+
| Not authenticated | Run `cue` and use `/auth` |
|
|
98
|
+
| Authentication expired | Run `/auth` again |
|
|
99
|
+
| Invalid payload | Use valid JSON and required location/coordinates |
|
|
100
|
+
| 400 Bad Request | Verify either `location` or both `lat`+`lng` are provided |
|
|
101
|
+
| 502 Bad Gateway | Weather provider returned an error |
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: web-fetch
|
|
3
|
+
description: Fetch web content via `cue web-fetch`.
|
|
4
|
+
category: data
|
|
5
|
+
type: context
|
|
6
|
+
metadata:
|
|
7
|
+
short-description: Fetch and summarize web content
|
|
8
|
+
scope: first-party
|
|
9
|
+
supports-json-output: true
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
Fetch web pages and extract readable content using the built-in web tool.
|
|
13
|
+
|
|
14
|
+
## Requirements
|
|
15
|
+
|
|
16
|
+
- `cue` CLI installed and authenticated (`cue` then `/auth`)
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
cue web-fetch fetch "https://example.com/article" [--max-uses 5]
|
|
22
|
+
cue web-search fetch "https://example.com/article" --citations --json
|
|
23
|
+
cue web fetch "https://example.com/article" --citations
|
|
24
|
+
cue web fetch "https://example.com/article" --json
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Options
|
|
28
|
+
|
|
29
|
+
- `fetch <url>`:
|
|
30
|
+
- `--max-uses N` — maximum page fetch attempts (1-20)
|
|
31
|
+
- `--citations` — include source citation details
|
|
32
|
+
- `--max-content-tokens N` — cap fetched content size (1000-200000)
|
|
33
|
+
- `--json` — machine-readable response
|
|
34
|
+
- `--compact` — compact human output (default)
|
|
35
|
+
|
|
36
|
+
## Output
|
|
37
|
+
|
|
38
|
+
`--json` returns structured fields for downstream automation.
|
|
39
|
+
|
|
40
|
+
## Notes
|
|
41
|
+
|
|
42
|
+
- `cue web-fetch` is an alias of `cue web`.
|
|
43
|
+
- `cue web-search` is also available for web search + fetch via `fetch`.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: web-search
|
|
3
|
+
description: Search and fetch web pages via `cue web-search`.
|
|
4
|
+
category: data
|
|
5
|
+
type: context
|
|
6
|
+
metadata:
|
|
7
|
+
short-description: Search and fetch web content
|
|
8
|
+
scope: first-party
|
|
9
|
+
supports-json-output: true
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
Search the web from the Cue CLI using built-in command mode.
|
|
13
|
+
|
|
14
|
+
## Requirements
|
|
15
|
+
|
|
16
|
+
- `cue` CLI installed and authenticated (`cue` then `/auth`)
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
cue web-search search "AI agent tooling" [--provider anthropic|z-ai|gemini|exa] [--max-results 10] [--allowed-domains "docs.python.org"]
|
|
22
|
+
cue web-search search "AI agent news" --json
|
|
23
|
+
cue web-search search "latest nvidia news" --provider exa --max-results 5
|
|
24
|
+
cue web-fetch fetch "https://example.com/report" [--max-uses 5]
|
|
25
|
+
cue web-search fetch "https://example.com/report" [--max-uses 5]
|
|
26
|
+
cue web-search fetch "https://example.com/report" --citations --json
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Options
|
|
30
|
+
|
|
31
|
+
- `search <query>`:
|
|
32
|
+
- `--provider <provider>` — search provider: `anthropic`, `z-ai`, `gemini`, `exa`
|
|
33
|
+
- `--max-results N` (`--count` alias) — number of results (1-20)
|
|
34
|
+
- `--allowed-domains "domain1.com,domain2.com"`
|
|
35
|
+
- `--blocked-domains "domain3.com"`
|
|
36
|
+
- `--json` — machine-readable response
|
|
37
|
+
- `--compact` — compact human output (default)
|
|
38
|
+
- `fetch <url>`:
|
|
39
|
+
- `--max-uses N` — max page fetch attempts (1-20)
|
|
40
|
+
- `--citations` — include source citation details
|
|
41
|
+
- `--max-content-tokens N` — cap fetched content size (1000-200000)
|
|
42
|
+
- `--json` — machine-readable response
|
|
43
|
+
- `--compact` — compact human output
|
|
44
|
+
|
|
45
|
+
## Output
|
|
46
|
+
|
|
47
|
+
JSON responses for `search` and `fetch` are available with `--json`.
|
|
48
|
+
|
|
49
|
+
## Notes
|
|
50
|
+
|
|
51
|
+
- `cue web-search` and `cue web-fetch` are aliases of `cue web`.
|
|
52
|
+
- `--json` keeps output in a stable structure and is required for downstream automation.
|