Explanation:
**Evaluating video tool options**

PixVerse offers 90 free daily refresh credits, which is great. I suspect Pika might work without an account, but I need to check if it has an API. For CapCut, I need to figure out the manual process since there are no credit details. It seems I should establish a process for using these free providers effectively, including a workflow for exports and external AI video job specifications. Additionally, I need to look into my code repository to track changes and implement new tests, maybe using TDD again.


test-driven-development

---
name: test-driven-development
description: "TDD: enforce RED-GREEN-REFACTOR, tests before code."
version: 1.1.0
author: Hermes Agent (adapted from obra/superpowers)
license: MIT
platforms: [linux, macos, windows]
metadata:
  hermes:
    tags: [testing, tdd, development, quality, red-green-refactor]
    related_skills: [systematic-debugging, writing-plans, subagent-driven-development]
---

# Test-Driven Development (TDD)

## Overview

Write the test first. Watch it fail. Write minimal code to pass.

**Core principle:** If you didn't watch the test fail, you don't know if it tests the right thing.

**Violating the letter of the rules is violating the spirit of the rules.**

## When to Use

**Always:**
- New features
- Bug fixes
- Refactoring
- Behavior changes

**Exceptions (ask the user first):**
- Throwaway prototypes
- Generated code
- Configuration files

Thinking "skip TDD just this once"? Stop. That's rationalization.

## The Iron Law

```
NO PRODUCTION CODE WITHOUT A FAILING TEST FIRST
```

Write code before the test? Delete it. Start over.

**No exceptions:**
- Don't keep it as "reference"
- Don't "adapt" it while writing tests
- Don't look at it
- Delete means delete

Implement fresh from tests. Period.

## Red-Green-Refactor Cycle

### RED — Write Failing Test

Write one minimal test showing what should happen.

**Good test:**
```python
def test_retries_failed_operations_3_times():
    attempts = 0
    def operation():
        nonlocal attempts
        attempts += 1
        if attempts < 3:
            raise Exception('fail')
        return 'success'

    result = retry_operation(operation)

    assert result == 'success'
    assert attempts == 3
```
Clear name, tests real behavior, one thing.

**Bad test:**
```python
def test_retry_works():
    mock = MagicMock()
    mock.side_effect = [Exception(), Exception(), 'success']
    result = retry_operation(mock)
    assert result == 'success'  # What about retry count? Timing?
```
Vague name, tests mock not real code.

**Requirements:**
- One behavior per test
- Clear descriptive name ("and" in name? Split it)
- Real code, not mocks (unless truly unavoidable)
- Name describes behavior, not implementation

### Verify RED — Watch It Fail

**MANDATORY. Never skip.**

```bash
# Use terminal tool to run the specific test
pytest tests/test_feature.py::test_specific_behavior -v
```

Confirm:
- Test fails (not errors from typos)
- Failure message is expected
- Fails because the feature is missing

**Test passes immediately?** You're testing existing behavior. Fix the test.

**Test errors?** Fix the error, re-run until it fails correctly.

### GREEN — Minimal Code

Write the simplest code to pass the test. Nothing more.

**Good:**
```python
def add(a, b):
    return a + b  # Nothing extra
```

**Bad:**
```python
def add(a, b):
    result = a + b
    logging.info(f"Adding {a} + {b} = {result}")  # Extra!
    return result
```

Don't add features, refactor other code, or "improve" beyond the test.

**Cheating is OK in GREEN:**
- Hardcode return values
- Copy-paste
- Duplicate code
- Skip edge cases

We'll fix it in REFACTOR.

### Verify GREEN — Watch It Pass

**MANDATORY.**

```bash
# Run the specific test
pytest tests/test_feature.py::test_specific_behavior -v

# Then run ALL tests to check for regressions
pytest tests/ -q
```

Confirm:
- Test passes
- Other tests still pass
- Output pristine (no errors, warnings)

**Test fails?** Fix the code, not the test.

**Other tests fail?** Fix regressions now.

### REFACTOR — Clean Up

After green only:
- Remove duplication
- Improve names
- Extract helpers
- Simplify expressions

Keep tests green throughout. Don't add behavior.

**If tests fail during refactor:** Undo immediately. Take smaller steps.

### Repeat

Next failing test for next behavior. One cycle at a time.

## Why Order Matters

**"I'll write tests after to verify it works"**

Tests written after code pass immediately. Passing immediately proves nothing:
- Might test the wrong thing
- Might test implementation, not behavior
- Might miss edge cases you forgot
- You never saw it catch the bug

Test-first forces you to see the test fail, proving it actually tests something.

**"I already manually tested all the edge cases"**

Manual testing is ad-hoc. You think you tested everything but:
- No record of what you tested
- Can't re-run when code changes
- Easy to forget cases under pressure
- "It worked when I tried it" ≠ comprehensive

Automated tests are systematic. They run the same way every time.

**"Deleting X hours of work is wasteful"**

Sunk cost fallacy. The time is already gone. Your choice now:
- Delete and rewrite with TDD (high confidence)
- Keep it and add tests after (low confidence, likely bugs)

The "waste" is keeping code you can't trust.

**"TDD is dogmatic, being pragmatic means adapting"**

TDD IS pragmatic:
- Finds bugs before commit (faster than debugging after)
- Prevents regressions (tests catch breaks immediately)
- Documents behavior (tests show how to use code)
- Enables refactoring (change freely, tests catch breaks)

"Pragmatic" shortcuts = debugging in production = slower.

**"Tests after achieve the same goals — it's spirit not ritual"**

No. Tests-after answer "What does this do?" Tests-first answer "What should this do?"

Tests-after are biased by your implementation. You test what you built, not what's required. Tests-first force edge case discovery before implementing.

## Common Rationalizations

| Excuse | Reality |
|--------|---------|
| "Too simple to test" | Simple code breaks. Test takes 30 seconds. |
| "I'll test after" | Tests passing immediately prove nothing. |
| "Tests after achieve same goals" | Tests-after = "what does this do?" Tests-first = "what should this do?" |
| "Already manually tested" | Ad-hoc ≠ systematic. No record, can't re-run. |
| "Deleting X hours is wasteful" | Sunk cost fallacy. Keeping unverified code is technical debt. |
| "Keep as reference, write tests first" | You'll adapt it. That's testing after. Delete means delete. |
| "Need to explore first" | Fine. Throw away exploration, start with TDD. |
| "Test hard = design unclear" | Listen to the test. Hard to test = hard to use. |
| "TDD will slow me down" | TDD faster than debugging. Pragmatic = test-first. |
| "Manual test faster" | Manual doesn't prove edge cases. You'll re-test every change. |
| "Existing code has no tests" | You're improving it. Add tests for the code you touch. |

## Red Flags — STOP and Start Over

If you catch yourself doing any of these, delete the code and restart with TDD:

- Code before test
- Test after implementation
- Test passes immediately on first run
- Can't explain why test failed
- Tests added "later"
- Rationalizing "just this once"
- "I already manually tested it"
- "Tests after achieve the same purpose"
- "Keep as reference" or "adapt existing code"
- "Already spent X hours, deleting is wasteful"
- "TDD is dogmatic, I'm being pragmatic"
- "This is different because..."

**All of these mean: Delete code. Start over with TDD.**

## Verification Checklist

Before marking work complete:

- [ ] Every new function/method has a test
- [ ] Watched each test fail before implementing
- [ ] Each test failed for expected reason (feature missing, not typo)
- [ ] Wrote minimal code to pass each test
- [ ] All tests pass
- [ ] Output pristine (no errors, warnings)
- [ ] Tests use real code (mocks only if unavoidable)
- [ ] Edge cases and errors covered

Can't check all boxes? You skipped TDD. Start over.

## When Stuck

| Problem | Solution |
|---------|----------|
| Don't know how to test | Write the wished-for API. Write the assertion first. Ask the user. |
| Test too complicated | Design too complicated. Simplify the interface. |
| Must mock everything | Code too coupled. Use dependency injection. |
| Test setup huge | Extract helpers. Still complex? Simplify the design. |

## Hermes Agent Integration

### Running Tests

Use the `terminal` tool to run tests at each step:

```python
# RED — verify failure
terminal("pytest tests/test_feature.py::test_name -v")

# GREEN — verify pass
terminal("pytest tests/test_feature.py::test_name -v")

# Full suite — verify no regressions
terminal("pytest tests/ -q")
```

### With delegate_task

When dispatching subagents for implementation, enforce TDD in the goal:

```python
delegate_task(
    goal="Implement [feature] using strict TDD",
    context="""
    Follow test-driven-development skill:
    1. Write failing test FIRST
    2. Run test to verify it fails
    3. Write minimal code to pass
    4. Run test to verify it passes
    5. Refactor if needed
    6. Commit

    Project test command: pytest tests/ -q
    Project structure: [describe relevant files]
    """,
    toolsets=['terminal', 'file']
)
```

### With systematic-debugging

Bug found? Write failing test reproducing it. Follow TDD cycle. The test proves the fix and prevents regression.

Never fix bugs without a test.

## Testing Anti-Patterns

- **Testing mock behavior instead of real behavior** — mocks should verify interactions, not replace the system under test
- **Testing implementation details** — test behavior/results, not internal method calls
- **Happy path only** — always test edge cases, errors, and boundaries
- **Brittle tests** — tests should verify behavior, not structure; refactoring shouldn't break them
- **Substring sentinels that collide with generated IDs** — when asserting that amounts or fixture values are excluded from a result, assert the full formatted token (e.g. `999.00`) or a typed field, not a short substring like `999` that can appear inside UUIDs/hash-like IDs.

## Final Rule

```
Production code → test exists and failed first
Otherwise → not TDD
```

No exceptions without the user's explicit permission.


Explanation:
**Inspecting the repo**

I need to implement something, but first, it seems like a good idea to inspect the repository. I wonder if there are any important details or documentation I've missed. By checking it out first, I can ensure I'm on the right track and avoid potential issues later on. It’s always better to gather all necessary information before diving into an implementation. Let's see what I can find!

terminal

git status --short && git log --oneline -3


Output:
?? autoshorts/review_package.py
?? data/telegram_reviews/
?? scripts/generate_telegram_review_packages.py
?? tests/test_review_package.py
ff5df62 feat: add free local motion renderer
b54a903 feat: add free production job specs
4d1e8f8 feat: generate mechanism render manifests


Explanation:
**Considering video provider options**

I'm thinking about implementing a provider registry. It seems I might need to compile research into data. I'll create tests for the free AI video providers to select those suitable for realistic scenes. It would be helpful to generate external handoff specs and use source URLs with observed details. I also need to follow test-driven development along with adding options like CapCut, Pika, PixVerse, and Runway. These providers have usable free tiers, which the user wants.


Plans & Pricing | Luma

