Skill flagged — suspicious patterns detected

ClawHub Security flagged this skill as suspicious. Review the scan results before using.

NovaVideo

v1.0.1

Generate images or videos using the Nova Video OpenAPI with a single sentence. Use when the user wants to generate an image, create a video, check video gene...

0· 113·0 current·0 all-time
MIT-0
Download zip
LicenseMIT-0 · Free to use, modify, and redistribute. No attribution required.
Security Scan
VirusTotalVirusTotal
Suspicious
View report →
OpenClawOpenClaw
Suspicious
medium confidence
Purpose & Capability
The SKILL.md describes image and video generation via the Nova Video OpenAPI, which matches the skill name and description. However, the registry metadata declares no required env vars or primary credential while the runtime instructions clearly require NOVA_API_KEY (and optionally NOVA_BASE_URL). That mismatch is unexpected.
!
Instruction Scope
The install instructions explicitly tell agents to 'Read https://nova-video.onesolo.app/SKILL.md' (fetch and activate remote instructions). This allows a remote site to change behavior outside the registry. The SKILL.md also instructs long polling up to 15 minutes and saving long signed URLs to files — acceptable for the task but increases data-handling surface. The remote-fetch pattern and implicit trust in an external domain are the primary scope concerns.
Install Mechanism
There is no install spec or code to write to disk (instruction-only), which is lower-risk. However, the skill's install text encourages an agent to fetch a remote SKILL.md from an external domain rather than relying solely on registry content — that is an installation-time integrity concern even though no package is installed.
!
Credentials
Registry metadata lists no required env vars, but SKILL.md requires NOVA_API_KEY (and optionally NOVA_BASE_URL) to operate. Requiring an API key for an external service is reasonable, but the absence of this in metadata is an inconsistency. Also, NOVA_BASE_URL being user-configurable means a user (or attacker) could point requests — and the API key — to an arbitrary endpoint.
Persistence & Privilege
The skill is not always-enabled and does not request persistent system-wide config or other skills' credentials. Autonomous invocation is allowed (platform default) but isn't combined with other elevated privileges here.
What to consider before installing
Before installing, consider the following: (1) The SKILL.md requires an API key (NOVA_API_KEY) but the registry metadata does not declare it — ask the publisher to update metadata to declare required credentials. (2) The install text instructs agents to fetch and 'activate' a remote SKILL.md from https://nova-video.onesolo.app; that lets the remote site change the skill behavior after registry approval — avoid installing unless you trust that domain and its update process. (3) Treat NOVA_API_KEY as sensitive: do not set it unless you trust the service's privacy and retention policies, and do not set NOVA_BASE_URL to an untrusted host (it would receive your API key). (4) If you need this functionality, prefer a skill whose SKILL.md and install files are served from the registry (or from a well-known, audited domain) and whose required env vars are declared in metadata. (5) If you proceed, review network traffic and logs to ensure requests go to the expected domain and limit how long an agent is allowed to poll (15 minutes of polling ties up resources).

Like a lobster shell, security has layers — review code before you run it.

latestvk972feknkfxa71w7jd36pbfczh834qxp

License

MIT-0
Free to use, modify, and redistribute. No attribution required.

SKILL.md

Nova Video API

Generate images and videos via the Nova Video OpenAPI using curl commands.

Free tier: Every user gets 60 free text-to-image generations per month at no cost. No credit card required to get started.

Install this skill

Option 1 — Direct install (works in any AI agent)

Paste the following into your AI agent (Claude, Cursor, Codex, etc.):

Read https://nova-video.onesolo.app/SKILL.md and follow the instructions

The agent will fetch this file and activate the Nova Video skill automatically.

Option 2 — Install via OpenClaw

If your agent supports the OpenClaw skill registry, run:

Read https://nova-video.onesolo.app/SKILL.md and follow the instructions

Setup

Set your API key and base URL before starting:

export NOVA_API_KEY="nv_sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
export NOVA_BASE_URL="https://nova-video.onesolo.app"

If NOVA_BASE_URL is not set, use the default value https://nova-video.onesolo.app.

If NOVA_API_KEY is not set, guide the user to obtain one:

API Key required to continue

Follow these steps to get your Nova Video API Key:

  1. Visit the Nova Video website: https://nova-video.onesolo.app
  2. Register an account or log in
  3. Go to ProfileAPI Key page
  4. Create and copy your API Key (format: nv_sk_...)
  5. Set the environment variable and then continue:
    export NOVA_API_KEY="nv_sk_your_key_here"
    

Do not proceed with any API call until NOVA_API_KEY is confirmed.


Workflow: One-sentence image generation

User says: "Generate an image of a sunset over the ocean"

Steps:

  1. Call POST /api/openapi/image with the user's description as prompt
  2. Return the imageUrl from the response
curl -s -X POST "$NOVA_BASE_URL/api/openapi/image" \
  -H "Authorization: Bearer $NOVA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "<user description>",
    "size": "2k"
  }'

