← Back to home@NL859

dsh-papercut

No description

Stars
0
Language
JavaScript
Created
Oct 20, 2026
Updated
Oct 20, 2026

Introduction

dsh-papercut

Papercut explainer films, end to end — natively on Windows, no WSL.

A DeepSeek Harness plugin that turns one sentence of idea into a finished vertical (9:16) cut-paper explainer: script → local text-to-speech → word-level timed captions → Remotion render → QA contact sheets.

$ dsh --profile papercut
> 做一个关于剪纸的 25 秒短片
   → papercut_plan → papercut_voice → papercut_storyboard → papercut_render → papercut_qa
   → episodes/01-jianzhi/papercut/out/jianzhi-papercut.mp4   (1080×1920, 27.5 s, −14.7 LUFS)

demo

Why this exists

The upstream papercut-explainer library is a beautiful Remotion kit, but its toolchain is 27 bash and Python scripts written for macOS (Apple rsync, mlx-whisper, Homebrew ffmpeg, readlink -f). Everything that touches the OS has been rewritten here in Node, so the whole pipeline runs on a stock Windows machine:

PieceUpstreamHere
Choreographyrender.py + render.shsrc/node/render.js — one bundle, per-scene ProRes HQ segments, content-keyed cache
Audio mixmix.py (numpy)ffmpeg sidechaincompress + alimiter + loudnorm
Voicenarrate.py (qwen-tts)local IndexTTS-2.5 bridge over HTTP
Word timingasr.py (mlx-whisper)openai-whisper + forced alignment against the known script (py/align.py)
Chromiumsystem Chromethe Edge that ships with Windows
ffmpeg/ffprobebrew installbundled static binaries from npm

No WSL. No Homebrew. No ffmpeg on PATH. Python is only needed for two leaf scripts (forced alignment, CJK font subsetting), and the plugin calls the interpreter you point it at.

The six tools

ToolArgumentsWhat it does
papercut_list—Existing episodes, their duration, scene count and whether a render exists
papercut_planidea, slug?, comp?, lines?Scaffolds the episode and returns the 7-line script brief
papercut_storyboardslugCamera / cut / SFX table derived from the real frame plan
papercut_voiceslug, engine?, force?, model?, keepWarm?Local TTS per line, silence trim, forced word alignment, voiceover.wav + captions + plan
papercut_renderslug, force?, workers?, conc?Segmented Remotion render, then one x264 pass with the audio bed
papercut_qaslug, every?, scale?Contact sheets every N frames, numbered, for visual review

Everything else — composing scenes, writing the hook, choosing assets — is the agent's job, guided by nine skills.

The nine skills

Installed into <DSH_HOME>/skills by npm run skills, so DSH picks them up live:

papercut-explainer (router / end-to-end) · papercut-strategy · papercut-hook · papercut-script · papercut-storyboard · papercut-build · papercut-voice · papercut-qa · papercut-setup (toolchain doctor for this machine).

Say "make a papercut reel about X" and the router takes it from there.

Install

# 1. the plugin
dsh plugin --profile papercut add "link:D:/path/to/dsh-papercut"
#    or, from npm:  dsh plugin --profile papercut add dsh-papercut

# 2. the skills (idempotent)
cd D:/path/to/dsh-papercut
node scripts/install-skills.mjs

# 3. check the toolchain
#    in DSH: "check my papercut install"   -> runs the papercut-setup doctor

What the workspace must look like

dsh-papercut drives a workspace directory holding the upstream library and the render app. The plugin finds it by walking up from its own package folder (and then from the current working directory) looking for app/node_modules + src/papercut-explainer-main/library, so a linked checkout and an npm-installed copy both work without configuration. Point it elsewhere with root in cordis.patch.yml, or the PAPERCUT_ROOT env var.

<root>/
  app/                          Remotion project (node_modules with remotion, ffmpeg-static, ...)
  src/papercut-explainer-main/  the upstream MIT library (kit, audio engine, scenes template)
  episodes/<slug>/              one folder per film
  tools/                        the Node CLI used during development

Use papercut-setup (or node tools/bin/papercut.mjs list) to see what is missing.

Requirements

  • Windows 10/11 with Edge (any modern Edge has the headless Chromium Remotion needs)
  • Node 22+
  • A Python 3.11 virtualenv with openai-whisper + fonttools — only for the aligner and the CJK font subsetter. Point at it with python: in the plugin config.
  • Optional: a local TTS HTTP bridge on 127.0.0.1:7865 (IndexTTS-2.5). The plugin probes /health and tells you how to start it; it never spawns the model itself, because that would hold VRAM hostage.

Configuration

cordis.patch.yml in this package:

- insert:
    - id: papercut
      name: dsh-papercut
      config:
        root: ''                 # workspace path, else PAPERCUT_ROOT, else the built-in default
        ttsUrl: http://127.0.0.1:7865
        python: D:/tts/index-tts/.venv/Scripts/python.exe
        chromePath: C:/Program Files (x86)/Microsoft/Edge/Application/msedge.exe
        defaultModel: small      # whisper model for forced alignment
        debug: false

Verified numbers

First film, episodes/01-jianzhi (1080×1920, 30 fps, 824 frames):

Voice + alignment7 lines, 24.1 s of speech, ~4 s synth + ~3.3 s align per line
Render (cold)55 s — bundle 2 s, 824 frames in 3 parallel workers, final encode 9 s
Render (one scene changed)20 s — cache hits on the other six segments
OutputH.264 High, yuv420p, bt709, 8.6 Mbps, −14.7 LUFS, −1.0 dBTP, 0 decode errors

License

MIT. The bundled story kit comes from papercut-explainer (MIT), also credited in NOTICE.