- main
  - navigation
    - link "Luma company logo" [ref=e21]
      - image "Luma company logo"
    - generic
      - link "PRODUCT" [ref=e22]
      - link "PRICING" [ref=e23]
      - link "API" [ref=e24]
      - link "ENTERPRISE" [ref=e25]
      - link "NEWS" [ref=e26]
      - link "JOIN US" [ref=e27]
    - link "Sign In" [ref=e28]
  - generic
    - heading "Plans & Pricing" [level=1, ref=e1]
    - paragraph
      - StaticText "Save up to 20% with yearly"
    - button "Monthly" [ref=e2]
      - StaticText "Monthly"
    - button "Yearly" [ref=e3]
    - heading "Individual plans" [level=3, ref=e4]
    - StaticText "Plus"
    - paragraph
      - StaticText "$30/month"
    - link "Start Now" [ref=e5]
    - image
    - StaticText "Luma and third-party image and video models"
    - image
    - StaticText "Edit access for guest collaborators"
    - image
    - StaticText "Commercial use"
    - StaticText "Pro"
    - paragraph
      - StaticText "$90/month"
    - link "Start Now" [ref=e6]
    - paragraph
      - StaticText "Everything in Plus, with:"
    - image
    - StaticText "4x usage with the Luma Agents"
    - StaticText "Ultra"
    - paragraph
      - StaticText "$300/month"
    - link "Start Now" [ref=e7]
    - paragraph
      - StaticText "Everything in Pro, with:"
    - image
    - StaticText "15x usage with the Luma Agents"
    - heading "Business plans" [level=3, ref=e8]
    - StaticText "Team"
    - StaticText "Contact us"
    - link "Get in touch" [ref=e9]
    - paragraph
      - StaticText "Everything in our regular plans, plus:"
    - image
    - StaticText "Manage and add team members"
    - image
    - StaticText "Projects, team organization, and team-wide sharing"
    - image
    - StaticText "Usage analytics"
    - image
    - StaticText "Shared team credits"
    - image
    - StaticText "SSO"
    - StaticText "Enterprise"
    - StaticText "Contact us"
    - link "Get in touch" [ref=e10]
    - paragraph
      - StaticText "Everything in our Team plan, plus"
    - image
    - StaticText "Enterprise commitments"
    - image
    - StaticText "Dedicated education and training"
    - image
    - StaticText "Custom fine-tuning"
  - generic
    - paragraph
      - StaticText "Force multiplying teams at"
    - list
      - listitem [level=1]
      - listitem [level=1]
      - listitem [level=1]
      - listitem [level=1]
      - listitem [level=1]
      - listitem [level=1]
      - listitem [level=1]
      - listitem [level=1]
      - listitem [level=1]
      - listitem [level=1]
      - listitem [level=1]
      - listitem [level=1]
      - listitem [level=1]
      - listitem [level=1]
      - listitem [level=1]
  - generic
    - heading "Cost Per Video Generation" [level=2, ref=e11]
    - StaticText "Model"
    - StaticText "Action"
    - StaticText "Resolution"
    - StaticText "Audio"
    - StaticText "Cost per second"
    - StaticText "Ray3.14 HDR"
    - StaticText "Text-to-Video Image-to-Video"
    - StaticText "Draft"
    - StaticText "-"
    - StaticText "16 credits"
    - StaticText "540p"
    - StaticText "-"
    - StaticText "40 credits"
    - StaticText "720p"
    - StaticText "-"
    - StaticText "80 credits"
    - StaticText "1080p"
    - StaticText "-"
    - StaticText "320 credits"
    - StaticText "Video-to-Video"
    - StaticText "Draft"
    - StaticText "-"
    - StaticText "48 credits"
    - StaticText "540p"
    - StaticText "-"
    - StaticText "96 credits"
    - StaticText "720p"
    - StaticText "-"
    - StaticText "192 credits"
    - StaticText "1080p"
    - StaticText "-"
    - StaticText "768 credits"
    - StaticText "Ray3.14"
    - StaticText "Text-to-Video Image-to-Video"
    - StaticText "Draft"
    - StaticText "-"
    - StaticText "4 credits"
    - StaticText "540p"
    - StaticText "-"
    - StaticText "10 credits"
    - StaticText "720p"
    - StaticText "-"
    - StaticText "20 credits"
    - StaticText "1080p"
    - StaticText "-"
    - StaticText "80 credits"
    - StaticText "Video-to-Video"
    - StaticText "Draft"
    - StaticText "-"
    - StaticText "12 credits"
    - StaticText "540p"
    - StaticText "-"
    - StaticText "24 credits"
    - StaticText "720p"
    - StaticText "-"
    - StaticText "48 credits"
    - StaticText "1080p"
    - StaticText "-"
    - StaticText "192 credits"
    - StaticText "Seedance 2.0"
    - StaticText "Text-to-Video Image-to-Video"
    - StaticText "480p"
    - StaticText "Yes"
    - StaticText "106 credits"
    - StaticText "720p"
    - StaticText "Yes"
    - StaticText "106 credits"
    - StaticText "1080p"
    - StaticText "Yes"
    - StaticText "106 credits"
    - StaticText "Video-to-Video"
    - StaticText "480p"
    - StaticText "Yes"
    - StaticText "106 credits"
    - StaticText "720p"
    - StaticText "Yes"
    - StaticText "106 credits"
    - StaticText "1080p"
    - StaticText "Yes"
    - StaticText "106 credits"
    - StaticText "Kling Omni"
    - StaticText "Text-to-Video Image-to-Video"
    - StaticText "720p"
    - StaticText "-"
    - StaticText "30 credits"
    - StaticText "720p"
    - StaticText "Yes"
    - StaticText "40 credits"
    - StaticText "1080p"
    - StaticText "-"
    - StaticText "40 credits"
    - StaticText "1080p"
    - StaticText "Yes"
    - StaticText "49 credits"
    - StaticText "2160p (4K)"
    - StaticText "-"
    - StaticText "147 credits"
    - StaticText "2160p (4K)"
    - StaticText "Yes"
    - StaticText "147 credits"
    - StaticText "Video-to-Video"
    - StaticText "720p"
    - StaticText "Yes"
    - StaticText "45 credits"
    - StaticText "1080p"
    - StaticText "Yes"
    - StaticText "59 credits"
    - StaticText "2160p (4K)"
    - StaticText "Yes"
    - StaticText "147 credits"
    - StaticText "Kling 3.0"
    - StaticText "Text-to-Video Image-to-Video"
    - StaticText "720p"
    - StaticText "-"
    - StaticText "30 credits"
    - StaticText "720p"
    - StaticText "Yes"
    - StaticText "40 credits"
    - StaticText "1080p"
    - StaticText "-"
    - StaticText "40 credits"
    - StaticText "1080p"
    - StaticText "Yes"
    - StaticText "49 credits"
    - StaticText "2160p (4K)"
    - StaticText "-"
    - StaticText "147 credits"
    - StaticText "2160p (4K)"
    - StaticText "Yes"
    - StaticText "147 credits"
    - StaticText "Kling 2.6"
    - StaticText "Text-to-Video Image-to-Video"
    - StaticText "720p"
    - StaticText "-"
    - StaticText "29 credits"
    - StaticText "720p"
    - StaticText "Yes"
    - StaticText "58 credits"
    - StaticText "1080p"
    - StaticText "-"
    - StaticText "29 credits"
    - StaticText "1080p"
    - StaticText "Yes"
    - StaticText "58 credits"
    - StaticText "Veo 3.1"
    - StaticText "Text-to-Video Image-to-Video"
    - StaticText "720p"
    - StaticText "-"
    - StaticText "140 credits"
    - StaticText "720p"
    - StaticText "Yes"
    - StaticText "280 credits"
    - StaticText "1080p"
    - StaticText "-"
    - StaticText "140 credits"
    - StaticText "1080p"
    - StaticText "Yes"
    - StaticText "280 credits"
    - StaticText "Veo 3"
    - StaticText "Text-to-Video Image-to-Video"
    - StaticText "720p"
    - StaticText "-"
    - StaticText "140 credits"
    - StaticText "720p"
    - StaticText "Yes"
    - StaticText "280 credits"
    - StaticText "1080p"
    - StaticText "-"
    - StaticText "140 credits"
    - StaticText "1080p"
    - StaticText "Yes"
    - StaticText "280 credits"
  - generic
    - heading "Cost Per Image Generation" [level=2, ref=e12]
    - StaticText "Model"
    - StaticText "Action"
    - StaticText "Quality"
    - StaticText "Cost per image"
    - StaticText "Uni-1"
    - StaticText "Create/Modify"
    - StaticText "-"
    - StaticText "30 credits"
    - StaticText "GPT Image 2"
    - StaticText "Create/Modify"
    - StaticText "Low-1K"
    - StaticText "3 credits"
    - StaticText "Low-2K"
    - StaticText "5 credits"
    - StaticText "Low-4K"

[... 116 more lines truncated, use browser_snapshot for full content]


Hailuo AI: AI Video Generator from Text & Image

