Not in the top 1,000 by GitHub stars
Black-Line-Ops/scroll-scrub-hero
Turn any photo into a scroll-scrubbed website hero. kie.ai pipeline: storyboard, keyframes, Kling first/last-frame tweens, drop-in WebP frames. By Black Line Design.
History
Review weekly changes to SKILL.md before updating. Dates mark the weeks in which we observed each version; checks apply to the recorded commits.
View weekly changes
SKILL.md
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Network or broad shell
First observation → a390a0486cae
No earlier version was observed for comparison.
Verified commit a390a0486cae9bec29ab11d1ede102267db3bb9d
git clone --filter=blob:none --no-checkout https://github.com/Black-Line-Ops/scroll-scrub-hero.git .hotskills/black-line-ops-scroll-scrub-hero && git -C .hotskills/black-line-ops-scroll-scrub-hero checkout --detach a390a0486cae9bec29ab11d1ede102267db3bb9d
# Copy each selected skill directory from .hotskills/black-line-ops-scroll-scrub-hero into .claude/skills/<skill-name>/git clone --filter=blob:none --no-checkout https://github.com/Black-Line-Ops/scroll-scrub-hero.git .hotskills/black-line-ops-scroll-scrub-hero && git -C .hotskills/black-line-ops-scroll-scrub-hero checkout --detach a390a0486cae9bec29ab11d1ede102267db3bb9d
# Copy each selected skill directory from .hotskills/black-line-ops-scroll-scrub-hero into .agents/skills/<skill-name>/Heat
0.4- Star growth, last 7 daysNot available
- Star growth, last 24 hoursNot available
- Rank movement, last 7 daysNot available
- Commits, last 30 daysNot available
- Accounts asking about it through MCP, last 7 daysNot available
- Hot votes this weekNot available
Heat never changes the order by stars, and sponsorship never touches it. How heat works
Stars over time
30-day change not yet available: not enough history.
Individual skills in this repository
How it works
scroll-scrub-hero
When your agent uses it
Build a scroll-scrubbed hero from one or two REAL photos plus an idea — or from the idea alone. Scrolling drives a subject through a transformation (bare yard → finished pool, empty room → staged interior, raw stock → machined part, before → after). Uses kie.ai: GPT 5.6 Sol writes the storyboard, GPT Image 2 renders keyframe stills so the client's ACTUAL property stays recognisable (and draws the opening frame when there is no photo), Kling 3.0 first/last-frame tweens the motion, and ffmpeg cuts drop-in scrub frames plus config.js. Use whenever someone wants a scroll-driven build/progress/before-after hero, mentions scrubbing video on scroll, asks to "animate" a client photo, wants Kling or kie.ai wired into a site, or wants project photos turned into a scrolling story — even if they never say "scroll scrub". Suits a fixed camera with a subject that changes state; not a camera flying through a scene.
What it loads into context
Frontmatter
256 tokensAlways available to the agent
SKILL.md
11,605 tokensWhen the skill is activated
Reference documents
40,703 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Before round 1: get the raw material
- Round 1 — the story (4 questions, one `AskUserQuestion` call)
- Round 2 — how it looks (3 questions, one `AskUserQuestion` call)
- Round 3 — what it costs (2 questions, one `AskUserQuestion` call)
- The rules these questions follow
- The forecast table
- Show the forecast before you generate anything
- Mapping the nine answers to flags
- Why the pipeline is shaped this way
- Before starting
- The run
- Money, in one place
- Reference material
- When a run goes wrong
Scripts executed separately
package.jsonscripts/build-frames.mjsscripts/connect-key.mjsscripts/doctor.mjsscripts/ffmpeg-flags.mjsscripts/keyframes.mjsscripts/kie.mjsscripts/pricing.mjsscripts/seams.mjsscripts/storyboard.mjsscripts/tween.mjstest/args.test.mjstest/build-frames-aspect.test.mjstest/build-frames-gaps.test.mjstest/build-frames-steps.test.mjstest/camera-lock.test.mjstest/captions.test.mjstest/cheaper-ways.test.mjstest/config-globals-documented.test.mjstest/connect-key.test.mjstest/contact-sheet.test.mjstest/doctor-mask.test.mjstest/dry-run.test.mjstest/encoder-column.test.mjstest/ffmpeg-compat.test.mjstest/float.test.mjstest/frame-normalisation.test.mjstest/helpers/harness.mjstest/image-url-unwrap.test.mjstest/kie-client.test.mjstest/only-unknown-id.test.mjstest/pricing-balance.test.mjstest/pricing-calibration.test.mjstest/pricing-estimates.test.mjstest/retry-policy.test.mjstest/run.mjstest/seams.test.mjstest/spend-gate-cost.test.mjstest/stale-config.test.mjstest/storyboard-schema.test.mjstest/storyboard-seed.test.mjstest/style.test.mjstest/upload-name.test.mjs
Files
.claude-plugin/marketplace.jsonasset868 bytes.claude-plugin/plugin.jsonasset785 bytes.editorconfigasset869 bytes.github/workflows/tests.ymlasset2,346 bytes.gitignoreasset416 bytes.nvmrcasset3 bytesAGENTS.mddoc6,153 bytesCHANGELOG.mddoc29,318 bytesCONTRIBUTING.mddoc6,586 bytesLICENSEasset1,071 bytesREADME.mddoc19,141 bytesSECURITY.mddoc6,636 bytesSKILL.mdcore47,530 bytesSKILL.mdcore47,530 bytesSKILL.mdcore47,530 bytesSKILL.mdcore47,530 bytesSKILL.mdcore47,530 bytesSKILL.mdcore47,530 bytesSKILL.mdcore47,530 bytesSKILL.mdcore47,530 bytesSKILL.mdcore47,530 bytesSKILL.mdcore47,530 bytesSKILL.mdcore47,530 bytesSKILL.mdcore47,530 bytesSKILL.mdcore47,530 bytesSKILL.mdcore47,530 bytesSKILL.mdcore47,530 bytesSKILL.mdcore47,530 bytesSKILL.mdcore47,530 bytesSKILL.mdcore47,530 bytesdocs/examples-reel.gifasset7,938,526 bytesdocs/examples-reel.mp4asset7,574,479 bytesdocs/how-it-works.mddoc5,967 bytesdocs/readme-reel.mddoc2,013 bytesexamples/README.mddoc9,866 bytesexamples/pools-pavers-patios.mddoc4,621 bytespackage.jsonruns662 bytesreferences/hero-wiring.mddoc10,921 bytesreferences/kie-api.mddoc25,245 bytesreferences/prompting.mddoc9,539 bytesscripts/build-frames.mjsruns30,094 bytesscripts/connect-key.mjsruns11,213 bytesscripts/doctor.mjsruns30,170 bytesscripts/ffmpeg-flags.mjsruns3,663 bytesscripts/keyframes.mjsruns30,410 bytesscripts/kie.mjsruns25,688 bytesscripts/pricing.mjsruns63,413 bytesscripts/seams.mjsruns9,249 bytesscripts/storyboard.mjsruns33,737 bytesscripts/tween.mjsruns25,661 bytestest/README.mddoc25,034 bytestest/args.test.mjsruns10,008 bytestest/build-frames-aspect.test.mjsruns5,514 bytestest/build-frames-gaps.test.mjsruns8,379 bytestest/build-frames-steps.test.mjsruns5,938 bytestest/camera-lock.test.mjsruns3,446 bytestest/captions.test.mjsruns7,754 bytestest/cheaper-ways.test.mjsruns6,710 bytestest/config-globals-documented.test.mjsruns4,128 bytestest/connect-key.test.mjsruns5,137 bytestest/contact-sheet.test.mjsruns12,098 bytestest/doctor-mask.test.mjsruns5,041 bytestest/dry-run.test.mjsruns6,526 bytestest/encoder-column.test.mjsruns9,309 bytestest/ffmpeg-compat.test.mjsruns6,543 bytestest/float.test.mjsruns8,421 bytestest/frame-normalisation.test.mjsruns7,644 bytestest/helpers/harness.mjsruns15,969 bytestest/image-url-unwrap.test.mjsruns5,930 bytestest/kie-client.test.mjsruns10,726 bytestest/only-unknown-id.test.mjsruns7,835 bytestest/pricing-balance.test.mjsruns11,452 bytestest/pricing-calibration.test.mjsruns13,793 bytestest/pricing-estimates.test.mjsruns17,189 bytestest/retry-policy.test.mjsruns12,321 bytestest/run.mjsruns3,034 bytestest/seams.test.mjsruns5,819 bytestest/spend-gate-cost.test.mjsruns17,825 bytestest/stale-config.test.mjsruns7,719 bytestest/storyboard-schema.test.mjsruns10,282 bytestest/storyboard-seed.test.mjsruns9,210 bytestest/style.test.mjsruns4,878 bytestest/upload-name.test.mjsruns2,591 bytes
Read SKILL.md
# scroll-scrub-hero
Turns a real photograph into a hero where **scroll drives time**: the camera holds still and
the subject transforms. It is built as a chain of keyframe stills joined by short AI-generated
video tweens, then flattened into an image sequence the page scrubs on a canvas.
The output is deliberately boring to consume: numbered WebP frames plus a small `config.js`.
No runtime AI, no video element, no streaming — just images a canvas paints, which is why it
scrubs smoothly and works offline once deployed.
**It spends the user's money at kie.ai.** A typical run is around **$2.55**; the levers that
change that are in the interview below, and every one of them is priced. The two generation
stages — stills and video, about 98% of the bill — each stop and ask before spending anything.
View the complete source on GitHubSkills included
- scroll-scrub-hero
Repository facts
- License
- MIT
- Created
- Aug 5, 2026
- Last pushed
- Sep 14, 2026
- Forks
- 1
- Open issues
- 0
- Project activity
- Active
Before you install
Network or broad shellAutomated signals, not a guarantee
Checked Nov 4, 2026
Not fully analyzed: some files were too long, unreadable or missing. This never lowers the level.
Show 17 notes
SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzed
- 1 broad permissionin 1 file: SKILL.md:1
- 4 dangerous shell commandsin 3 files: scripts/doctor.mjs:111 .github/workflows/tests.yml:41 test/kie-client.test.mjs:120
- 213 network referencesin 27 files: README.md:12 scripts/pricing.mjs:71 references/kie-api.md:38 and 24 more
- No hidden or obfuscated text
- No instruction overrides
- 43 executable scriptsin 43 files: package.json:1 scripts/build-frames.mjs:1 scripts/connect-key.mjs:1 and 40 more
- 65 references to secretsin 21 files: scripts/doctor.mjs:189 test/connect-key.test.mjs:29 scripts/connect-key.mjs:1 and 18 more
- No requests to vote in Hot
Show all 326 signals by file
.claude-plugin/marketplace.json
- Network accessline 1
{ "$schema": "https://anthropic.com/claude-code/marketplace.schema.json", - Network accessline 2
"$schema": "https://anthropic.com/claude-code/marketplace.schema.json", - Network accessline 5
"owner": { "name": "Black Line Ops", "url": "https://blacklinedesign.website" - Network accessline 6
"name": "Black Line Ops", "url": "https://blacklinedesign.website" }, - Network accessline 7
"url": "https://blacklinedesign.website"
.claude-plugin/plugin.json
- Network accessline 5
"author": { "name": "Black Line Ops", "url": "https://blacklinedesign.website" - Network accessline 6
"name": "Black Line Ops", "url": "https://blacklinedesign.website" }, - Network accessline 7
"url": "https://blacklinedesign.website" - Network accessline 8
}, "homepage": "https://github.com/Black-Line-Ops/scroll-scrub-hero", "license": "MIT", - Network accessline 9
"homepage": "https://github.com/Black-Line-Ops/scroll-scrub-hero",
.github/workflows/tests.yml
- Dangerous shell operationline 41
run: sudo apt-get update -q && sudo apt-get install -y -q ffmpeg
.gitignore
- Access to secretsline 13
[Credential-related source omitted]
AGENTS.md
- Access to secretsline 57
[Credential-related source omitted]
CHANGELOG.md
- Network accessline 3
Notable changes to this skill. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); - Network accessline 293
* **The file upload posted to the wrong host.** `POST https://api.kie.ai/api/v1/file-base64-upload` - Network accessline 294
returns 404, and so does the same path without `/v1` — the route lives on a different host entirely, `https://kieai.redpandaai.co/api/file-base64-upload`. `storyboard.mjs` uploads the reference photo as its first action after the key ch - Network accessline 295
entirely, `https://kieai.redpandaai.co/api/file-base64-upload`. `storyboard.mjs` uploads the
README.md
- Network accessline 12
**[Get started](#installing-it)** · **[Case studies](examples/)** · **[How it works](docs/how-it-works.md)** · **[What it costs](#cost)** · **[New to Claude Code?](https://blacklineops.ai/claude-code-guide)** - Network accessline 14
**[New to Claude Code?](https://blacklineops.ai/claude-code-guide)** - Network accessline 36
[](LICENSE) - Network accessline 37
[](CHANGELOG.md) - Network accessline 38
[](https://nodejs.org) - Network accessline 39
[](#what-you-need) - Network accessline 40
[](test/) - Network accessline 41
[](https://github.com/Black-Line-Ops/scroll-scrub-hero/actions/workflows/tests.yml) - Network accessline 42
[](https://kie.ai?ref=da271de69b92c3461d59a15884817078) - Network accessline 44
[](#installing-it) - Network accessline 45
[](#installing-it) - Network accessline 46
[](#installing-it) - Network accessline 47
[](#setup) - Network accessline 48
[](#setup) - Network accessline 49
[](#setup) - Network accessline 55
> [!NOTE] > **You'll need a [kie.ai account](https://kie.ai?ref=da271de69b92c3461d59a15884817078)** — that's - Network accessline 56
> **You'll need a [kie.ai account](https://kie.ai?ref=da271de69b92c3461d59a15884817078)** — that's - Network accessline 181
| **Git** | the skills CLI clones this repo to install it (`git --version`) | | **ffmpeg + ffprobe** | for cutting frames — `winget install Gyan.FFmpeg`, `brew install ffmpeg-full` (Homebrew's plain `ffmpeg` is a slim build with no WebP enc - Network accessline 183
| **A kie.ai account with credits** | this is where the models run — **[sign up](https://kie.ai?ref=da271de69b92c3461d59a15884817078)** | - Network accessline 187
> **Never set any of this up before?** The > **[plain-English starter guide](https://blacklineops.ai/claude-code-guide)** walks through installing all of it from - Network accessline 188
> **[plain-English starter guide](https://blacklineops.ai/claude-code-guide)** walks through installing all of it from - Network accessline 193
Get an API key from **[kie.ai](https://kie.ai?ref=da271de69b92c3461d59a15884817078) → API keys**, - Access to secretsline 203
[Credential-related source omitted] - Access to secretsline 208
[Credential-related source omitted] - Access to secretsline 220
[Credential-related source omitted] - Access to secretsline 225
[Credential-related source omitted] - Network accessline 324
You pay [kie.ai](https://kie.ai?ref=da271de69b92c3461d59a15884817078) directly for what you - Network accessline 370
[](https://blacklinedesign.website) - Network accessline 371
[](https://blacklineops.ai) - Network accessline 373
[](https://github.com/Black-Line-Ops) - Network accessline 374
[](https://www.linkedin.com/company/blacklineops/) - Network accessline 375
[](https://youtube.com/@blacklineopsllc) - Network accessline 376
[](https://www.instagram.com/blacklineops.llc/) - Network accessline 377
[](https://www.facebook.com/profile.php?id=61591659974557) - Network accessline 383
This is the whole pipeline, free, MIT. But if you would rather not run it yourself — or you want the hero designed into a page rather than dropped into one — that is the day job. Rates and contact are on **[blacklinedesign.website](https:// - Network accessline 385
are on **[blacklinedesign.website](https://blacklinedesign.website)**. - Network accessline 389
Special thanks to **[Titus Byron (@Prxdigy-exe)](https://github.com/Prxdigy-exe)**, Security Analyst Intern at Black Line Ops. Titus contributed debugging, security hardening, operational support, and fixes for several important issues in ` - Network accessline 395
<div align="center"> <a href="https://blacklineops.ai/support"> - Network accessline 396
<a href="https://blacklineops.ai/support"> - Network accessline 397
<img src="https://img.shields.io/badge/SUPPORT_BLACK_LINE_OPS-DC2626?style=for-the-badge&logo=stripe&logoColor=white" alt="Support Black Line Ops">
SECURITY.md
SKILL.md
docs/how-it-works.md
- Network accessline 91
**File upload is on a different host from everything else.** `https://kieai.redpandaai.co`, not
docs/readme-reel.md
- Network accessline 29
Accepting click-to-play: drag `docs/examples-reel.mp4` into any GitHub comment box, copy the `https://github.com/user-attachments/assets/...` URL it returns, and paste it bare on its own line - Network accessline 30
`https://github.com/user-attachments/assets/...` URL it returns, and paste it bare on its own line
package.json
- Executable scriptline 1
Executable file - Network accessline 6
"description": "Build a scroll-scrubbed hero from one or two real photos, using kie.ai for the storyboard, keyframes and tweens and ffmpeg for the frame sequence.", "license": "MIT", "author": "Black Line Ops (https://blacklinedesign.we - Network accessline 7
"license": "MIT", "author": "Black Line Ops (https://blacklinedesign.website)", "homepage": "https://github.com/Black-Line-Ops/scroll-scrub-hero", - Network accessline 8
"author": "Black Line Ops (https://blacklinedesign.website)", - Network accessline 9
"homepage": "https://github.com/Black-Line-Ops/scroll-scrub-hero", - Network accessline 10
"repository": { "type": "git", "url": "git+https://github.com/Black-Line-Ops/scroll-scrub-hero.git" - Network accessline 11
"type": "git", "url": "git+https://github.com/Black-Line-Ops/scroll-scrub-hero.git" }, - Network accessline 12
"url": "git+https://github.com/Black-Line-Ops/scroll-scrub-hero.git"
references/kie-api.md
- Network accessline 38
There are **two hosts**, not one. Everything in this document is on `https://api.kie.ai` **except - Network accessline 39
file upload**, which is on `https://kieai.redpandaai.co` — see [File upload](#file-upload). They - Access to secretsline 46
[Credential-related source omitted] - Network accessline 63
{ "model": "<model string>", "input": { ... }, "callBackUrl": "https://optional" } - Network accessline 80
{ "code": 200, "data": { "taskId": "...", "state": "success", "progress": 100, "resultJson": "{\"resultUrls\":[\"https://...\"]}", - Network accessline 81
"taskId": "...", "state": "success", "progress": 100, "resultJson": "{\"resultUrls\":[\"https://...\"]}", "failCode": "", "failMsg": "", "costTime": 15000, "creditsConsumed": 50 } } - Network accessline 82
"resultJson": "{\"resultUrls\":[\"https://...\"]}", - Network accessline 98
`POST https://kieai.redpandaai.co/api/file-base64-upload` - Network accessline 104
POST https://api.kie.ai/api/v1/file-base64-upload -> HTTP 404 Not Found - Network accessline 105
POST https://api.kie.ai/api/file-base64-upload -> HTTP 404 Not Found (dropping /v1 is NOT the fix) - Network accessline 106
POST https://kieai.redpandaai.co/api/file-base64-upload -> HTTP 200, body code 401 (route exists, auth required) - Network accessline 151
{ "type": "input_text", "text": "..." }, { "type": "input_image", "image_url": "https://..." } ] } ], - Network accessline 152
{ "type": "input_image", "image_url": "https://..." } ] } ], - Network accessline 182
{ "prompt": "up to 20000 chars", "input_urls": ["https://...", "https://..."], - Network accessline 183
"input_urls": ["https://...", "https://..."], - Network accessline 234
**1 credit = $0.005 USD.** Read from https://kie.ai/pricing, which states it twice in its own - Network accessline 251
| Key | Rate | Per | Confidence | Read from | |---|---|---|---|---| | `creditUsd` | $0.005 | credit | **high** | https://kie.ai/pricing — "Each credit is valued at $0.005 USD" | - Network accessline 252
|---|---|---|---|---| | `creditUsd` | $0.005 | credit | **high** | https://kie.ai/pricing — "Each credit is valued at $0.005 USD" | | `image.1K` | 6 cr ($0.03) | image | **high** | https://kie.ai/gpt-image-2 — "6 credits ($0.03) for 1 K" | - Network accessline 253
| `creditUsd` | $0.005 | credit | **high** | https://kie.ai/pricing — "Each credit is valued at $0.005 USD" | - Network accessline 254
| `image.1K` | 6 cr ($0.03) | image | **high** | https://kie.ai/gpt-image-2 — "6 credits ($0.03) for 1 K" | - Network accessline 255
| `image.2K` | 10 cr ($0.05) | image | **high** | https://kie.ai/gpt-image-2 — "10 credits ($0.05) for 2 K" | - Network accessline 256
| `image.4K` | 16 cr ($0.08) | image | **high** | https://kie.ai/gpt-image-2 — "16 credits ($0.08) for 4 K" | - Network accessline 257
| `video.std` | 14 cr ($0.07) | second | **high** | https://kie.ai/kling-3-0 — "Standard: no-audio 14 credits ($0.07) /s" | - Network accessline 258
| `video.pro` | 18 cr ($0.09) | second | **high** | https://kie.ai/kling-3-0 — "Pro: no-audio 18 credits ($0.09) / s" | - Network accessline 259
| `video.4K` | 67 cr ($0.335) | second | **high** | https://kie.ai/kling-3-0 — "4K: no/with audio 67 credits ($0.335) /s" | - Network accessline 260
| `sol.call` | 0.84–6.72 cr ($0.004–$0.034) | call | **medium — derived** | https://kie.ai/gpt-5-6 rates + one measured run |
scripts/build-frames.mjs
- Executable scriptline 1
Executable file
scripts/connect-key.mjs
- Executable scriptline 1
[Credential-related source omitted] - Access to secretsline 1
[Credential-related source omitted] - Network accessline 25
[Credential-related source omitted] - Access to secretsline 25
[Credential-related source omitted] - Network accessline 26
const SIGNUP = 'https://kie.ai?ref=da271de69b92c3461d59a15884817078' - Access to secretsline 72
[Credential-related source omitted] - Access to secretsline 77
[Credential-related source omitted] - Access to secretsline 79
[Credential-related source omitted] - Access to secretsline 82
[Credential-related source omitted] - Network accessline 90
export async function check (key) { try { const res = await fetch('https://api.kie.ai/api/v1/jobs/recordInfo?taskId=connect-key-probe', { - Network accessline 91
[Credential-related source omitted] - Network accessline 92
const res = await fetch('https://api.kie.ai/api/v1/jobs/recordInfo?taskId=connect-key-probe', {
scripts/doctor.mjs
- Executable scriptline 1
Executable file - Dangerous shell operationline 111
: os.platform() === 'darwin' ? 'brew install ffmpeg-full (plain "ffmpeg" is Homebrew\'s slim build and cannot write WebP)' : 'sudo apt install ffmpeg') - Dangerous shell operationline 159
: 'sudo apt install ffmpeg (distro builds vary - otherwise a static build from johnvansickle.com/ffmpeg)' - Access to secretsline 189
[Credential-related source omitted] - Access to secretsline 190
[Credential-related source omitted] - Access to secretsline 191
[Credential-related source omitted] - Access to secretsline 193
[Credential-related source omitted] - Network accessline 197
[Credential-related source omitted] - Access to secretsline 197
[Credential-related source omitted] - Network accessline 198
[Credential-related source omitted] - Network accessline 199
const res = await fetch('https://api.kie.ai/api/v1/jobs/recordInfo?taskId=preflight-probe', { - Access to secretsline 200
[Credential-related source omitted] - Network accessline 247
route table from the client's is worse than no preflight at all. */ const ROUTES = [ ['upload host', 'POST', 'https://kieai.redpandaai.co/api/file-base64-upload'], - Network accessline 248
const ROUTES = [ ['upload host', 'POST', 'https://kieai.redpandaai.co/api/file-base64-upload'], ['createTask', 'POST', 'https://api.kie.ai/api/v1/jobs/createTask'], - Network accessline 249
['upload host', 'POST', 'https://kieai.redpandaai.co/api/file-base64-upload'], - Network accessline 250
['createTask', 'POST', 'https://api.kie.ai/api/v1/jobs/createTask'], - Network accessline 251
['Sol responses', 'POST', 'https://api.kie.ai/codex/v1/responses'], - Network accessline 252
['recordInfo', 'GET', 'https://api.kie.ai/api/v1/jobs/recordInfo?taskId=preflight-probe'], - Network accessline 258
code 401. The control is what makes that meaningful - the neighbouring /api/v1/common/credit answers a real HTTP 404 - so a 404 here would mean the route had genuinely moved. */ ['credit balance', 'GET', 'https://api.kie.ai/api/v1/ch - Network accessline 259
answers a real HTTP 404 - so a 404 here would mean the route had genuinely moved. */ ['credit balance', 'GET', 'https://api.kie.ai/api/v1/chat/credit'], ] - Network accessline 260
['credit balance', 'GET', 'https://api.kie.ai/api/v1/chat/credit'], - Network accessline 263
async function probeRoute (method, url) { try { const res = await fetch(url, { - Network accessline 264
try { const res = await fetch(url, { method, - Network accessline 265
const res = await fetch(url, { - Access to secretsline 453
[Credential-related source omitted] - Access to secretsline 458
[Credential-related source omitted] - Access to secretsline 460
[Credential-related source omitted] - Access to secretsline 462
[Credential-related source omitted] - Access to secretsline 464
[Credential-related source omitted]
scripts/ffmpeg-flags.mjs
- Executable scriptline 1
Executable file
scripts/keyframes.mjs
scripts/kie.mjs
- Executable scriptline 1
Executable file - Network accessline 16
const BASE = 'https://api.kie.ai' - Network accessline 20
that does not exist answers HTTP 404, a route that does answers quirk 2 above, an HTTP 200 carrying code 401): POST https://api.kie.ai/api/v1/file-base64-upload -> HTTP 404 Not Found - Network accessline 21
carrying code 401): POST https://api.kie.ai/api/v1/file-base64-upload -> HTTP 404 Not Found POST https://api.kie.ai/api/file-base64-upload -> HTTP 404 Not Found (dropping /v1 is NOT the fix) - Network accessline 22
POST https://api.kie.ai/api/v1/file-base64-upload -> HTTP 404 Not Found - Network accessline 23
POST https://api.kie.ai/api/file-base64-upload -> HTTP 404 Not Found (dropping /v1 is NOT the fix) - Network accessline 24
POST https://kieai.redpandaai.co/api/file-base64-upload -> HTTP 200, body code 401 (route exists, auth required) - Network accessline 25
The jobs API and the file host are two different services. Point uploads back at BASE and every run dies at its first network call with `HTTP 404 - No message available`. */ const UPLOAD_BASE = 'https://kieai.redpandaai.co' - Network accessline 27
const UPLOAD_BASE = 'https://kieai.redpandaai.co' - Access to secretsline 35
[Credential-related source omitted] - Access to secretsline 37
[Credential-related source omitted] - Network accessline 103
res = await fetch(url, { ...opts, signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS) }) - Access to secretsline 149
[Credential-related source omitted] - Network accessline 304
export async function download (url, dest) { fs.mkdirSync(path.dirname(dest), { recursive: true }) const res = await fetch(url, { signal: AbortSignal.timeout(DOWNLOAD_TIMEOUT_MS) }) - Network accessline 305
fs.mkdirSync(path.dirname(dest), { recursive: true }) const res = await fetch(url, { signal: AbortSignal.timeout(DOWNLOAD_TIMEOUT_MS) }) if (!res.ok) throw new KieError(`download failed ${res.status} for ${url}`) - Network accessline 306
const res = await fetch(url, { signal: AbortSignal.timeout(DOWNLOAD_TIMEOUT_MS) })
scripts/pricing.mjs
- Executable scriptline 1
Executable file - Network accessline 71
export const RATES = Object.freeze({ /* Read from https://kie.ai/pricing, which states it twice in its own copy: "Each credit is - Network accessline 72
/* Read from https://kie.ai/pricing, which states it twice in its own copy: "Each credit is - Network accessline 77
creditUsd: entry({ key: 'creditUsd', unit: 'usd-per-credit', low: 0.005, high: 0.005, source: 'https://kie.ai/pricing - "Each credit is valued at $0.005 USD"; matches the account ' + - Network accessline 78
key: 'creditUsd', unit: 'usd-per-credit', low: 0.005, high: 0.005, source: 'https://kie.ai/pricing - "Each credit is valued at $0.005 USD"; matches the account ' + "holder's $5 = 1000 credits top-up and every per-model quote on th - Network accessline 79
source: 'https://kie.ai/pricing - "Each credit is valued at $0.005 USD"; matches the account ' + - Network accessline 88
/* GPT Image 2, per image. Read from https://kie.ai/gpt-image-2, which carries the same line for - Network accessline 93
'image.1K': entry({ key: 'image.1K', unit: 'image', low: 6, high: 6, source: 'https://kie.ai/gpt-image-2 - "6 credits ($0.03) for 1 K"', - Network accessline 94
key: 'image.1K', unit: 'image', low: 6, high: 6, source: 'https://kie.ai/gpt-image-2 - "6 credits ($0.03) for 1 K"', checked: '2026-08-07', confidence: 'high', - Network accessline 95
source: 'https://kie.ai/gpt-image-2 - "6 credits ($0.03) for 1 K"', - Network accessline 98
'image.2K': entry({ key: 'image.2K', unit: 'image', low: 10, high: 10, source: 'https://kie.ai/gpt-image-2 - "10 credits ($0.05) for 2 K"', - Network accessline 99
key: 'image.2K', unit: 'image', low: 10, high: 10, source: 'https://kie.ai/gpt-image-2 - "10 credits ($0.05) for 2 K"', checked: '2026-08-07', confidence: 'high', - Network accessline 100
source: 'https://kie.ai/gpt-image-2 - "10 credits ($0.05) for 2 K"', - Network accessline 103
'image.4K': entry({ key: 'image.4K', unit: 'image', low: 16, high: 16, source: 'https://kie.ai/gpt-image-2 - "16 credits ($0.08) for 4 K"', - Network accessline 104
key: 'image.4K', unit: 'image', low: 16, high: 16, source: 'https://kie.ai/gpt-image-2 - "16 credits ($0.08) for 4 K"', checked: '2026-08-07', confidence: 'high', - Network accessline 105
source: 'https://kie.ai/gpt-image-2 - "16 credits ($0.08) for 4 K"', - Network accessline 109
/* Kling 3.0, per second of finished video. Read from https://kie.ai/kling-3-0, verbatim: - Network accessline 127
'video.std': entry({ key: 'video.std', unit: 'second', low: 14, high: 14, source: 'https://kie.ai/kling-3-0 - "Standard: no-audio 14 credits ($0.07) /s"', - Network accessline 128
key: 'video.std', unit: 'second', low: 14, high: 14, source: 'https://kie.ai/kling-3-0 - "Standard: no-audio 14 credits ($0.07) /s"', checked: '2026-08-07', confidence: 'high', - Network accessline 129
source: 'https://kie.ai/kling-3-0 - "Standard: no-audio 14 credits ($0.07) /s"', - Network accessline 133
'video.pro': entry({ key: 'video.pro', unit: 'second', low: 18, high: 18, source: 'https://kie.ai/kling-3-0 - "Pro: no-audio 18 credits ($0.09) / s"', - Network accessline 134
key: 'video.pro', unit: 'second', low: 18, high: 18, source: 'https://kie.ai/kling-3-0 - "Pro: no-audio 18 credits ($0.09) / s"', checked: '2026-08-07', confidence: 'high', - Network accessline 135
source: 'https://kie.ai/kling-3-0 - "Pro: no-audio 18 credits ($0.09) / s"', - Network accessline 139
'video.4K': entry({ key: 'video.4K', unit: 'second', low: 67, high: 67, source: 'https://kie.ai/kling-3-0 - "4K: no/with audio 67 credits ($0.335) /s"', - Network accessline 140
key: 'video.4K', unit: 'second', low: 67, high: 67, source: 'https://kie.ai/kling-3-0 - "4K: no/with audio 67 credits ($0.335) /s"', checked: '2026-08-07', confidence: 'high', - Network accessline 141
source: 'https://kie.ai/kling-3-0 - "4K: no/with audio 67 credits ($0.335) /s"', - Network accessline 149
kie.ai's per-token rates are quoted plainly (https://kie.ai/gpt-5-6): - Network accessline 162
'sol.call': entry({ key: 'sol.call', unit: 'call', low: 0.84, high: 6.72, source: 'derived: https://kie.ai/gpt-5-6 quotes gpt-5-6-sol at 280 credits/1M input tokens and ' + - Network accessline 163
key: 'sol.call', unit: 'call', low: 0.84, high: 6.72, source: 'derived: https://kie.ai/gpt-5-6 quotes gpt-5-6-sol at 280 credits/1M input tokens and ' + '1680 credits/1M output tokens; one measured storyboard run used ~3-4k tokens - Network accessline 164
source: 'derived: https://kie.ai/gpt-5-6 quotes gpt-5-6-sol at 280 credits/1M input tokens and ' + - Network accessline 639
through several backoffs for a number it is allowed not to have. One attempt, short deadline, degrade. */ const BALANCE_URL = 'https://api.kie.ai/api/v1/chat/credit' - Network accessline 640
degrade. */ const BALANCE_URL = 'https://api.kie.ai/api/v1/chat/credit' const BALANCE_TIMEOUT_MS = 8000 - Network accessline 641
const BALANCE_URL = 'https://api.kie.ai/api/v1/chat/credit' - Access to secretsline 646
[Credential-related source omitted] - Access to secretsline 654
[Credential-related source omitted]
scripts/seams.mjs
- Executable scriptline 1
Executable file
scripts/storyboard.mjs
- Executable scriptline 1
Executable file
scripts/tween.mjs
test/README.md
- Access to secretsline 64
[Credential-related source omitted] - Network accessline 112
One caveat, recorded so nobody over-reads the file: the *mid-response* drop test holds with or without the flag. `fetch()` resolves once headers arrive and it is `await res.text()` that rejects, - Network accessline 113
without the flag. `fetch()` resolves once headers arrive and it is `await res.text()` that rejects, - Access to secretsline 233
[Credential-related source omitted]
test/args.test.mjs
- Executable scriptline 1
Executable file
test/build-frames-aspect.test.mjs
- Executable scriptline 1
Executable file
test/build-frames-gaps.test.mjs
- Executable scriptline 1
Executable file
test/build-frames-steps.test.mjs
- Executable scriptline 1
Executable file
test/camera-lock.test.mjs
- Executable scriptline 1
Executable file - Network accessline 24
const file = path.join(kfDir, `keyframe-0${s.id}.png`) write(file, 'placeholder') frames[s.id] = { file, url: 'https://example.invalid/uploads/fake/kf' + s.id, uploadedAt: Date.now() } - Network accessline 25
write(file, 'placeholder') frames[s.id] = { file, url: 'https://example.invalid/uploads/fake/kf' + s.id, uploadedAt: Date.now() } } - Network accessline 26
frames[s.id] = { file, url: 'https://example.invalid/uploads/fake/kf' + s.id, uploadedAt: Date.now() }
test/captions.test.mjs
- Executable scriptline 1
Executable file
test/cheaper-ways.test.mjs
- Executable scriptline 1
Executable file - Network accessline 32
const file = path.join(kfDir, `keyframe-0${s.id}.png`) write(file, 'placeholder') frames[s.id] = { file, url: 'https://example.invalid/uploads/fake/kf' + s.id, uploadedAt: Date.now() } - Network accessline 33
write(file, 'placeholder') frames[s.id] = { file, url: 'https://example.invalid/uploads/fake/kf' + s.id, uploadedAt: Date.now() } } - Network accessline 34
frames[s.id] = { file, url: 'https://example.invalid/uploads/fake/kf' + s.id, uploadedAt: Date.now() } - Network accessline 121
const file = path.join(kfDir, `keyframe-0${s.id}.png`) write(file, 'placeholder') frames[s.id] = { file, url: 'https://example.invalid/uploads/fake/kf' + s.id, uploadedAt: Date.now() } - Network accessline 122
write(file, 'placeholder') frames[s.id] = { file, url: 'https://example.invalid/uploads/fake/kf' + s.id, uploadedAt: Date.now() } } - Network accessline 123
frames[s.id] = { file, url: 'https://example.invalid/uploads/fake/kf' + s.id, uploadedAt: Date.now() }
test/config-globals-documented.test.mjs
- Executable scriptline 1
Executable file
test/connect-key.test.mjs
- Executable scriptline 1
Executable file - Access to secretsline 29
[Credential-related source omitted] - Access to secretsline 30
[Credential-related source omitted] - Access to secretsline 31
[Credential-related source omitted] - Access to secretsline 32
[Credential-related source omitted] - Access to secretsline 33
[Credential-related source omitted] - Access to secretsline 34
[Credential-related source omitted] - Access to secretsline 35
[Credential-related source omitted] - Access to secretsline 36
[Credential-related source omitted]
test/contact-sheet.test.mjs
- Executable scriptline 1
Executable file - Network accessline 81
{ ...sb, _meta: { ref: 'ref.jpg', ...extraMeta } }) write(path.join(outDir, '_state.json'), { refUrlRec: { url: 'https://example.invalid/ref.jpg', uploadedAt: Date.now() }, - Network accessline 82
write(path.join(outDir, '_state.json'), { refUrlRec: { url: 'https://example.invalid/ref.jpg', uploadedAt: Date.now() }, frames, - Network accessline 83
refUrlRec: { url: 'https://example.invalid/ref.jpg', uploadedAt: Date.now() },
test/doctor-mask.test.mjs
test/dry-run.test.mjs
- Executable scriptline 1
Executable file - Network accessline 84
const file = path.join(kfDir, `keyframe-0${s.id}.png`) write(file, 'placeholder') frames[s.id] = { file, url: 'https://example.invalid/uploads/fake/kf' + s.id, uploadedAt: Date.now() } - Network accessline 85
write(file, 'placeholder') frames[s.id] = { file, url: 'https://example.invalid/uploads/fake/kf' + s.id, uploadedAt: Date.now() } } - Network accessline 86
frames[s.id] = { file, url: 'https://example.invalid/uploads/fake/kf' + s.id, uploadedAt: Date.now() }
test/encoder-column.test.mjs
- Executable scriptline 1
Executable file
test/ffmpeg-compat.test.mjs
- Executable scriptline 1
Executable file
test/float.test.mjs
- Executable scriptline 1
Executable file
test/frame-normalisation.test.mjs
- Executable scriptline 1
Executable file
test/helpers/harness.mjs
- Executable scriptline 1
Executable file - Network accessline 69
default: every other test in this suite proves it did NOT reach a paid path, and that proof is worth more than the convenience of a stub that always answers. */ function stubSource ({ solText = null, image = null, uploadUrl = 'https://ex - Network accessline 70
worth more than the convenience of a stub that always answers. */ function stubSource ({ solText = null, image = null, uploadUrl = 'https://example.invalid/uploads/fake' } = {}) { return `/* GENERATED by test/helpers/harness.mjs. Not part - Network accessline 71
function stubSource ({ solText = null, image = null, uploadUrl = 'https://example.invalid/uploads/fake' } = {}) { - Access to secretsline 81
[Credential-related source omitted] - Access to secretsline 194
[Credential-related source omitted] - Access to secretsline 199
[Credential-related source omitted]
test/image-url-unwrap.test.mjs
test/kie-client.test.mjs
- Executable scriptline 1
Executable file - Network accessline 27
const UPLOAD_URL = 'https://kieai.redpandaai.co/api/file-base64-upload' - Network accessline 39
const OK = () => new Response(JSON.stringify({ code: 200, data: { fileUrl: 'https://files.invalid/x.bin' } }), - Access to secretsline 47
[Credential-related source omitted] - Access to secretsline 48
[Credential-related source omitted] - Access to secretsline 59
[Credential-related source omitted] - Access to secretsline 60
[Credential-related source omitted] - Network accessline 93
const declared = r.calls[0].body.base64Data.slice(5, r.calls[0].body.base64Data.indexOf(';')) assert.equal(declared.split('/')[1].replace('jpeg', 'jpg'), path.extname(fileName).slice(1)) assert.equal(r.v.url, 'https://files.inva - Network accessline 94
assert.equal(declared.split('/')[1].replace('jpeg', 'jpg'), path.extname(fileName).slice(1)) assert.equal(r.v.url, 'https://files.invalid/x.bin') assert.equal(typeof r.v.uploadedAt, 'number', 'the RECORD shape is what freshUrl n - Network accessline 95
assert.equal(r.v.url, 'https://files.invalid/x.bin') - Dangerous shell operationline 120
assert.doesNotMatch(r.e.message, /brew |apt-get |sudo /)
test/only-unknown-id.test.mjs
- Executable scriptline 1
Executable file - Network accessline 29
const cached = (n) => Object.fromEntries(Array.from({ length: n }, (_, i) => [i + 1, { file: `/tmp/keyframe-0${i + 1}.png`, url: `https://example.invalid/kf${i + 1}.png` }])) - Network accessline 30
[i + 1, { file: `/tmp/keyframe-0${i + 1}.png`, url: `https://example.invalid/kf${i + 1}.png` }])) - Network accessline 38
{ ...storyboard(4), _meta: { ref: 'ref.jpg' } }) write(path.join(outDir, '_state.json'), { refUrlRec: { url: 'https://example.invalid/ref.jpg', uploadedAt: Date.now() }, - Network accessline 39
write(path.join(outDir, '_state.json'), { refUrlRec: { url: 'https://example.invalid/ref.jpg', uploadedAt: Date.now() }, frames: cached(4), - Network accessline 40
refUrlRec: { url: 'https://example.invalid/ref.jpg', uploadedAt: Date.now() },
test/pricing-balance.test.mjs
test/pricing-calibration.test.mjs
- Executable scriptline 1
Executable file
test/pricing-estimates.test.mjs
- Executable scriptline 1
Executable file
test/retry-policy.test.mjs
- Executable scriptline 1
Executable file - Network accessline 48
const DONE = () => json({ code: 200, data: { state: 'success', resultJson: JSON.stringify({ resultUrls: ['https://files.invalid/clip.mp4'] }) }, - Network accessline 49
code: 200, data: { state: 'success', resultJson: JSON.stringify({ resultUrls: ['https://files.invalid/clip.mp4'] }) }, }) - Network accessline 50
data: { state: 'success', resultJson: JSON.stringify({ resultUrls: ['https://files.invalid/clip.mp4'] }) }, - Access to secretsline 60
[Credential-related source omitted] - Access to secretsline 63
[Credential-related source omitted] - Access to secretsline 79
[Credential-related source omitted] - Access to secretsline 80
[Credential-related source omitted] - Network accessline 95
resolve({ seen, base: `http://127.0.0.1:${srv.address().port}`, - Network accessline 96
seen, base: `http://127.0.0.1:${srv.address().port}`, close: () => new Promise(r => { srv.closeAllConnections(); srv.close(r) }), - Network accessline 97
base: `http://127.0.0.1:${srv.address().port}`, - Network accessline 136
dies. From the client that is indistinguishable from a request that never arrived, which is precisely why it must not be replayed. Verified against this server: fetch() itself rejects, the client reports `network error - - Network accessline 137
precisely why it must not be replayed. Verified against this server: fetch() itself rejects, the client reports `network error - fetch failed`, and the warning fires. */ - Network accessline 138
Verified against this server: fetch() itself rejects, the client reports `network error - - Network accessline 155
test('a socket dropped mid-response on createTask is not replayed either', async () => { /* The other half of the drop: headers arrived, the body was cut off. Observed rather than assumed - fetch() resolves here and `await res.text() - Network accessline 156
/* The other half of the drop: headers arrived, the body was cut off. Observed rather than assumed - fetch() resolves here and `await res.text()` is what rejects, which is OUTSIDE the attempt loop, so the failure escapes as a bare - Network accessline 157
assumed - fetch() resolves here and `await res.text()` is what rejects, which is OUTSIDE the - Network accessline 197
(url, opts, n) => (n === 1 ? json({ msg: 'bad gateway' }, 502) : DONE())) assert.ok(r.ok, `pollTask threw: ${r.e && r.e.message}`) assert.deepEqual(r.v, ['https://files.invalid/clip.mp4']) - Network accessline 198
assert.ok(r.ok, `pollTask threw: ${r.e && r.e.message}`) assert.deepEqual(r.v, ['https://files.invalid/clip.mp4']) assert.ok(r.calls.length > 1, 'a poll must keep retrying - it is free, and giving up abandons a render already paid for') - Network accessline 199
assert.deepEqual(r.v, ['https://files.invalid/clip.mp4'])
test/run.mjs
- Executable scriptline 1
Executable file
test/seams.test.mjs
- Executable scriptline 1
Executable file
test/spend-gate-cost.test.mjs
- Executable scriptline 1
Executable file - Access to secretsline 20
[Credential-related source omitted] - Network accessline 42
const frames = (ids) => Object.fromEntries(ids.map(i => [i, { file: `keyframe-0${i}.png`, url: `https://example.invalid/kf${i}.png` }])) - Network accessline 43
[i, { file: `keyframe-0${i}.png`, url: `https://example.invalid/kf${i}.png` }])) - Network accessline 51
const sbFile = write(path.join(dir, 'storyboard.json'), { ...storyboard(steps), _meta: meta }) write(path.join(outDir, '_state.json'), { refUrlRec: { url: 'https://example.invalid/ref.jpg', uploadedAt: Date.now() }, - Network accessline 52
write(path.join(outDir, '_state.json'), { refUrlRec: { url: 'https://example.invalid/ref.jpg', uploadedAt: Date.now() }, frames: frames(cached), - Network accessline 53
refUrlRec: { url: 'https://example.invalid/ref.jpg', uploadedAt: Date.now() }, - Access to secretsline 178
[Credential-related source omitted] - Network accessline 226
export { args, confirm, state } export function requireKey () { return 'test-key-that-is-never-sent-anywhere' } export async function uploadFile () { return { url: 'https://example.invalid/u', uploadedAt: Date.now() } } - Network accessline 227
export function requireKey () { return 'test-key-that-is-never-sent-anywhere' } export async function uploadFile () { return { url: 'https://example.invalid/u', uploadedAt: Date.now() } } export async function freshUrl (rec) { return rec || - Network accessline 228
export async function uploadFile () { return { url: 'https://example.invalid/u', uploadedAt: Date.now() } } - Network accessline 229
export async function freshUrl (rec) { return rec || { url: 'https://example.invalid/u', uploadedAt: Date.now() } } - Network accessline 240
const outDir = path.join(dir, 'keyframes') const sbFile = write(path.join(dir, 'storyboard.json'), { ...storyboard(3), _meta: { ref: 'ref.jpg' } }) write(path.join(outDir, '_state.json'), { refUrlRec: { url: 'https://example.inv - Network accessline 241
const sbFile = write(path.join(dir, 'storyboard.json'), { ...storyboard(3), _meta: { ref: 'ref.jpg' } }) write(path.join(outDir, '_state.json'), { refUrlRec: { url: 'https://example.invalid/r', uploadedAt: Date.now() }, frames: {} }) - Network accessline 242
write(path.join(outDir, '_state.json'), { refUrlRec: { url: 'https://example.invalid/r', uploadedAt: Date.now() }, frames: {} })
test/stale-config.test.mjs
- Executable scriptline 1
Executable file
test/storyboard-schema.test.mjs
- Executable scriptline 1
Executable file
test/storyboard-seed.test.mjs
- Executable scriptline 1
Executable file
test/style.test.mjs
- Executable scriptline 1
Executable file
test/upload-name.test.mjs
- Executable scriptline 1
Executable file - Access to secretsline 20
[Credential-related source omitted] - Access to secretsline 25
[Credential-related source omitted] - Network accessline 27
globalThis.fetch = async (url, opts) => { names.push(JSON.parse(opts.body).fileName) return new Response(JSON.stringify({ code: 200, msg: 'success', data: { fileUrl: 'https://file.kie.ai/uploads/x.png' } }), { status: 200 }) - Network accessline 28
names.push(JSON.parse(opts.body).fileName) return new Response(JSON.stringify({ code: 200, msg: 'success', data: { fileUrl: 'https://file.kie.ai/uploads/x.png' } }), { status: 200 }) } - Network accessline 29
return new Response(JSON.stringify({ code: 200, msg: 'success', data: { fileUrl: 'https://file.kie.ai/uploads/x.png' } }), { status: 200 }) - Access to secretsline 33
[Credential-related source omitted] - Access to secretsline 34
[Credential-related source omitted]
How the signals fit together
Facts from a static read of the files at the pinned commit. They describe what the code does, not why.
Some files could not be read; the facts below still hold.
Declared and executed: 2 facts
- Contacts kieai.redpandaai.co, which SKILL.md, the README and the plugin manifest do not mentionscripts/doctor.mjs:249High confidence
- Contacts kieai.redpandaai.co, which SKILL.md, the README and the plugin manifest do not mentionscripts/kie.mjs:24High confidence
Signal confidence: 314 facts
- Access to secrets in prose of documentationAGENTS.md:57Low confidence
- Network access in prose of documentationCHANGELOG.md:3Low confidence
- Network access in prose of documentationCHANGELOG.md:293Low confidence
- Network access in prose of documentationCHANGELOG.md:294Low confidence
- Network access in prose of documentationCHANGELOG.md:295Low confidence
- Network access in prose of documentationREADME.md:12Low confidence
- Network access in prose of documentationREADME.md:14Low confidence
- Network access in prose of documentationREADME.md:36Low confidence
- Network access in prose of documentationREADME.md:37Low confidence
- Network access in prose of documentationREADME.md:38Low confidence
- Network access in prose of documentationREADME.md:39Low confidence
- Network access in prose of documentationREADME.md:40Low confidence
- Network access in prose of documentationREADME.md:41Low confidence
- Network access in prose of documentationREADME.md:42Low confidence
- Network access in prose of documentationREADME.md:44Low confidence
- Network access in prose of documentationREADME.md:45Low confidence
- Network access in prose of documentationREADME.md:46Low confidence
- Network access in prose of documentationREADME.md:47Low confidence
- Network access in prose of documentationREADME.md:48Low confidence
- Network access in prose of documentationREADME.md:49Low confidence
- Network access in prose of documentationREADME.md:55Low confidence
- Network access in prose of documentationREADME.md:56Low confidence
- Network access in prose of documentationREADME.md:181Low confidence
- Network access in prose of documentationREADME.md:183Low confidence
- Network access in prose of documentationREADME.md:187Low confidence
- Network access in prose of documentationREADME.md:188Low confidence
- Network access in prose of documentationREADME.md:193Low confidence
- Access to secrets in code of documentation: a variable, placeholder or call, not a stored valueREADME.md:203Low confidence
- Access to secrets in code of documentation: a variable, placeholder or call, not a stored valueREADME.md:208Low confidence
- Access to secrets in code of documentation: a variable, placeholder or call, not a stored valueREADME.md:220Low confidence
- Access to secrets in code of documentation: a variable, placeholder or call, not a stored valueREADME.md:225Low confidence
- Network access in prose of documentationREADME.md:324Low confidence
- Network access in prose of documentationREADME.md:370Low confidence
- Network access in prose of documentationREADME.md:371Low confidence
- Network access in prose of documentationREADME.md:373Low confidence
- Network access in prose of documentationREADME.md:374Low confidence
- Network access in prose of documentationREADME.md:375Low confidence
- Network access in prose of documentationREADME.md:376Low confidence
- Network access in prose of documentationREADME.md:377Low confidence
- Network access in prose of documentationREADME.md:383Low confidence
- Network access in prose of documentationREADME.md:385Low confidence
- Network access in prose of documentationREADME.md:389Low confidence
- Network access in prose of documentationREADME.md:395Low confidence
- Network access in prose of documentationREADME.md:396Low confidence
- Network access in prose of documentationREADME.md:397Low confidence
- Network access in prose of documentationSECURITY.md:13Low confidence
- Access to secrets in prose of documentationSECURITY.md:27Low confidence
- Access to secrets in prose of documentationSECURITY.md:35Low confidence
- Broad permissions in the frontmatter of the SKILL.mdSKILL.md:1High confidence
- Access to secrets in prose of the SKILL.mdSKILL.md:414Low confidence
and 264 more
Works with
| Agent | Status | Evidence | Install to |
|---|---|---|---|
| Claude Code | Native | Manifest .claude-plugin/marketplace.json | .claude/skills/<skill-name>/ |
| Codex | Native | Manifest AGENTS.md | .agents/skills/<skill-name>/ |
| Cursor | Compatible | Standard SKILL.md SKILL.md | .cursor/skills/<skill-name>/ |
| Gemini CLI | Compatible | Standard SKILL.md SKILL.md | .gemini/skills/<skill-name>/ |
| GitHub Copilot | Compatible | Standard SKILL.md SKILL.md | .github/skills/<skill-name>/ |
| OpenCode | Compatible | Standard SKILL.md SKILL.md | .opencode/skills/<skill-name>/ |
- Native The repository ships a manifest, folder or frontmatter field for this agent.
- Compatible A standard SKILL.md that this agent can read.
- Unknown No evidence either way.
Derived automatically from paths, manifests and frontmatter. Not tested on each agent.