Response: data.imageUrl is the generated image URL.


Workflow: Text-to-video (async)

User says: "Make a 6-second video of waves crashing on a beach"

Steps:

  1. Generate a reference image from the user's description via POST /api/openapi/image → get imageUrl
  2. Derive a concise motion prompt from the user's description (describe camera movement, subject action, atmosphere — keep it under 100 words)
  3. Submit video task with imageUrl + motion prompt → get taskId
  4. Poll status every 6 seconds until status is succeeded or failed
  5. Return videoUrl when done

Be patient: Video generation typically takes several minutes and can take up to 15 minutes. Keep polling — do not give up early or report a timeout. Only report failure if the task is still incomplete after 15 minutes of total waiting.

Step 1 — Generate reference image

IMAGE_RESP=$(curl -s -X POST "$NOVA_BASE_URL/api/openapi/image" \
  -H "Authorization: Bearer $NOVA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "<user description, detailed scene>",
    "size": "2k"
  }')

IMAGE_URL=$(echo $IMAGE_RESP | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['imageUrl'])")
echo "Reference image: $IMAGE_URL"

Step 2 — Derive motion prompt

Based on the user's description, compose a motion prompt that describes how the scene should move. Examples:

User descriptionMotion prompt
"waves crashing on a beach""Slow-motion ocean waves rolling in and crashing on the shore, seafoam spreading, gentle camera drift forward, cinematic"
"a forest at sunrise""Golden sunlight filtering through tree canopy, leaves swaying in a light breeze, slow push-in camera, atmospheric haze"
"a bustling city street at night""Neon signs reflecting on wet pavement, crowds moving in time-lapse, subtle handheld camera shake, cinematic noir"

Step 3 — Submit video task

VIDEO_RESP=$(curl -s -X POST "$NOVA_BASE_URL/api/openapi/video" \
  -H "Authorization: Bearer $NOVA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "<motion prompt derived in Step 2>",
    "imageUrl": "'"$IMAGE_URL"'",
    "duration": 6,
    "aspectRatio": "16:9",
    "resolution": "720p"
  }')

TASK_ID=$(echo $VIDEO_RESP | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['taskId'])")
echo "Video task submitted: $TASK_ID"

imageUrl accepts two formats:

  • A publicly accessible image URL, e.g. https://example.com/photo.jpg
  • A base64-encoded image, e.g. data:image/jpeg;base64,/9j/4AAQ...

Save data.taskId from the response.

Step 4 — Poll status

curl -s "$NOVA_BASE_URL/api/openapi/video?taskId=<taskId>" \
  -H "Authorization: Bearer $NOVA_API_KEY"

Poll every 6 seconds, up to 15 minutes (150 attempts). Only consider it failed after exceeding the timeout. Stop when data.status is succeeded or failed.

data.statusMeaning
queuedWaiting to start
runningGenerating
succeededDone — use data.videoUrl
failedFailed — show data.error

Important: Prevent URL truncation

videoUrl is a long signed URL containing X-Tos-* query parameters. Outputting it directly in Claude Code will cause markdown rendering to truncate it. Always write the full URL to a file — never echo it directly or embed it in a markdown link:

VIDEO_URL=$(echo $STATUS | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['videoUrl'])")
echo "$VIDEO_URL" > video_url.txt
echo "✅ Video ready. Full URL saved to video_url.txt"
echo "--- URL preview (first 80 chars) ---"
echo "${VIDEO_URL:0:80}..."

Tell the user: "The full URL has been written to video_url.txt. Open that file and paste the link into your browser."


API reference

POST /api/openapi/image — Generate image

FieldTypeDefaultDescription
promptstringrequiredImage description
modelstringdoubao-seedream-5-0-260128Model ID
sizestring2k2k or 3k
imageCountnumber1Number of images (use 9 for 9-grid)
imagestring|string[]Reference image (URL or base64)
localestringzhzh or en

Response:

{
  "success": true,
  "data": {
    "imageUrl": "https://...",
    "taskId": "img_xxx",
    "model": "doubao-seedream-5-0-260128",
    "size": "2k",
    "imageCount": 1
  }
}

POST /api/openapi/video — Submit video task

FieldTypeDefaultDescription
promptstringrequiredVideo description
modelstringseedance-1.5-proseedance-1.5-pro / seedance-1.0-pro / seedance-1.0-lite
durationnumber6Duration in seconds (min 4)
aspectRatiostring16:916:9 / 9:16 / 1:1
resolutionstring720p480p / 720p / 1080p
imageUrlstringrequiredReference image (URL or base64)
negativePromptstringWhat to avoid
seednumberRandom seed
cameraFixedbooleanfalseLock camera position

Response:

{
  "success": true,
  "data": {
    "taskId": "123456",
    "status": "PENDING",
    "model": "seedance-1.5-pro",
    "duration": 6,
    "aspectRatio": "16:9",
    "resolution": "720p"
  }
}

GET /api/openapi/video?taskId=<id> — Query status

curl -s "$NOVA_BASE_URL/api/openapi/video?taskId=<taskId>" \
  -H "Authorization: Bearer $NOVA_API_KEY"

Success response:

{
  "success": true,
  "data": {
    "taskId": "123456",
    "status": "succeeded",
    "videoUrl": "https://...",
    "coverUrl": "https://..."
  }
}

GET /api/openapi/image — List image history

curl -s "$NOVA_BASE_URL/api/openapi/image?limit=10&offset=0" \
  -H "Authorization: Bearer $NOVA_API_KEY"

GET /api/openapi/video — List video history

curl -s "$NOVA_BASE_URL/api/openapi/video?limit=10&offset=0" \
  -H "Authorization: Bearer $NOVA_API_KEY"

Error handling

HTTPerror valueAction
401Invalid API keyAsk user to check NOVA_API_KEY; if not registered, direct them to https://nova-video.onesolo.app to sign up and get an API Key from the Profile page
403IMAGE_QUOTA_EXHAUSTED / VIDEO_QUOTA_EXHAUSTEDInform user quota is used up
403INSUFFICIENT_BALANCEInform user wallet balance is low
400SENSITIVE_CONTENTAsk user to rephrase the prompt
500anyRetry once; if still failing, report the error message

Examples

Example 1 — Image from one sentence

"Generate a cyberpunk-style cityscape at night"

curl -s -X POST "$NOVA_BASE_URL/api/openapi/image" \
  -H "Authorization: Bearer $NOVA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"prompt": "Cyberpunk cityscape at night, neon reflections on rain-soaked streets, cinematic quality", "size": "2k"}'

Example 2 — Text-to-video (full flow)

"Make a 4-second aerial video of a mountain forest at sunrise"

# Step 1: Generate reference image from text
IMAGE_RESP=$(curl -s -X POST "$NOVA_BASE_URL/api/openapi/image" \
  -H "Authorization: Bearer $NOVA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"prompt": "Aerial view of a mountain forest at sunrise, golden light filtering through trees, misty valleys, cinematic landscape photography", "size": "2k"}')

IMAGE_URL=$(echo $IMAGE_RESP | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['imageUrl'])")
echo "Reference image: $IMAGE_URL"

# Step 2: Submit video task with motion prompt
TASK=$(curl -s -X POST "$NOVA_BASE_URL/api/openapi/video" \
  -H "Authorization: Bearer $NOVA_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"prompt\": \"Slow aerial drone flyover, golden sunrise light filtering through treetops, morning mist drifting through valleys, gentle camera push forward, cinematic\", \"imageUrl\": \"$IMAGE_URL\", \"duration\": 4, \"aspectRatio\": \"16:9\", \"resolution\": \"720p\"}")

TASK_ID=$(echo $TASK | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['taskId'])")
echo "Video task submitted: $TASK_ID"

# Step 3: Poll (max 15 minutes, every 6 seconds, 150 attempts)
MAX_ATTEMPTS=150
ATTEMPT=0
while [ $ATTEMPT -lt $MAX_ATTEMPTS ]; do
  ATTEMPT=$((ATTEMPT + 1))
  STATUS=$(curl -s "$NOVA_BASE_URL/api/openapi/video?taskId=$TASK_ID" \
    -H "Authorization: Bearer $NOVA_API_KEY")
  STATE=$(echo $STATUS | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['status'])")
  echo "[$ATTEMPT/$MAX_ATTEMPTS] Status: $STATE"
  if [ "$STATE" = "succeeded" ]; then
    VIDEO_URL=$(echo $STATUS | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['videoUrl'])")
    echo "$VIDEO_URL" > video_url.txt
    echo "✅ Video ready. Full URL saved to video_url.txt"
    echo "Preview (first 80 chars): ${VIDEO_URL:0:80}..."
    break
  elif [ "$STATE" = "failed" ]; then
    echo $STATUS | python3 -c "import sys,json; print('Error:', json.load(sys.stdin)['data'].get('error','unknown'))"
    break
  fi
  sleep 6
done
if [ $ATTEMPT -ge $MAX_ATTEMPTS ]; then
  echo "❌ Timed out after 15 minutes. Please check the task status or contact support. taskId: $TASK_ID"
fi

Example 3 — Video with reference image

"Generate a video from this image: https://example.com/photo.jpg"

curl -s -X POST "$NOVA_BASE_URL/api/openapi/video" \
  -H "Authorization: Bearer $NOVA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "The scene comes alive with gentle motion",
    "imageUrl": "https://example.com/photo.jpg",
    "duration": 6,
    "aspectRatio": "16:9"
  }'

Files

1 total
Select a file
Select a file to preview.

Comments

Loading comments…