- generic
  - alert
  - main
    - generic [ref=e1] clickable [cursor:pointer, onclick]
      - StaticText "Seedance 2.0 Price Blowout: Limited-time 65% OFF for omni reference! 720P costs as low as $0.07/sec."
      - image
      - StaticText "08d : 12h : 25m : 29s"
      - generic [ref=e2] clickable [cursor:pointer, onclick]
        - StaticText "Get Deal Now"
      - generic [ref=e3] clickable [cursor:pointer, onclick]
        - image
    - generic
      - generic
        - link [ref=e9]
        - link "Home" [ref=e10]
        - link "Assets" [ref=e11]
        - link "Tools" [ref=e12]
        - link "Hub" [ref=e13]
        - link "Video" [ref=e14]
        - link "Image" [ref=e15]
        - link "Audio" [ref=e16]
        - generic [ref=e5] clickable [cursor:pointer, onclick]
        - generic [ref=e6] clickable [cursor:pointer, onclick]
        - generic [ref=e7] clickable [cursor:pointer, onclick]
        - image
      - generic
        - tablist "Creation type"
          - tab "Create Video" [selected, ref=e17]
          - tab "Create Image" [ref=e18]
          - tab "Hailuo Agent" [ref=e19]
        - generic
        - generic
        - generic
        - generic
          - generic [ref=e29] clickable [onclick]
          - generic [ref=e20] clickable [cursor:pointer, onclick]
          - generic [ref=e30] clickable [onclick]
          - textbox [ref=e21]: Describe the video content you want to generate, e.g., "A child flying a kite in the park, golden sunlight, camera tilting up."

            - paragraph
              - StaticText "Describe the video content you want to generate, e.g., \"A child flying a kite in the park, golden sunlight, camera tilting up.\""
              - LineBreak "\n"
          - generic [ref=e22] clickable [cursor:pointer, onclick]
            - image
            - StaticText "Hailuo 2.3"
          - generic [ref=e23] clickable [cursor:pointer, onclick]
            - image
            - StaticText "Start/End Frame"
          - generic [ref=e24] clickable [cursor:pointer, onclick]
            - image
            - StaticText "768p"
            - image
            - StaticText "6s"
          - generic [ref=e25] clickable [cursor:pointer, onclick]
            - image
            - StaticText "1"
          - image
          - StaticText "25"
          - button "Create" [ref=e26]
            - image
            - StaticText "Create"
        - generic
          - generic
            - generic
              - generic [ref=e31] clickable [onclick]
                - generic [ref=e46] clickable [onclick]
                  - generic [ref=e82] clickable [onclick]
                    - image "AI Video banner by Hailuo AI Video Generator" [ref=e121] clickable [cursor:pointer, onclick]
                    - generic [ref=e122] clickable [cursor:pointer]
                      - image "logo" [ref=e125] clickable [cursor:pointer, onclick]
              - list
                - listitem [level=1]
                  - button "1" [ref=e47]
                - listitem [level=1]
                  - button "2" [ref=e48]
                - listitem [level=1]
                  - button "3" [ref=e49]
                - listitem [level=1]
                  - button "4" [ref=e50]
            - button [ref=e32]
              - image
            - button [ref=e33]
              - image
          - generic [ref=e34] clickable [onclick]
            - generic [ref=e51] clickable [onclick]
              - generic [ref=e83] clickable [onclick]
                - image "AI Video banner by Hailuo AI Video Generator" [ref=e123] clickable [cursor:pointer, onclick]
                - generic [ref=e124] clickable [cursor:pointer]
                  - image "logo" [ref=e126] clickable [cursor:pointer, onclick]
                  - StaticText "Tools Tab is Live: \nLight Studio is Ready "
        - generic
          - generic
            - generic
              - image
              - image
            - generic
              - link "Trending" [ref=e35]
                - StaticText "Trending"
              - link "Creative Image Pack" [ref=e36]
                - StaticText "Creative Image Pack"
              - link "Ads Free" [ref=e37]
                - StaticText "Ads"
                - StaticText "Free"
              - link "LoveFrame" [ref=e38]
                - StaticText "LoveFrame"
              - link "PetPal" [ref=e39]
                - StaticText "PetPal"
              - link "BabyForm" [ref=e40]
                - StaticText "BabyForm"
              - link "PlayFun" [ref=e41]
                - StaticText "PlayFun"
              - link "SnapMorph" [ref=e42]
                - StaticText "SnapMorph"
              - link "Style Switch" [ref=e43]
                - StaticText "Style Switch"
              - link "CineScope" [ref=e44]
                - StaticText "CineScope"
              - link "ASMR" [ref=e45]
                - StaticText "ASMR"
          - generic
            - generic
              - image
              - StaticText "HOT"
              - generic [ref=e52] clickable [cursor:pointer]
                - button "Realistic KBO Close-up Video from Photo - Upload a photo to create a realistic KBO baseball broadcast close-up video cover image by Hailuo AI Video Generator" [ref=e84]
              - button "39.8K" [ref=e85]
                - image
                - StaticText "39.8K"
            - generic
              - generic [ref=e53] clickable [cursor:pointer]
                - button "Upload Your Photo for a Trashion Makeover - Upload your photo to get your Trashion Makeover! cover image by Hailuo AI Video Generator" [ref=e86]
              - button "1522" [ref=e87]
                - image
                - StaticText "1522"
            - generic
              - generic [ref=e54] clickable [cursor:pointer]
              - button "1044" [ref=e88]
                - image
                - StaticText "1044"
            - generic
              - generic [ref=e55] clickable [cursor:pointer]
              - button "441" [ref=e89]
                - image
                - StaticText "441"
            - generic
              - generic [ref=e56] clickable [cursor:pointer]
              - button "1105" [ref=e90]
                - image
                - StaticText "1105"
            - generic
              - generic [ref=e57] clickable [cursor:pointer]
              - button "258" [ref=e91]
                - image
                - StaticText "258"
            - generic
              - generic [ref=e58] clickable [cursor:pointer]
              - button "2607" [ref=e92]
                - image
                - StaticText "2607"
            - generic
              - generic [ref=e59] clickable [cursor:pointer]
              - button "1392" [ref=e93]
                - image
                - StaticText "1392"
            - generic
              - generic [ref=e60] clickable [cursor:pointer]
              - button "2846" [ref=e94]
                - image
                - StaticText "2846"
            - generic
              - generic [ref=e61] clickable [cursor:pointer]
              - button "1295" [ref=e95]
                - image
                - StaticText "1295"
            - generic
              - generic [ref=e62] clickable [cursor:pointer]
                - button "Next-Gen Productivity: Evolved Creation Spaces - Creation Space Evolved: Defining Next-Gen Productivity cover image by Hailuo AI Video Generator" [ref=e96]
                  - image "Next-Gen Productivity: Evolved Creation Spaces - Creation Space Evolved: Defining Next-Gen Productivity cover image by Hailuo AI Video Generator"
              - button "283" [ref=e97]
                - image
                - StaticText "283"
            - generic
              - generic [ref=e63] clickable [cursor:pointer]

[... 93 more lines truncated, use browser_snapshot for full content]


Explanation:
**Planning a video project**

I think I need to create a realistic video plan that combines AI-generated clips from a free tier with a local renderer. That's a good hybrid approach! I should start coding now and make sure to use fixtures to streamline the process. And, of course, writing tests will be essential to ensure everything runs smoothly. I’ll document this step-by-step so that I can keep track of my progress!

todo

Free/freemium KI-Video-Tools für realistischere Shorts recherchieren

Gratis-Workflow-Entscheidung für AutoShortsBot ableiten


Provider-/Free-Tier-Registry und Job-Specs im Repo ergänzen

Tests, Artefakte und Git-Status verifizieren


import json
from pathlib import Path

from autoshorts.free_ai_video_providers import (
    FREE_AI_VIDEO_PROVIDERS,
    build_free_ai_video_handoff,
    recommended_provider_order,
    write_free_ai_video_handoffs,
)

FIXTURE = Path("data/free_production_jobs/mechanism_pilots/hidden-money-systems-warum-ein-billiges-auto-teuer-sein-kann.json")

def _jobs() -> dict:
    return json.loads(FIXTURE.read_text(encoding="utf-8"))

def test_provider_registry_contains_real_free_tier_candidates_from_research():
    providers = FREE_AI_VIDEO_PROVIDERS

    assert {"pixverse", "pika", "capcut", "hailuo"} <= set(providers)
    assert providers["pika"]["free_tier"]["monthly_credits"] == 80
    assert providers["pika"]["free_tier"]["max_resolution"] == "480p"
    assert providers["pixverse"]["free_tier"]["daily_refresh_credits"] == 90
    assert providers["capcut"]["free_tier"]["hd_export_claimed"] is True
    assert all(provider["cost_policy"] == "free_tier_only_no_paid_topups" for provider in providers.values())
    assert all(provider["automation_mode"] == "manual_browser_handoff" for provider in providers.values())

def test_recommended_provider_order_prioritizes_free_realistic_ai_video_for_cinematic_scenes():
    order = recommended_provider_order("cinematic_ai_video")

    assert order[:2] == ["pixverse", "pika"]
    assert "capcut" in order
    assert "runway" not in order
    assert "luma" not in order

def test_free_ai_video_handoff_creates_manual_jobs_for_realistic_clip_scenes_only():
    handoff = build_free_ai_video_handoff(_jobs())

    assert handoff["schema_version"] == "free_ai_video_handoff.v1"
    assert handoff["budget_policy"]["paid_topups_allowed"] is False
    assert handoff["video"]["id"] == "hidden-money-systems-warum-ein-billiges-auto-teuer-sein-kann"
    assert handoff["hybrid_strategy"]["final_assembly"] == "local_ffmpeg"

    ai_jobs = handoff["ai_video_jobs"]
    assert [job["scene_id"] for job in ai_jobs] == ["scene_01", "scene_02"]
    assert all(job["status"] == "manual_generation_required" for job in ai_jobs)
    assert all(job["provider_order"][:2] == ["pixverse", "pika"] for job in ai_jobs)
    assert all(job["free_tier_guardrails"]["do_not_buy_credits"] is True for job in ai_jobs)
    assert all(job["duration_seconds"] <= 5 for job in ai_jobs)
    assert all("no readable text" in job["negative_prompt"].lower() for job in ai_jobs)

    local_jobs = handoff["local_jobs"]
    assert {job["asset_mode"] for job in local_jobs} == {"mechanism_animation", "kinetic_text_overlay"}

def test_write_free_ai_video_handoffs_outputs_reviewable_json(tmp_path):
    paths = write_free_ai_video_handoffs([_jobs()], tmp_path)

    assert len(paths) == 1
    payload = json.loads(paths[0].read_text(encoding="utf-8"))
    assert payload["schema_version"] == "free_ai_video_handoff.v1"
    assert payload["ai_video_jobs"][0]["manual_steps"]


LSP diagnostics introduced by this edit:
<diagnostics file="/home/agent/jarvis_runtime/AutoShortsBot/tests/test_free_ai_video_providers.py">
ERROR [4:6] Import "autoshorts.free_ai_video_providers" could not be resolved [reportMissingImports] (Pyright)
</diagnostics>


terminal

Output:
==================================== ERRORS ====================================
____________ ERROR collecting tests/test_free_ai_video_providers.py ____________
ImportError while importing test module '/home/agent/jarvis_runtime/AutoShortsBot/tests/test_free_ai_video_providers.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
../../.local/share/uv/python/cpython-3.11.15-linux-x86_64-gnu/lib/python3.11/importlib/__init__.py:126: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
tests/test_free_ai_video_providers.py:4: in <module>
    from autoshorts.free_ai_video_providers import (
E   ModuleNotFoundError: No module named 'autoshorts.free_ai_video_providers'
=========================== short test summary info ============================
ERROR tests/test_free_ai_video_providers.py
!!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!
1 error in 0.12s


"""Free-tier AI video provider handoff specs.

This module does not automate paid video generation. It creates manual browser
handoff packets for free/freemium AI video tools, then keeps final assembly local.
The intent is a hybrid workflow: realistic short AI clips from free quotas plus
local mechanism animation/captions/FFmpeg composition.
"""

from __future__ import annotations

import json
from pathlib import Path
from typing import Any

from autoshorts.script_drafts import _slug

FREE_AI_VIDEO_PROVIDERS: dict[str, dict[str, Any]] = {
    "pixverse": {
        "display_name": "PixVerse",
        "url": "https://app.pixverse.ai/",
        "source_url": "https://app.pixverse.ai/",
        "researched_evidence": "App page showed 90 credits with daily refresh and signup prompt for free credits.",
        "cost_policy": "free_tier_only_no_paid_topups",
        "automation_mode": "manual_browser_handoff",
        "free_tier": {
            "daily_refresh_credits": 90,
            "signup_required": True,
            "best_use": "realistic text/image-to-video short clips",
        },
        "strengths": ["realistic clips", "daily free quota", "templates", "image-to-video"],
        "risks": ["terms and quotas can change", "manual account/login required", "possible watermark depending export path"],
    },
    "pika": {
        "display_name": "Pika",
        "url": "https://pika.art/",
        "source_url": "https://pika.art/pricing",
        "researched_evidence": "Pricing page showed Basic $0 with 80 monthly video credits, Pika 2.5 at 480p only, no-watermark downloads, and commercial use.",
        "cost_policy": "free_tier_only_no_paid_topups",
        "automation_mode": "manual_browser_handoff",
        "free_tier": {
            "monthly_credits": 80,
            "max_resolution": "480p",
            "text_to_video_5s_credits": 12,
            "watermark_free_claimed": True,
            "commercial_use_claimed": True,
            "signup_required": True,
        },
        "strengths": ["no-watermark claim", "commercial-use claim", "good fallback for 5s shots"],
        "risks": ["low 480p free resolution", "monthly quota is small", "manual account/login required"],
    },
    "capcut": {
        "display_name": "CapCut AI Video Maker",
        "url": "https://www.capcut.com/tools/ai-video-generator",
        "source_url": "https://www.capcut.com/tools/ai-video-generator",
        "researched_evidence": "CapCut tool page describes a free AI video generator and says final videos can be exported in HD quality for free.",
        "cost_policy": "free_tier_only_no_paid_topups",
        "automation_mode": "manual_browser_handoff",
        "free_tier": {
            "hd_export_claimed": True,
            "credit_amount_publicly_clear": False,
            "best_use": "editorial assembly, templates, captions, quick drafts",
            "signup_required": True,
        },
        "strengths": ["HD export claim", "editing/captions/templates", "easy manual polishing"],
        "risks": ["free quota not clearly exposed on public page", "may upsell Pro assets", "manual export required"],
    },
    "hailuo": {
        "display_name": "Hailuo AI",
        "url": "https://hailuoai.video/",
        "source_url": "https://hailuoai.video/",
        "researched_evidence": "Public generator page exposed 768p/6s generation controls and a visible 25-credit create cost, suitable only if free account credits are available.",
        "cost_policy": "free_tier_only_no_paid_topups",
        "automation_mode": "manual_browser_handoff",
        "free_tier": {
            "default_visible_generation_cost_credits": 25,
            "signup_required": True,
            "use_only_existing_free_credits": True,
        },
        "strengths": ["realistic generator", "768p/6s option visible"],
        "risks": ["do not buy credits", "free quota may vary", "user explicitly wants no paid Hailuo credits"],
    },
}

PAID_OR_UNSUITABLE_FOR_FREE_FIRST = {"runway", "luma", "kling", "veo", "sora"}
AI_VIDEO_SCENE_MODES = {"cinematic_ai_video"}
LOCAL_SCENE_MODES = {"mechanism_animation", "kinetic_text_overlay", "screen_recording_simulation", "animated_card"}

def recommended_provider_order(asset_mode: str) -> list[str]:
    """Return provider preference for a scene mode under free-tier constraints."""
    if asset_mode == "cinematic_ai_video":
        return ["pixverse", "pika", "capcut", "hailuo"]
    if asset_mode == "mechanism_animation":
        return ["local_renderer", "capcut"]
    return ["local_renderer"]

def _local_render_jobs(production_jobs: dict[str, Any]) -> list[dict[str, Any]]:
    return [job for job in production_jobs["jobs"] if job["provider"] in {"local_renderer", "local_ffmpeg"}]

def _duration_for_free_ai(job: dict[str, Any]) -> float:
    # Most free-tier AI video tools are strongest around 5s clips. Longer scenes
    # should be split later; the current pilot only needs two short cinematic clips.
    return min(5.0, float(job["duration_seconds"]))

def _provider_notes(provider_id: str) -> dict[str, Any]:
    provider = FREE_AI_VIDEO_PROVIDERS[provider_id]
    return {
        "provider": provider_id,
        "display_name": provider["display_name"],
        "url": provider["url"],
        "free_tier": provider["free_tier"],
        "risks": provider["risks"],
    }

def _ai_video_job(job: dict[str, Any]) -> dict[str, Any]:
    provider_order = recommended_provider_order(job["asset_mode"])
    return {
        "job_id": f"{job['scene_id']}_free_ai_video_handoff",
        "scene_id": job["scene_id"],
        "asset_mode": job["asset_mode"],
        "status": "manual_generation_required",
        "duration_seconds": _duration_for_free_ai(job),
        "aspect_ratio": "9:16",
        "preferred_resolution": "480p_or_best_free_available",
        "provider_order": provider_order,
        "providers": [_provider_notes(provider_id) for provider_id in provider_order],
        "prompt": _free_ai_prompt(job),
        "negative_prompt": job["negative_prompt"],
        "overlay_text": job["overlay_text"],
        "free_tier_guardrails": {
            "do_not_buy_credits": True,
            "use_only_free_daily_or_monthly_quota": True,
            "avoid_pro_templates_or_paid_assets": True,
            "export_without_baked_captions": True,
            "final_captions_added_locally": True,
        },
        "manual_steps": [
            "Open the first available provider in provider_order.",
            "Use text-to-video or image-to-video with the prompt below; choose vertical 9:16 if available.",
            "Set duration to the requested scene duration or the nearest free option, usually 5s.",
            "Do not buy credits, subscribe, or select paid-only models/templates.",
            "Download the clip, then place it under data/imported_ai_clips/<video_id>/<scene_id>.mp4 for local assembly.",
        ],
        "expected_clip_path": f"data/imported_ai_clips/{{video_id}}/{job['scene_id']}.mp4",
    }

def _free_ai_prompt(job: dict[str, Any]) -> str:
    return (
        f"Vertical 9:16 realistic cinematic short video, {job['source_prompt']} "
        "No captions, no readable text, no logos, no watermarks. Leave clean negative space in the lower third for captions. "
        "The clip should feel like real b-roll for a mechanism explainer, not a slideshow."
    )

def build_free_ai_video_handoff(production_jobs: dict[str, Any]) -> dict[str, Any]:
    """Build a manual free-tier AI video handoff while keeping local assembly."""
    local_jobs = _local_render_jobs(production_jobs)
    ai_jobs = [job for job in local_jobs if job["asset_mode"] in AI_VIDEO_SCENE_MODES]
    fallback_local_jobs = [job for job in local_jobs if job["asset_mode"] not in AI_VIDEO_SCENE_MODES]
    return {
        "schema_version": "free_ai_video_handoff.v1",
        "video": production_jobs["video"],
        "budget_policy": {
            "paid_topups_allowed": False,
            "paid_subscriptions_allowed": False,
            "allowed_strategy": "free_tier_manual_generation_plus_local_assembly",
            "local_fallback_required": True,
        },
        "researched_sources": [
            {"provider": key, "source_url": value["source_url"], "evidence": value["researched_evidence"]}
            for key, value in FREE_AI_VIDEO_PROVIDERS.items()
        ],
        "hybrid_strategy": {
            "realistic_clip_source": "free_tier_ai_video_tools_manual_handoff",
            "mechanism_explainer_source": "local_renderer",
            "captions": "local_kinetic_renderer_overlay",
            "final_assembly": "local_ffmpeg",
        },
        "ai_video_jobs": [_ai_video_job(job) for job in ai_jobs],
        "local_jobs": [
            {
                "scene_id": job["scene_id"],
                "asset_mode": job["asset_mode"],
                "provider": job["provider"],
                "execution_mode": job["execution_mode"],
                "duration_seconds": job["duration_seconds"],
                "role": "local_mechanism_or_caption_layer",
            }
            for job in fallback_local_jobs
        ],
    }

def _handoff_filename(video: dict[str, Any]) -> str:
    title_slug = _slug(video["title"])
    video_id = video["id"]
    if video_id.endswith(title_slug):
        return f"{video_id}.json"
    return f"{video_id}-{title_slug}.json"

def write_free_ai_video_handoffs(production_jobs_list: list[dict[str, Any]], output_dir: Path) -> list[Path]:
    """Write free-tier AI video handoff packets as JSON files."""
    output_dir.mkdir(parents=True, exist_ok=True)
    paths: list[Path] = []
    for production_jobs in production_jobs_list:
        handoff = build_free_ai_video_handoff(production_jobs)
        path = output_dir / _handoff_filename(handoff["video"])
        path.write_text(json.dumps(handoff, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
        paths.append(path)
    return paths


"""Generate manual free-tier AI video handoff packets."""

from __future__ import annotations

import argparse
import json
import sys
from pathlib import Path

PROJECT_ROOT = Path(__file__).resolve().parents[1]
if str(PROJECT_ROOT) not in sys.path:
    sys.path.insert(0, str(PROJECT_ROOT))

from autoshorts.free_ai_video_providers import write_free_ai_video_handoffs

def _load_jobs(path: Path) -> list[dict]:
    files = sorted(path.glob("*.json")) if path.is_dir() else [path]
    return [json.loads(file.read_text(encoding="utf-8")) for file in files]

def main() -> None:
    parser = argparse.ArgumentParser(description="Generate free-tier AI video handoff specs.")
    parser.add_argument("--jobs", default="data/free_production_jobs/mechanism_pilots")
    parser.add_argument("--out", default="data/free_ai_video_handoffs/mechanism_pilots")
    args = parser.parse_args()

    production_jobs = _load_jobs(Path(args.jobs))
    paths = write_free_ai_video_handoffs(production_jobs, Path(args.out))
    print(f"Generated {len(paths)} free AI video handoff specs in {args.out}")
    for path in paths:
        print(path)

if __name__ == "__main__":
    main()


Output:
....                                                                     [100%]
4 passed in 0.05s


python scripts/generate_free_ai_video_handoffs.py --jobs data/free_production_jobs/mechanism_pilots/hidden-money-systems-warum-ein-billiges-auto-teuer-sein-kann.json --out data/free_ai_video_handoffs/mechanism_pilots && pytest tests/ -q


Output:
Generated 1 free AI video handoff specs in data/free_ai_video_handoffs/mechanism_pilots
data/free_ai_video_handoffs/mechanism_pilots/hidden-money-systems-warum-ein-billiges-auto-teuer-sein-kann.json
.......................................................                  [100%]
55 passed in 3.53s


     1|{
     2|  "schema_version": "free_ai_video_handoff.v1",
     3|  "video": {
     4|    "id": "hidden-money-systems-warum-ein-billiges-auto-teuer-sein-kann",
     5|    "title": "Warum ein billiges Auto teuer sein kann",
     6|    "pillar": "hidden_money_systems",
     7|    "duration_ms": 34000,
     8|    "aspect_ratio": "9:16",
     9|    "resolution": {
    10|      "width": 1080,
    11|      "height": 1920
    12|    },
    13|    "fps": 30
    14|  },
    15|  "budget_policy": {
    16|    "paid_topups_allowed": false,
    17|    "paid_subscriptions_allowed": false,
    18|    "allowed_strategy": "free_tier_manual_generation_plus_local_assembly",
    19|    "local_fallback_required": true
    20|  },
    21|  "researched_sources": [
    22|    {
    23|      "provider": "pixverse",
    24|      "source_url": "https://app.pixverse.ai/",
    25|      "evidence": "App page showed 90 credits with daily refresh and signup prompt for free credits."
    26|    },
    27|    {
    28|      "provider": "pika",
    29|      "source_url": "https://pika.art/pricing",
    30|      "evidence": "Pricing page showed Basic $0 with 80 monthly video credits, Pika 2.5 at 480p only, no-watermark downloads, and commercial use."
    31|    },
    32|    {
    33|      "provider": "capcut",
    34|      "source_url": "https://www.capcut.com/tools/ai-video-generator",
    35|      "evidence": "CapCut tool page describes a free AI video generator and says final videos can be exported in HD quality for free."
    36|    },
    37|    {
    38|      "provider": "hailuo",
    39|      "source_url": "https://hailuoai.video/",
    40|      "evidence": "Public generator page exposed 768p/6s generation controls and a visible 25-credit create cost, suitable only if free account credits are available."
    41|    }
    42|  ],
    43|  "hybrid_strategy": {
    44|    "realistic_clip_source": "free_tier_ai_video_tools_manual_handoff",
    45|    "mechanism_explainer_source": "local_renderer",
    46|    "captions": "local_kinetic_renderer_overlay",
    47|    "final_assembly": "local_ffmpeg"
    48|  },
    49|  "ai_video_jobs": [
    50|    {
    51|      "job_id": "scene_01_free_ai_video_handoff",
    52|      "scene_id": "scene_01",
    53|      "asset_mode": "cinematic_ai_video",
    54|      "status": "manual_generation_required",
    55|      "duration_seconds": 1.4,
    56|      "aspect_ratio": "9:16",
    57|      "preferred_resolution": "480p_or_best_free_available",
    58|      "provider_order": [
    59|        "pixverse",
    60|        "pika",
    61|        "capcut",
    62|        "hailuo"
    63|      ],
    64|      "providers": [
    65|        {
    66|          "provider": "pixverse",
    67|          "display_name": "PixVerse",
    68|          "url": "https://app.pixverse.ai/",
    69|          "free_tier": {
    70|            "daily_refresh_credits": 90,
    71|            "signup_required": true,
    72|            "best_use": "realistic text/image-to-video short clips"
    73|          },
    74|          "risks": [
    75|            "terms and quotas can change",
    76|            "manual account/login required",
    77|            "possible watermark depending export path"
    78|          ]
    79|        },
    80|        {
    81|          "provider": "pika",
    82|          "display_name": "Pika",
    83|          "url": "https://pika.art/",
    84|          "free_tier": {
    85|            "monthly_credits": 80,
    86|            "max_resolution": "480p",
    87|            "text_to_video_5s_credits": 12,
    88|            "watermark_free_claimed": true,
    89|            "commercial_use_claimed": true,
    90|            "signup_required": true
    91|          },
    92|          "risks": [
    93|            "low 480p free resolution",
    94|            "monthly quota is small",
    95|            "manual account/login required"
    96|          ]
    97|        },
    98|        {
    99|          "provider": "capcut",
   100|          "display_name": "CapCut AI Video Maker",
   101|          "url": "https://www.capcut.com/tools/ai-video-generator",
   102|          "free_tier": {
   103|            "hd_export_claimed": true,
   104|            "credit_amount_publicly_clear": false,
   105|            "best_use": "editorial assembly, templates, captions, quick drafts",
   106|            "signup_required": true
   107|          },
   108|          "risks": [
   109|            "free quota not clearly exposed on public page",
   110|            "may upsell Pro assets",
   111|            "manual export required"
   112|          ]
   113|        },
   114|        {
   115|          "provider": "hailuo",
   116|          "display_name": "Hailuo AI",
   117|          "url": "https://hailuoai.video/",
   118|          "free_tier": {
   119|            "default_visible_generation_cost_credits": 25,
   120|            "signup_required": true,
   121|            "use_only_existing_free_credits": true
   122|          },
   123|          "risks": [
   124|            "do not buy credits",
   125|            "free quota may vary",
   126|            "user explicitly wants no paid Hailuo credits"
   127|          ]
   128|        }
   129|      ],
   130|      "prompt": "Vertical 9:16 realistic cinematic short video, Vertical 9:16 cinematic-looking local motion scene, a realistic creator at a desk late evening, laptop open to an AI chat, thoughtful but in control, hands moving between keyboard and notebook. Mood: focused, modern, high-retention social video, dramatic lighting simulated with gradients and shadows. Scene intent: 3D car x-ray with price tag layers and risk meters freezes mid-action with warning signal. Camera: slow handheld push-in, subtle parallax, natural micro-movements. Use local procedural animation/parallax rather than paid AI-video credits; keep captions renderer-overlay only. No captions, no readable text, no logos, no watermarks. Leave clean negative space in the lower third for captions. The clip should feel like real b-roll for a mechanism explainer, not a slideshow.",
   131|      "negative_prompt": "no readable text, no subtitles, no logos, no watermarks, no distorted hands, no fake UI text, no slideshow, no static image, no uncanny faces",
   132|      "overlay_text": "Dieser Occasion-Käufer denkt, er spart 4'000 Franken.",
   133|      "free_tier_guardrails": {
   134|        "do_not_buy_credits": true,
   135|        "use_only_free_daily_or_monthly_quota": true,
   136|        "avoid_pro_templates_or_paid_assets": true,
   137|        "export_without_baked_captions": true,
   138|        "final_captions_added_locally": true
   139|      },
   140|      "manual_steps": [
   141|        "Open the first available provider in provider_order.",
   142|        "Use text-to-video or image-to-video with the prompt below; choose vertical 9:16 if available.",
   143|        "Set duration to the requested scene duration or the nearest free option, usually 5s.",
   144|        "Do not buy credits, subscribe, or select paid-only models/templates.",
   145|        "Download the clip, then place it under data/imported_ai_clips/<video_id>/<scene_id>.mp4 for local assembly."
   146|      ],
   147|      "expected_clip_path": "data/imported_ai_clips/{video_id}/scene_01.mp4"
   148|    },
   149|    {
   150|      "job_id": "scene_02_free_ai_video_handoff",
   151|      "scene_id": "scene_02",
   152|      "asset_mode": "cinematic_ai_video",
   153|      "status": "manual_generation_required",
   154|      "duration_seconds": 3.6,
   155|      "aspect_ratio": "9:16",
   156|      "preferred_resolution": "480p_or_best_free_available",
   157|      "provider_order": [
   158|        "pixverse",
   159|        "pika",
   160|        "capcut",
   161|        "hailuo"
   162|      ],
   163|      "providers": [
   164|        {
   165|          "provider": "pixverse",
   166|          "display_name": "PixVerse",
   167|          "url": "https://app.pixverse.ai/",
   168|          "free_tier": {
   169|            "daily_refresh_credits": 90,
   170|            "signup_required": true,
   171|            "best_use": "realistic text/image-to-video short clips"
   172|          },
   173|          "risks": [
   174|            "terms and quotas can change",
   175|            "manual account/login required",
   176|            "possible watermark depending export path"
   177|          ]
   178|        },
   179|        {
   180|          "provider": "pika",
   181|          "display_name": "Pika",
   182|          "url": "https://pika.art/",
   183|          "free_tier": {
   184|            "monthly_credits": 80,
   185|            "max_resolution": "480p",
   186|            "text_to_video_5s_credits": 12,
   187|            "watermark_free_claimed": true,
   188|            "commercial_use_claimed": true,
   189|            "signup_required": true
   190|          },
   191|          "risks": [
   192|            "low 480p free resolution",
   193|            "monthly quota is small",
   194|            "manual account/login required"
   195|          ]
   196|        },
   197|        {
   198|          "provider": "capcut",
   199|          "display_name": "CapCut AI Video Maker",
   200|          "url": "https://www.capcut.com/tools/ai-video-generator",
   201|          "free_tier": {
   202|            "hd_export_claimed": true,
   203|            "credit_amount_publicly_clear": false,
   204|            "best_use": "editorial assembly, templates, captions, quick drafts",
   205|            "signup_required": true
   206|          },
   207|          "risks": [
   208|            "free quota not clearly exposed on public page",
   209|            "may upsell Pro assets",
   210|            "manual export required"
   211|          ]
   212|        },
   213|        {
   214|          "provider": "hailuo",
   215|          "display_name": "Hailuo AI",
   216|          "url": "https://hailuoai.video/",
   217|          "free_tier": {
   218|            "default_visible_generation_cost_credits": 25,
   219|            "signup_required": true,
   220|            "use_only_existing_free_credits": true
   221|          },
   222|          "risks": [
   223|            "do not buy credits",
   224|            "free quota may vary",
   225|            "user explicitly wants no paid Hailuo credits"
   226|          ]
   227|        }
   228|      ],
   229|      "prompt": "Vertical 9:16 realistic cinematic short video, Vertical 9:16 cinematic-looking local motion scene, a realistic creator at a desk late evening, laptop open to an AI chat, thoughtful but in control, hands moving between keyboard and notebook. Mood: focused, modern, high-retention social video, dramatic lighting simulated with gradients and shadows. Scene intent: surface layer peels away to reveal the hidden system underneath. Camera: slow handheld push-in, subtle parallax, natural micro-movements. Use local procedural animation/parallax rather than paid AI-video credits; keep captions renderer-overlay only. No captions, no readable text, no logos, no watermarks. Leave clean negative space in the lower third for captions. The clip should feel like real b-roll for a mechanism explainer, not a slideshow.",
   230|      "negative_prompt": "no readable text, no subtitles, no logos, no watermarks, no distorted hands, no fake UI text, no slideshow, no static image, no uncanny faces",
   231|      "overlay_text": "Das sieht harmlos aus, bis du den Mechanismus dahinter siehst.",
   232|      "free_tier_guardrails": {
   233|        "do_not_buy_credits": true,
   234|        "use_only_free_daily_or_monthly_quota": true,
   235|        "avoid_pro_templates_or_paid_assets": true,
   236|        "export_without_baked_captions": true,
   237|        "final_captions_added_locally": true
   238|      },
   239|      "manual_steps": [
   240|        "Open the first available provider in provider_order.",
   241|

Use offset=241 to continue reading (showing 1-240 of 275 lines)


patch

    assert all("no readable text" in job["negative_prompt"].lower() for job in ai_jobs)
    assert all("local procedural" not in job["prompt"].lower() for job in ai_jobs)
    assert all("paid ai-video credits" not in job["prompt"].lower() for job in ai_jobs)

    local_jobs = handoff["local_jobs"]

    assert all("no readable text" in job["negative_prompt"].lower() for job in ai_jobs)

    local_jobs = handoff["local_jobs"]


--- a//home/agent/jarvis_runtime/AutoShortsBot/tests/test_free_ai_video_providers.py
+++ b//home/agent/jarvis_runtime/AutoShortsBot/tests/test_free_ai_video_providers.py
@@ -52,6 +52,8 @@
     assert all(job["free_tier_guardrails"]["do_not_buy_credits"] is True for job in ai_jobs)
     assert all(job["duration_seconds"] <= 5 for job in ai_jobs)
     assert all("no readable text" in job["negative_prompt"].lower() for job in ai_jobs)
+    assert all("local procedural" not in job["prompt"].lower() for job in ai_jobs)
+    assert all("paid ai-video credits" not in job["prompt"].lower() for job in ai_jobs)

     local_jobs = handoff["local_jobs"]
     assert {job["asset_mode"] for job in local_jobs} == {"mechanism_animation", "kinetic_text_overlay"}


terminal

Output:
F                                                                        [100%]
=================================== FAILURES ===================================
_ test_free_ai_video_handoff_creates_manual_jobs_for_realistic_clip_scenes_only _

    def test_free_ai_video_handoff_creates_manual_jobs_for_realistic_clip_scenes_only():
        handoff = build_free_ai_video_handoff(_jobs())

        assert handoff["schema_version"] == "free_ai_video_handoff.v1"
        assert handoff["budget_policy"]["paid_topups_allowed"] is False
        assert handoff["video"]["id"] == "hidden-money-systems-warum-ein-billiges-auto-teuer-sein-kann"
        assert handoff["hybrid_strategy"]["final_assembly"] == "local_ffmpeg"

        ai_jobs = handoff["ai_video_jobs"]
        assert [job["scene_id"] for job in ai_jobs] == ["scene_01", "scene_02"]
        assert all(job["status"] == "manual_generation_required" for job in ai_jobs)
        assert all(job["provider_order"][:2] == ["pixverse", "pika"] for job in ai_jobs)
        assert all(job["free_tier_guardrails"]["do_not_buy_credits"] is True for job in ai_jobs)
        assert all(job["duration_seconds"] <= 5 for job in ai_jobs)
        assert all("no readable text" in job["negative_prompt"].lower() for job in ai_jobs)
>       assert all("local procedural" not in job["prompt"].lower() for job in ai_jobs)
E       assert False
E        +  where False = all(<generator object test_free_ai_video_handoff_creates_manual_jobs_for_realistic_clip_scenes_only.<locals>.<genexpr> at 0x724d5192e340>)

tests/test_free_ai_video_providers.py:55: AssertionError
=========================== short test summary info ============================
FAILED tests/test_free_ai_video_providers.py::test_free_ai_video_handoff_creates_manual_jobs_for_realistic_clip_scenes_only
1 failed in 0.06s


patch

def _free_ai_prompt(job: dict[str, Any]) -> str:
    intent = job.get("source_prompt", "")
    for marker in [
        "Use local procedural animation/parallax rather than paid AI-video credits; keep captions renderer-overlay only.",
        "Use local procedural animation/parallax rather than paid AI-video credits",
    ]:
        intent = intent.replace(marker, "")
    intent = intent.replace("Vertical 9:16 cinematic-looking local motion scene,", "")
    intent = " ".join(intent.split())
    return (
        f"Vertical 9:16 realistic cinematic short video. {intent} "
        "No captions, no readable text, no logos, no watermarks. Leave clean negative space in the lower third for captions. "
        "The clip should feel like real b-roll for a mechanism explainer, not a slideshow."
    )

def _free_ai_prompt(job: dict[str, Any]) -> str:
    return (
        f"Vertical 9:16 realistic cinematic short video, {job['source_prompt']} "
        "No captions, no readable text, no logos, no watermarks. Leave clean negative space in the lower third for captions. "
        "The clip should feel like real b-roll for a mechanism explainer, not a slideshow."
    )


--- a//home/agent/jarvis_runtime/AutoShortsBot/autoshorts/free_ai_video_providers.py
+++ b//home/agent/jarvis_runtime/AutoShortsBot/autoshorts/free_ai_video_providers.py
@@ -150,8 +150,16 @@

 def _free_ai_prompt(job: dict[str, Any]) -> str:
+    intent = job.get("source_prompt", "")
+    for marker in [
+        "Use local procedural animation/parallax rather than paid AI-video credits; keep captions renderer-overlay only.",
+        "Use local procedural animation/parallax rather than paid AI-video credits",
+    ]:
+        intent = intent.replace(marker, "")
+    intent = intent.replace("Vertical 9:16 cinematic-looking local motion scene,", "")
+    intent = " ".join(intent.split())
     return (
-        f"Vertical 9:16 realistic cinematic short video, {job['source_prompt']} "
+        f"Vertical 9:16 realistic cinematic short video. {intent} "
         "No captions, no readable text, no logos, no watermarks. Leave clean negative space in the lower third for captions. "
         "The clip should feel like real b-roll for a mechanism explainer, not a slideshow."
     )


terminal

pytest tests/test_free_ai_video_providers.py -q && python scripts/generate_free_ai_video_handoffs.py --jobs data/free_production_jobs/mechanism_pilots/hidden-money-systems-warum-ein-billiges-auto-teuer-sein-kann.json --out data/free_ai_video_handoffs/mechanism_pilots


Output:
....                                                                     [100%]
4 passed in 0.04s
Generated 1 free AI video handoff specs in data/free_ai_video_handoffs/mechanism_pilots
data/free_ai_video_handoffs/mechanism_pilots/hidden-money-systems-warum-ein-billiges-auto-teuer-sein-kann.json


patch

--- a//home/agent/jarvis_runtime/AutoShortsBot/.gitignore
+++ b//home/agent/jarvis_runtime/AutoShortsBot/.gitignore
@@ -33,3 +33,4 @@
 data/performance/*.local.json
 data/generated/
 data/local_motion_renders/
+data/imported_ai_clips/

No linter for  files


Explanation:
**Considering skill updates**

I feel like I might need to think about updating my skills later. I should definitely run some full tests and check on everything to see where I stand. It's always good to ensure I'm up to date and functioning at my best. Keeping my abilities sharp will help me serve the user better, so I'll keep that in mind as I move forward!


terminal

Output:
.......................................................                  [100%]
55 passed in 3.25s


Output:
.gitignore | 1 +
 1 file changed, 1 insertion(+)
 M .gitignore
?? autoshorts/free_ai_video_providers.py
?? autoshorts/review_package.py
?? data/free_ai_video_handoffs/
?? data/telegram_reviews/
?? scripts/generate_free_ai_video_handoffs.py
?? scripts/generate_telegram_review_packages.py
?? tests/test_free_ai_video_providers.py
?? tests/test_review_package.py


    49|  "ai_video_jobs": [
    50|    {
    51|      "job_id": "scene_01_free_ai_video_handoff",
    52|      "scene_id": "scene_01",
    53|      "asset_mode": "cinematic_ai_video",
    54|      "status": "manual_generation_required",
    55|      "duration_seconds": 1.4,
    56|      "aspect_ratio": "9:16",
    57|      "preferred_resolution": "480p_or_best_free_available",
    58|      "provider_order": [
    59|        "pixverse",
    60|        "pika",
    61|        "capcut",
    62|        "hailuo"
    63|      ],
    64|      "providers": [
    65|        {
    66|          "provider": "pixverse",
    67|          "display_name": "PixVerse",
    68|          "url": "https://app.pixverse.ai/",
    69|          "free_tier": {
    70|            "daily_refresh_credits": 90,
    71|            "signup_required": true,
    72|            "best_use": "realistic text/image-to-video short clips"
    73|          },
    74|          "risks": [
    75|            "terms and quotas can change",
    76|            "manual account/login required",
    77|            "possible watermark depending export path"
    78|          ]
    79|        },
    80|        {
    81|          "provider": "pika",
    82|          "display_name": "Pika",
    83|          "url": "https://pika.art/",
    84|          "free_tier": {
    85|            "monthly_credits": 80,
    86|            "max_resolution": "480p",
    87|            "text_to_video_5s_credits": 12,
    88|            "watermark_free_claimed": true,
    89|            "commercial_use_claimed": true,
    90|            "signup_required": true
    91|          },
    92|          "risks": [
    93|            "low 480p free resolution",
    94|            "monthly quota is small",
    95|            "manual account/login required"
    96|          ]
    97|        },
    98|        {
    99|          "provider": "capcut",
   100|          "display_name": "CapCut AI Video Maker",
   101|          "url": "https://www.capcut.com/tools/ai-video-generator",
   102|          "free_tier": {
   103|            "hd_export_claimed": true,
   104|            "credit_amount_publicly_clear": false,
   105|            "best_use": "editorial assembly, templates, captions, quick drafts",
   106|            "signup_required": true
   107|          },
   108|          "risks": [
   109|            "free quota not clearly exposed on public page",
   110|            "may upsell Pro assets",
   111|            "manual export required"
   112|          ]
   113|        },
   114|        {
   115|          "provider": "hailuo",
   116|          "display_name": "Hailuo AI",
   117|          "url": "https://hailuoai.video/",
   118|          "free_tier": {
   119|            "default_visible_generation_cost_credits": 25,
   120|            "signup_required": true,
   121|            "use_only_existing_free_credits": true
   122|          },
   123|          "risks": [
   124|            "do not buy credits",
   125|            "free quota may vary",
   126|            "user explicitly wants no paid Hailuo credits"
   127|          ]
   128|        }
   129|      ],
   130|      "prompt": "Vertical 9:16 realistic cinematic short video. a realistic creator at a desk late evening, laptop open to an AI chat, thoughtful but in control, hands moving between keyboard and notebook. Mood: focused, modern, high-retention social video, dramatic lighting simulated with gradients and shadows. Scene intent: 3D car x-ray with price tag layers and risk meters freezes mid-action with warning signal. Camera: slow handheld push-in, subtle parallax, natural micro-movements. No captions, no readable text, no logos, no watermarks. Leave clean negative space in the lower third for captions. The clip should feel like real b-roll for a mechanism explainer, not a slideshow.",
   131|      "negative_prompt": "no readable text, no subtitles, no logos, no watermarks, no distorted hands, no fake UI text, no slideshow, no static image, no uncanny faces",
   132|      "overlay_text": "Dieser Occasion-Käufer denkt, er spart 4'000 Franken.",
   133|      "free_tier_guardrails": {
   134|        "do_not_buy_credits": true,
   135|        "use_only_free_daily_or_monthly_quota": true,
   136|        "avoid_pro_templates_or_paid_assets": true,
   137|        "export_without_baked_captions": true,
   138|        "final_captions_added_locally": true
   139|      },
   140|      "manual_steps": [
   141|        "Open the first available provider in provider_order.",
   142|        "Use text-to-video or image-to-video with the prompt below; choose vertical 9:16 if available.",
   143|        "Set duration to the requested scene duration or the nearest free option, usually 5s.",
   144|        "Do not buy credits, subscribe, or select paid-only models/templates.",
   145|        "Download the clip, then place it under data/imported_ai_clips/<video_id>/<scene_id>.mp4 for local assembly."
   146|      ],
   147|      "expected_clip_path": "data/imported_ai_clips/{video_id}/scene_01.mp4"
   148|    },
   149|    {
   150|      "job_id": "scene_02_free_ai_video_handoff",
   151|      "scene_id": "scene_02",
   152|      "asset_mode": "cinematic_ai_video",
   153|      "status": "manual_generation_required",
   154|      "duration_seconds": 3.6,
   155|      "aspect_ratio": "9:16",
   156|      "preferred_resolution": "480p_or_best_free_available",
   157|      "provider_order": [
   158|        "pixverse",
   159|

Use offset=159 to continue reading (showing 49-158 of 275 lines)


Explanation:
**Considering git commits and .gitignore**

I'm thinking about the diff, which only shows changes in the gitignore because untracked files aren't listed. I should commit the new files, especially if I'm also updating my skills with an external provider. It's a good idea to check if `.gitignore` includes `data/free_ai_video_handoffs` since that JSON artifact should be committed. I'll need to ensure I handle credentials properly to push. I want to add and commit everything to avoid untracked files in my review.

social-media-shorts-growth-engine

For this AutoShortsBot/Retention-Studio workflow, prefer a free-first renderer path before any paid video provider: `free_production_jobs → local_motion_renderer → FFmpeg MP4`. The local renderer should use Pillow/FFmpeg procedural motion, mechanism layers, kinetic captions, and generated metadata; preserve exact scene durations from render manifests, exclude text-only LLM refinement jobs from rendering, and keep generated local renders out of git (`data/local_motion_renders/`). NVIDIA/build.nvidia.com LLMs are optional text-refinement helpers only, not video generation.

If the user wants more realistic footage without spending money, use a hybrid free-tier handoff rather than pretending local procedural graphics are realistic: `free_production_jobs → free_ai_video_handoff → manual browser generation in free-tier tools (PixVerse/Pika/CapCut/Hailuo only with existing free credits) → import clips under data/imported_ai_clips/ → local captions/mechanism layers/FFmpeg assembly`. Guardrails: no paid top-ups, no subscriptions, avoid Pro templates, no baked captions/logos/watermarks where possible, and keep imported clips out of git.

## Pitfalls

For this AutoShortsBot/Retention-Studio workflow, prefer a free-first renderer path before any paid video provider: `free_production_jobs → local_motion_renderer → FFmpeg MP4`. The local renderer should use Pillow/FFmpeg procedural motion, mechanism layers, kinetic captions, and generated metadata; preserve exact scene durations from render manifests, exclude text-only LLM refinement jobs from rendering, and keep generated local renders out of git (`data/local_motion_renders/`). NVIDIA/build.nvidia.com LLMs are optional text-refinement helpers only, not video generation.

## Pitfalls


Patched SKILL.md in skill 'social-media-shorts-growth-engine' (1 replacement).


terminal

git add .gitignore autoshorts/free_ai_video_providers.py scripts/generate_free_ai_video_handoffs.py tests/test_free_ai_video_providers.py data/free_ai_video_handoffs/mechanism_pilots/hidden-money-systems-warum-ein-billiges-auto-teuer-sein-kann.json && git diff --cached --check && git diff --cached | grep -iE 'api[_-]?key|token|secret|password|credential' || true && git commit -m "feat: add free ai video handoff specs"


Output:
[feat/initial-growth-engine 9f41a9f] feat: add free ai video handoff specs
 5 files changed, 604 insertions(+)
 create mode 100644 autoshorts/free_ai_video_providers.py
 create mode 100644 data/free_ai_video_handoffs/mechanism_pilots/hidden-money-systems-warum-ein-billiges-auto-teuer-sein-kann.json
 create mode 100644 scripts/generate_free_ai_video_handoffs.py
 create mode 100644 tests/test_free_ai_video_providers.py


git status --short && git log --oneline -4


Output:
.......................................................                  [100%]
55 passed in 3.55s


Output:
?? autoshorts/review_package.py
?? data/telegram_reviews/
?? scripts/generate_telegram_review_packages.py
?? tests/test_review_package.py
9f41a9f feat: add free ai video handoff specs
ff5df62 feat: add free local motion renderer
b54a903 feat: add free production job specs
4d1e8f8 feat: generate mechanism render manifests


Output: fatal: could not read Username for 'https://github.com': Kein passendes Gerät bzw. keine passende Adresse gefunden


Ja, Sir — exakt: **das aktuelle MP4 ist noch Konzept/Animatic**, kein fertiges realistisches Video.

Es zeigt Timing, Layer, Captions und Mechanik. Für ein „einigermaßen realistisches“ Endprodukt brauchen wir tatsächlich **KI-generierte Videoclips** als B-Roll/Scene-Clips — aber eben nur über **Free Tiers**, nicht über bezahlte Credits.

Ich habe recherchiert und den Workflow entsprechend weitergebaut.

## Recherche: gratis / free-tier KI-Video-Tools

## 1. PixVerse

Gefunden auf:

```text
https://app.pixverse.ai/
```

Die App zeigt aktuell:

```text
90
Täglich aktualisieren
Jetzt registrieren und kostenlose Credits erhalten
```

Einschätzung:

- sehr interessant als **Primary Free-Tier Candidate**
- offenbar tägliche Free-Credits
- geeignet für realistische 9:16 Short-Clips
- manuelle Browser-Nutzung/Login nötig
- keine paid Top-ups erlaubt

Priorität:

```text
#1 PixVerse
```

## 2. Pika

Gefunden auf offizieller Pricing-Seite:

```text
https://pika.art/pricing
```

Free Basic:

```text
$0
80 monthly video credits
Access to Pika 2.5, 480p only
Download videos with no watermark
Commercial use
```

Für Text/Image-to-Video laut Pricing:

```text
480p / 5s = 12 credits Free
```

Einschätzung:

- sehr brauchbarer Fallback
- Free-Output nur 480p, aber für Shorts mit lokalem Upscale/Compositing akzeptabel
- no-watermark + commercial-use Claim ist stark
- monatlich begrenzter als PixVerse

Priorität:

```text
#2 Pika
```

## 3. CapCut AI Video Maker

Gefunden auf:

```text
https://www.capcut.com/tools/ai-video-generator
```

CapCut sagt u.a.:

```text
Free AI Video Generator
Export the finished video in HD quality for free
```

Einschätzung:

- gut für manuelle Politur, Templates, Captions, Schnitt
- Free-Quota öffentlich weniger klar
- CapCut kann schnell in Pro-Assets/Upsell laufen
- trotzdem nützlich als kostenloser Editor-/Assembler-Kandidat

Priorität:

```text
#3 CapCut
```

## 4. Hailuo

Gefunden auf:

```text
https://hailuoai.video/
```

Die Seite zeigt einen Generator mit:

```text
768p
6s
25 credits
```

Einschätzung:

- nur verwenden, falls kostenlose vorhandene Credits da sind
- keine Käufe, keine Top-ups
- weil du Hailuo explizit als „kein Geld für Credits“ genannt hast: nur Free-Quota-Fallback, nicht Hauptpfad

Priorität:

```text
#4 Hailuo, nur falls Free-Credits verfügbar
```

## Nicht als Free-First geeignet

Aktuell nicht als Primary Free Workflow:

```text
Runway
Luma
Kling
Veo
Sora API
```

Grund:

- entweder paid-first
- Free-Kontingent unklar/klein
- API/Automation meist bezahlt
- oder nicht stabil genug für unseren kostenlosen Produktionspfad

## Neue Workflow-Entscheidung

Der Zielworkflow ist jetzt:

```text
1. Hermes/ChatGPT/NVIDIA LLM:
   Shot plan, prompts, captions, scene specs

2. Free AI Video Provider:
   PixVerse / Pika / CapCut / Hailuo-Free
   erzeugen realistische kurze Clips manuell im Browser

3. Import:
   Clips lokal speichern unter data/imported_ai_clips/...

4. Local Renderer:
   Mechanism-Layer, Captions, SFX, Timing, Assembly

5. FFmpeg:
   finales 9:16 MP4
```

Das heißt:
**Die realistischen Teile kommen aus kostenlosen KI-Video-Free-Tiers.**
**Die System-Erklärung, Captions und Montage bleiben lokal kontrolliert.**

Das ist der richtige Hybrid. Nur lokal wird zu sehr Konzeptgrafik. Nur KI-Video wird generischer Slop. Zusammen wird es brauchbar. Welch seltene Gelegenheit, dass zwei halbe Lösungen zusammen eine ganze ergeben.

## Im Repo neu gebaut

Neue Komponente:

```text
autoshorts/free_ai_video_providers.py
```

Neues CLI:

```text
scripts/generate_free_ai_video_handoffs.py
```

Neue Tests:

```text
tests/test_free_ai_video_providers.py
```

Neues Artefakt:

```text
data/free_ai_video_handoffs/mechanism_pilots/
  hidden-money-systems-warum-ein-billiges-auto-teuer-sein-kann.json
```

## Was dieses Handoff enthält

Für den Pilot:

```text
Warum ein billiges Auto teuer sein kann
```

werden jetzt **2 realistische AI-Video-Jobs** erzeugt:

```text
scene_01 → realistische KI-Video-Szene
scene_02 → realistische KI-Video-Szene
```

Provider-Reihenfolge:

```text
1. PixVerse
2. Pika
3. CapCut
4. Hailuo nur Free-Credits
```

Guardrails:

```text
paid_topups_allowed: false
paid_subscriptions_allowed: false
do_not_buy_credits: true
avoid_pro_templates_or_paid_assets: true
export_without_baked_captions: true
final_captions_added_locally: true
```

Die Mechanismus-Szenen bleiben vorerst lokal:

```text
scene_03 → local mechanism animation
scene_04 → local mechanism animation
scene_05 → local kinetic text
```

Warum? Weil KI-Video-Tools bei präzisen Layer-Erklärungen oft halluzinieren. Realistische Clips: ja. Exakte Erklärgrafik: lieber lokal kontrolliert.

## Beispiel Prompt für Scene 1

Das Handoff erzeugt provider-ready Prompts wie:

```text
Vertical 9:16 realistic cinematic short video.
A realistic creator at a desk late evening, laptop open to an AI chat,
thoughtful but in control, hands moving between keyboard and notebook.
Mood: focused, modern, high-retention social video.
Scene intent: 3D car x-ray with price tag layers and risk meters freezes mid-action with warning signal.
Camera: slow handheld push-in, subtle parallax, natural micro-movements.
No captions, no readable text, no logos, no watermarks.
Leave clean negative space in the lower third for captions.
The clip should feel like real b-roll for a mechanism explainer, not a slideshow.
```

Wichtig: Captions kommen später lokal drauf. Kein KI-Gibberish im Bild.

## Tests

Full suite:

```text
55 passed in 3.55s
```

## Git

Neuer lokaler Commit:

```text
9f41a9f feat: add free ai video handoff specs
```

Davor liegt noch:

```text
ff5df62 feat: add free local motion renderer
```

Push ist weiterhin blockiert, weil GitHub-Credentials in dieser Umgebung fehlen:

```text
fatal: could not read Username for 'https://github.com'
```

## Antwort auf deine Kernfrage

Ja: **Das Endprodukt soll realistischer werden.**

Was du aktuell gesehen hast, ist:

```text
Animatic / Motion Concept / Local Placeholder
```

Nicht das finale Video.

Der nächste Produktionsschritt ist jetzt konkret:

```text
PixVerse oder Pika öffnen
→ scene_01 + scene_02 mit Free Credits generieren
→ Clips herunterladen
→ lokal importieren
→ Local Renderer ersetzt Placeholder durch echte KI-Clips
→ Mechanism Layers + Captions + SFX darüber
→ finales MP4
```

## Nächster sinnvoller Schritt

Ich würde als Nächstes bauen:

```text
Imported AI Clip Assembler
```

Damit das System automatisch prüft:

```text
data/imported_ai_clips/<video_id>/scene_01.mp4
data/imported_ai_clips/<video_id>/scene_02.mp4
```

Wenn Clips vorhanden sind:

```text
echte AI-Clips verwenden
```

Wenn nicht:

```text
local placeholder verwenden
```

Dann können wir Free-Tier-Clips manuell aus PixVerse/Pika holen und sofort in denselben Renderprozess einbauen.


Explanation:
**Assessing ChatGPT Pro features**

I need to gather current facts about ChatGPT Pro features, so I'll check for the latest info. The task indicates I should continue building the imported assembler, which requires relevant skills in social and TDD that I might already have. I might also want to search for video generation related to ChatGPT Pro. Using a web search for OpenAI pricing and help could be beneficial as well, along with coding what I find.

todo

Aktuelle ChatGPT Pro Video-/Sora-Leistungen prüfen

TDD für Imported AI Clip Assembler schreiben und RED verifizieren

Imported AI Clip Assembler implementieren

Tests/Artefakte/Git-Status verifizieren


Tests/Artefakte/Git-Status verifizieren


ChatGPT-Pläne | Free, Go, Plus, Pro, Business und Enterprise

Running WITHOUT residential proxies. Bot detection may be more aggressive. Consider upgrading Browserbase plan for proxy support.

- generic
  - link "ChatGPT-Blüten-Logo" [ref=e1]
    - image "ChatGPT-Blüten-Logo"
  - navigation
    - list
      - listitem [level=1]
        - link "Über OpenAI" [ref=e61]
      - listitem [level=1]
        - button "Funktionen" [expanded=false, ref=e63]
      - listitem [level=1]
        - button "Lernen" [expanded=false, ref=e64]
      - listitem [level=1]
        - generic
          - link "Codex" [expanded=false, ref=e65]
      - listitem [level=1]
        - link "Business" [expanded=false, ref=e66]
      - listitem [level=1]
        - link "Preisgestaltung" [expanded=false, ref=e67]
      - listitem [level=1]
        - link "Herunterladen" [ref=e62]
  - button "Anmelden" [ref=e2]
  - button "Kostenlos registrieren" [ref=e3]
- generic
  - heading "Preisgestaltung" [level=1, ref=e4]
- generic
  - heading "Free" [level=3, ref=e22]
  - paragraph
  - StaticText "/ Monat"
  - link "Free holen" [ref=e23]
  - list
  - paragraph
    - link "Abrechnungshilfe" [ref=e44]
- generic
  - heading "Go" [level=3, ref=e24]
  - paragraph
  - StaticText "/ Monat"
  - link "Go holen" [ref=e25]
  - StaticText "Alles aus Free sowie:"
  - list
  - paragraph
    - link "Mehr erfahren" [ref=e45]
- generic
  - heading "Plus" [level=3, ref=e26]
  - paragraph
  - StaticText "/ Monat"
  - link "Plus holen" [ref=e27]
  - StaticText "Alles aus Go und:"
  - list
  - paragraph
    - link "Es gelten Nutzungsobergrenzen" [ref=e46]
- generic
  - StaticText "Das Doppelte deiner normalen Codex-Nutzung auf der Tarifstufe / Monat bis zum 31. Mai 2026."
  - heading "Pro" [level=3, ref=e28]
  - paragraph
  - StaticText "Ab"
  - StaticText "/ Monat"
  - link "Pro holen" [ref=e29]
  - StaticText "Alles aus Plus sowie:"
  - list
  - paragraph
    - link "Mehr erfahren" [ref=e47]
- article
  - heading "Unternehmen Codex" [level=3, ref=e30]
  - link "Jetzt loslegen" [ref=e48]
- article
  - heading "Unternehmen ChatGPT und Codex" [level=3, ref=e31]
  - paragraph
  - StaticText "/ Benutzer / Monat"
  - link "Loslegen" [ref=e49]
  - StaticText "Was enthalten ist:"
  - list
  - generic
    - link "Mehr erfahren" [ref=e50]
- article
  - heading "Enterprise" [level=3, ref=e32]
    - StaticText "Enterprise"
  - paragraph
    - StaticText "KI, Sicherheit und Support der Enterprise-Klasse für große Unternehmen"
  - StaticText "Individuelle Preisgestaltung"
  - StaticText "Wende dich an unser Vertriebsteam, um die Preise zu besprechen."
  - link "Vertrieb kontaktieren" [ref=e51]
    - StaticText "Vertrieb kontaktieren"
  - StaticText "Was enthalten ist:"
  - list
    - listitem [level=1]
      - paragraph
    - listitem [level=1]
      - paragraph
    - listitem [level=1]
      - paragraph
        - link "Mehr erfahren" [ref=e68]
- generic
  - heading "Im Einsatz bei Teams von" [level=4, ref=e33]
- generic
  - heading "Funktionen der Pläne vergleichen" [level=4, ref=e52]
- generic
  - generic
    - generic
      - paragraph
      - generic
        - link "Free holen" [ref=e75]
      - paragraph
      - generic
        - link "Go holen" [ref=e76]
      - paragraph
      - generic
        - link "Plus holen" [ref=e77]
      - paragraph
      - generic
        - link "Pro holen" [ref=e78]
      - paragraph
      - generic
        - link "Business holen" [ref=e79]
      - paragraph
      - generic
        - link "Vertrieb kontaktieren" [ref=e158]
    - generic
      - heading "Essentials" [level=3, ref=e69]
      - generic
        - heading "Nachrichten und Interaktionen" [level=6, ref=e80]
      - generic
        - heading "Chatverlauf" [level=6, ref=e81]
      - generic
        - heading "Zugriff per Web, iOS, Android" [level=6, ref=e82]
    - generic
      - heading "Modelle" [level=3, ref=e70]
      - generic
        - heading "GPT-5.5 Instant" [level=6, ref=e83]
      - generic
        - heading "GPT-5.5 Thinking" [level=6, ref=e84]
      - generic
        - heading "GPT-5.5 Pro" [level=6, ref=e85]
      - generic
        - heading "GPT-5 Thinking Mini" [level=6, ref=e86]
      - generic
        - heading "Legacy-Modelle" [level=6, ref=e87]
      - generic
        - heading "Reaktionszeiten" [level=6, ref=e88]
      - generic
        - heading "GPT Instant – Gesamt-Kontextfenster" [level=6, ref=e89]
      - generic
        - heading "GPT Instant – maximale Eingabe***" [level=6, ref=e90]
      - generic
        - heading "GPT Reasoning – Gesamt-Kontextfenster" [level=6, ref=e91]
      - generic
        - heading "GPT Reasoning – maximale Eingabe***" [level=6, ref=e92]
      - generic
        - heading "Regelmäßige Updates zu Qualität und Tempo bei Modellverbesserungen" [level=6, ref=e93]
    - generic
      - heading "Funktionen" [level=3, ref=e71]
      - generic
        - heading "Sprachchat" [level=6, ref=e94]
      - generic
        - heading "Stimme und Video" [level=6, ref=e95]
      - generic
        - heading "Apps" [level=6, ref=e96]
      - generic
        - heading "Codex" [level=6, ref=e97]
      - generic
        - heading "Skills-Beta" [level=6, ref=e98]
      - generic
        - heading "Erinnerung" [level=6, ref=e99]
      - generic
        - heading "Erinnerung mit vergangenen Chats" [level=6, ref=e100]
      - generic
        - heading "Erinnerungsquellen" [level=6, ref=e101]
      - generic
        - heading "Suche" [level=6, ref=e102]
      - generic
        - heading "Canvas" [level=6, ref=e103]
      - generic
        - heading "Codeänderungen auf macOS" [level=6, ref=e104]
      - generic
        - heading "Projekte" [level=6, ref=e105]
      - generic
        - heading "Gemeinsame Projekte" [level=6, ref=e106]
      - generic
        - heading "Aufgaben" [level=6, ref=e107]
      - generic
        - heading "Datenanalyse" [level=6, ref=e108]
      - generic
        - heading "Vision" [level=6, ref=e109]
      - generic
        - heading "Apps, die mit internen Tools verbunden sind" [level=6, ref=e110]
      - generic
        - heading "Interaktive Apps" [level=6, ref=e111]
      - generic
        - heading "App-Verzeichnis" [level=6, ref=e112]
      - generic
        - heading "Erweiterungen für Excel und Google Sheets" [level=6, ref=e113]
      - generic
        - heading "Unternehmenswissen" [level=6, ref=e114]
      - generic
        - heading "Entwicklermodus (Beta)" [level=6, ref=e115]
      - generic
        - heading "ChatGPT-Aufnahmemodus" [level=6, ref=e116]
      - generic
        - heading "Datei-Uploads" [level=6, ref=e117]
      - generic
        - heading "GPTs entdecken und verwenden" [level=6, ref=e118]
      - generic
        - heading "GPTs erstellen und teilen" [level=6, ref=e119]
      - generic
        - heading "GPTs mit deinem Workspace teilen" [level=6, ref=e120]
      - generic
        - heading "Möglichkeit zum Testen neuer Funktionen" [level=6, ref=e121]
      - generic
        - heading "Bildgenerierung" [level=6, ref=e122]
      - generic
        - heading "Bildgenerierung mit Thinking" [level=6, ref=e123]
      - generic
        - heading "Interaktive Tabellen und Diagramme" [level=6, ref=e124]
      - generic
        - heading "Deep Research" [level=6, ref=e125]
      - generic
        - heading "Apps für Deep Research" [level=6, ref=e126]
      - generic
        - heading "Lernmodus" [level=6, ref=e127]
      - generic
        - heading "ChatGPT Pulse" [level=6, ref=e128]
    - generic
      - heading "Datenschutz" [level=3, ref=e72]
      - generic
        - heading "Inhalte werden zum Training unserer Modelle verwendet" [level=6, ref=e129]
    - generic
      - heading "Sicherheit und Verwaltung" [level=3, ref=e73]
      - generic
        - heading "SAML SSO" [level=6, ref=e130]
      - generic
        - heading "Einheitliche Abrechnung" [level=6, ref=e131]
      - generic
        - heading "Dedizierter Workspace" [level=6, ref=e132]
      - generic
        - heading "GPT-Analytics und -Verwaltung" [level=6, ref=e133]
      - generic

[... 97 more lines truncated, use browser_snapshot for full content]


- link "OpenAI" [ref=e1]
- generic
  - button "Language" [expanded=false, ref=e6]
- link "Login" [ref=e2]
- generic
  - textbox "Search for articles..." [ref=e7]
- heading "UH OH. THAT PAGE DOESN'T EXIST." [level=1, ref=e3]
- link "Go back home" [ref=e4]
- paragraph
  - link "logging in" [ref=e8]
- contentinfo
  - image "OpenAI logo"
  - navigation
    - link "ChatGPT" [ref=e11]
    - link "API" [ref=e12]
    - link "Service Status" [ref=e13]
    - button "Open cookie preferences dialog" [ref=e14]
- button "Open chat" [ref=e5]
- generic
  - paragraph
  - paragraph
    - link "Cookie Policy" [ref=e15]
  - button "Reject all cookies" [ref=e9]
  - button "Accept all cookies" [ref=e10]


terminal

Output:
?? autoshorts/review_package.py
?? data/telegram_reviews/
?? scripts/generate_telegram_review_packages.py
?? tests/test_review_package.py
9f41a9f feat: add free ai video handoff specs
ff5df62 feat: add free local motion renderer
b54a903 feat: add free production job specs


We use cookies and similar technologies to deliver, maintain, improve our services and for security purposes.