@kenkaiiii/gg-editor 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +453 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +173 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/ass.d.ts +75 -0
- package/dist/core/ass.d.ts.map +1 -0
- package/dist/core/ass.js +128 -0
- package/dist/core/ass.js.map +1 -0
- package/dist/core/ass.test.d.ts +2 -0
- package/dist/core/ass.test.d.ts.map +1 -0
- package/dist/core/ass.test.js +112 -0
- package/dist/core/ass.test.js.map +1 -0
- package/dist/core/audio-cleanup.d.ts +16 -0
- package/dist/core/audio-cleanup.d.ts.map +1 -0
- package/dist/core/audio-cleanup.js +79 -0
- package/dist/core/audio-cleanup.js.map +1 -0
- package/dist/core/audio-cleanup.test.d.ts +2 -0
- package/dist/core/audio-cleanup.test.d.ts.map +1 -0
- package/dist/core/audio-cleanup.test.js +41 -0
- package/dist/core/audio-cleanup.test.js.map +1 -0
- package/dist/core/audio-mix.d.ts +89 -0
- package/dist/core/audio-mix.d.ts.map +1 -0
- package/dist/core/audio-mix.js +156 -0
- package/dist/core/audio-mix.js.map +1 -0
- package/dist/core/audio-mix.test.d.ts +2 -0
- package/dist/core/audio-mix.test.d.ts.map +1 -0
- package/dist/core/audio-mix.test.js +91 -0
- package/dist/core/audio-mix.test.js.map +1 -0
- package/dist/core/auth/anthropic.d.ts +4 -0
- package/dist/core/auth/anthropic.d.ts.map +1 -0
- package/dist/core/auth/anthropic.js +78 -0
- package/dist/core/auth/anthropic.js.map +1 -0
- package/dist/core/auth/index.d.ts +7 -0
- package/dist/core/auth/index.d.ts.map +1 -0
- package/dist/core/auth/index.js +6 -0
- package/dist/core/auth/index.js.map +1 -0
- package/dist/core/auth/login.d.ts +13 -0
- package/dist/core/auth/login.d.ts.map +1 -0
- package/dist/core/auth/login.js +188 -0
- package/dist/core/auth/login.js.map +1 -0
- package/dist/core/auth/openai.d.ts +4 -0
- package/dist/core/auth/openai.d.ts.map +1 -0
- package/dist/core/auth/openai.js +170 -0
- package/dist/core/auth/openai.js.map +1 -0
- package/dist/core/auth/pkce.d.ts +5 -0
- package/dist/core/auth/pkce.d.ts.map +1 -0
- package/dist/core/auth/pkce.js +17 -0
- package/dist/core/auth/pkce.js.map +1 -0
- package/dist/core/auth/storage.d.ts +29 -0
- package/dist/core/auth/storage.d.ts.map +1 -0
- package/dist/core/auth/storage.js +127 -0
- package/dist/core/auth/storage.js.map +1 -0
- package/dist/core/auth/types.d.ts +22 -0
- package/dist/core/auth/types.d.ts.map +1 -0
- package/dist/core/auth/types.js +12 -0
- package/dist/core/auth/types.js.map +1 -0
- package/dist/core/clustering.d.ts +52 -0
- package/dist/core/clustering.d.ts.map +1 -0
- package/dist/core/clustering.js +163 -0
- package/dist/core/clustering.js.map +1 -0
- package/dist/core/clustering.test.d.ts +2 -0
- package/dist/core/clustering.test.d.ts.map +1 -0
- package/dist/core/clustering.test.js +112 -0
- package/dist/core/clustering.test.js.map +1 -0
- package/dist/core/color-match.d.ts +19 -0
- package/dist/core/color-match.d.ts.map +1 -0
- package/dist/core/color-match.js +118 -0
- package/dist/core/color-match.js.map +1 -0
- package/dist/core/color-match.test.d.ts +2 -0
- package/dist/core/color-match.test.d.ts.map +1 -0
- package/dist/core/color-match.test.js +40 -0
- package/dist/core/color-match.test.js.map +1 -0
- package/dist/core/ducking.d.ts +37 -0
- package/dist/core/ducking.d.ts.map +1 -0
- package/dist/core/ducking.js +71 -0
- package/dist/core/ducking.js.map +1 -0
- package/dist/core/ducking.test.d.ts +2 -0
- package/dist/core/ducking.test.d.ts.map +1 -0
- package/dist/core/ducking.test.js +38 -0
- package/dist/core/ducking.test.js.map +1 -0
- package/dist/core/edl-roundtrip.test.d.ts +2 -0
- package/dist/core/edl-roundtrip.test.d.ts.map +1 -0
- package/dist/core/edl-roundtrip.test.js +171 -0
- package/dist/core/edl-roundtrip.test.js.map +1 -0
- package/dist/core/edl.d.ts +41 -0
- package/dist/core/edl.d.ts.map +1 -0
- package/dist/core/edl.js +56 -0
- package/dist/core/edl.js.map +1 -0
- package/dist/core/edl.test.d.ts +2 -0
- package/dist/core/edl.test.d.ts.map +1 -0
- package/dist/core/edl.test.js +62 -0
- package/dist/core/edl.test.js.map +1 -0
- package/dist/core/envelope-sync.d.ts +52 -0
- package/dist/core/envelope-sync.d.ts.map +1 -0
- package/dist/core/envelope-sync.js +169 -0
- package/dist/core/envelope-sync.js.map +1 -0
- package/dist/core/envelope-sync.test.d.ts +2 -0
- package/dist/core/envelope-sync.test.d.ts.map +1 -0
- package/dist/core/envelope-sync.test.js +70 -0
- package/dist/core/envelope-sync.test.js.map +1 -0
- package/dist/core/fcpxml-roundtrip.test.d.ts +2 -0
- package/dist/core/fcpxml-roundtrip.test.d.ts.map +1 -0
- package/dist/core/fcpxml-roundtrip.test.js +251 -0
- package/dist/core/fcpxml-roundtrip.test.js.map +1 -0
- package/dist/core/fcpxml.d.ts +172 -0
- package/dist/core/fcpxml.d.ts.map +1 -0
- package/dist/core/fcpxml.js +406 -0
- package/dist/core/fcpxml.js.map +1 -0
- package/dist/core/fcpxml.test.d.ts +2 -0
- package/dist/core/fcpxml.test.d.ts.map +1 -0
- package/dist/core/fcpxml.test.js +360 -0
- package/dist/core/fcpxml.test.js.map +1 -0
- package/dist/core/filler-words.d.ts +107 -0
- package/dist/core/filler-words.d.ts.map +1 -0
- package/dist/core/filler-words.js +221 -0
- package/dist/core/filler-words.js.map +1 -0
- package/dist/core/filler-words.test.d.ts +2 -0
- package/dist/core/filler-words.test.d.ts.map +1 -0
- package/dist/core/filler-words.test.js +177 -0
- package/dist/core/filler-words.test.js.map +1 -0
- package/dist/core/format.d.ts +36 -0
- package/dist/core/format.d.ts.map +1 -0
- package/dist/core/format.js +57 -0
- package/dist/core/format.js.map +1 -0
- package/dist/core/format.test.d.ts +2 -0
- package/dist/core/format.test.d.ts.map +1 -0
- package/dist/core/format.test.js +81 -0
- package/dist/core/format.test.js.map +1 -0
- package/dist/core/frames.d.ts +35 -0
- package/dist/core/frames.d.ts.map +1 -0
- package/dist/core/frames.js +64 -0
- package/dist/core/frames.js.map +1 -0
- package/dist/core/hook-analysis.d.ts +90 -0
- package/dist/core/hook-analysis.d.ts.map +1 -0
- package/dist/core/hook-analysis.js +222 -0
- package/dist/core/hook-analysis.js.map +1 -0
- package/dist/core/hook-analysis.test.d.ts +2 -0
- package/dist/core/hook-analysis.test.d.ts.map +1 -0
- package/dist/core/hook-analysis.test.js +130 -0
- package/dist/core/hook-analysis.test.js.map +1 -0
- package/dist/core/hosts/detect.d.ts +17 -0
- package/dist/core/hosts/detect.d.ts.map +1 -0
- package/dist/core/hosts/detect.js +64 -0
- package/dist/core/hosts/detect.js.map +1 -0
- package/dist/core/hosts/detect.test.d.ts +2 -0
- package/dist/core/hosts/detect.test.d.ts.map +1 -0
- package/dist/core/hosts/detect.test.js +17 -0
- package/dist/core/hosts/detect.test.js.map +1 -0
- package/dist/core/hosts/index.d.ts +13 -0
- package/dist/core/hosts/index.d.ts.map +1 -0
- package/dist/core/hosts/index.js +30 -0
- package/dist/core/hosts/index.js.map +1 -0
- package/dist/core/hosts/lazy.d.ts +53 -0
- package/dist/core/hosts/lazy.d.ts.map +1 -0
- package/dist/core/hosts/lazy.js +125 -0
- package/dist/core/hosts/lazy.js.map +1 -0
- package/dist/core/hosts/lazy.test.d.ts +2 -0
- package/dist/core/hosts/lazy.test.d.ts.map +1 -0
- package/dist/core/hosts/lazy.test.js +117 -0
- package/dist/core/hosts/lazy.test.js.map +1 -0
- package/dist/core/hosts/none/adapter.d.ts +74 -0
- package/dist/core/hosts/none/adapter.d.ts.map +1 -0
- package/dist/core/hosts/none/adapter.js +99 -0
- package/dist/core/hosts/none/adapter.js.map +1 -0
- package/dist/core/hosts/premiere/adapter.d.ts +87 -0
- package/dist/core/hosts/premiere/adapter.d.ts.map +1 -0
- package/dist/core/hosts/premiere/adapter.js +218 -0
- package/dist/core/hosts/premiere/adapter.js.map +1 -0
- package/dist/core/hosts/premiere/bridge-source.d.ts +26 -0
- package/dist/core/hosts/premiere/bridge-source.d.ts.map +1 -0
- package/dist/core/hosts/premiere/bridge-source.js +326 -0
- package/dist/core/hosts/premiere/bridge-source.js.map +1 -0
- package/dist/core/hosts/premiere/bridge-source.test.d.ts +2 -0
- package/dist/core/hosts/premiere/bridge-source.test.d.ts.map +1 -0
- package/dist/core/hosts/premiere/bridge-source.test.js +36 -0
- package/dist/core/hosts/premiere/bridge-source.test.js.map +1 -0
- package/dist/core/hosts/premiere/bridge.d.ts +38 -0
- package/dist/core/hosts/premiere/bridge.d.ts.map +1 -0
- package/dist/core/hosts/premiere/bridge.js +238 -0
- package/dist/core/hosts/premiere/bridge.js.map +1 -0
- package/dist/core/hosts/premiere/http-bridge.d.ts +47 -0
- package/dist/core/hosts/premiere/http-bridge.d.ts.map +1 -0
- package/dist/core/hosts/premiere/http-bridge.js +82 -0
- package/dist/core/hosts/premiere/http-bridge.js.map +1 -0
- package/dist/core/hosts/premiere/http-bridge.test.d.ts +2 -0
- package/dist/core/hosts/premiere/http-bridge.test.d.ts.map +1 -0
- package/dist/core/hosts/premiere/http-bridge.test.js +113 -0
- package/dist/core/hosts/premiere/http-bridge.test.js.map +1 -0
- package/dist/core/hosts/premiere/ws-bridge.d.ts +91 -0
- package/dist/core/hosts/premiere/ws-bridge.d.ts.map +1 -0
- package/dist/core/hosts/premiere/ws-bridge.js +303 -0
- package/dist/core/hosts/premiere/ws-bridge.js.map +1 -0
- package/dist/core/hosts/premiere/ws-bridge.test.d.ts +2 -0
- package/dist/core/hosts/premiere/ws-bridge.test.d.ts.map +1 -0
- package/dist/core/hosts/premiere/ws-bridge.test.js +146 -0
- package/dist/core/hosts/premiere/ws-bridge.test.js.map +1 -0
- package/dist/core/hosts/resolve/adapter.d.ts +99 -0
- package/dist/core/hosts/resolve/adapter.d.ts.map +1 -0
- package/dist/core/hosts/resolve/adapter.js +187 -0
- package/dist/core/hosts/resolve/adapter.js.map +1 -0
- package/dist/core/hosts/resolve/bridge-source.d.ts +17 -0
- package/dist/core/hosts/resolve/bridge-source.d.ts.map +1 -0
- package/dist/core/hosts/resolve/bridge-source.js +660 -0
- package/dist/core/hosts/resolve/bridge-source.js.map +1 -0
- package/dist/core/hosts/resolve/bridge.d.ts +51 -0
- package/dist/core/hosts/resolve/bridge.d.ts.map +1 -0
- package/dist/core/hosts/resolve/bridge.integration.test.d.ts +2 -0
- package/dist/core/hosts/resolve/bridge.integration.test.d.ts.map +1 -0
- package/dist/core/hosts/resolve/bridge.integration.test.js +472 -0
- package/dist/core/hosts/resolve/bridge.integration.test.js.map +1 -0
- package/dist/core/hosts/resolve/bridge.js +270 -0
- package/dist/core/hosts/resolve/bridge.js.map +1 -0
- package/dist/core/hosts/resolve/bridge.test.d.ts +2 -0
- package/dist/core/hosts/resolve/bridge.test.d.ts.map +1 -0
- package/dist/core/hosts/resolve/bridge.test.js +50 -0
- package/dist/core/hosts/resolve/bridge.test.js.map +1 -0
- package/dist/core/hosts/types.d.ts +167 -0
- package/dist/core/hosts/types.d.ts.map +1 -0
- package/dist/core/hosts/types.js +27 -0
- package/dist/core/hosts/types.js.map +1 -0
- package/dist/core/keyframes.d.ts +35 -0
- package/dist/core/keyframes.d.ts.map +1 -0
- package/dist/core/keyframes.js +90 -0
- package/dist/core/keyframes.js.map +1 -0
- package/dist/core/keyframes.test.d.ts +2 -0
- package/dist/core/keyframes.test.d.ts.map +1 -0
- package/dist/core/keyframes.test.js +73 -0
- package/dist/core/keyframes.test.js.map +1 -0
- package/dist/core/keyword-captions.d.ts +75 -0
- package/dist/core/keyword-captions.d.ts.map +1 -0
- package/dist/core/keyword-captions.js +285 -0
- package/dist/core/keyword-captions.js.map +1 -0
- package/dist/core/keyword-captions.test.d.ts +2 -0
- package/dist/core/keyword-captions.test.d.ts.map +1 -0
- package/dist/core/keyword-captions.test.js +90 -0
- package/dist/core/keyword-captions.test.js.map +1 -0
- package/dist/core/loudness.d.ts +52 -0
- package/dist/core/loudness.d.ts.map +1 -0
- package/dist/core/loudness.js +120 -0
- package/dist/core/loudness.js.map +1 -0
- package/dist/core/loudness.test.d.ts +2 -0
- package/dist/core/loudness.test.d.ts.map +1 -0
- package/dist/core/loudness.test.js +34 -0
- package/dist/core/loudness.test.js.map +1 -0
- package/dist/core/marker-colors.d.ts +39 -0
- package/dist/core/marker-colors.d.ts.map +1 -0
- package/dist/core/marker-colors.js +83 -0
- package/dist/core/marker-colors.js.map +1 -0
- package/dist/core/marker-colors.test.d.ts +2 -0
- package/dist/core/marker-colors.test.d.ts.map +1 -0
- package/dist/core/marker-colors.test.js +116 -0
- package/dist/core/marker-colors.test.js.map +1 -0
- package/dist/core/media/ffmpeg.d.ts +27 -0
- package/dist/core/media/ffmpeg.d.ts.map +1 -0
- package/dist/core/media/ffmpeg.js +53 -0
- package/dist/core/media/ffmpeg.js.map +1 -0
- package/dist/core/multicam.d.ts +40 -0
- package/dist/core/multicam.d.ts.map +1 -0
- package/dist/core/multicam.js +77 -0
- package/dist/core/multicam.js.map +1 -0
- package/dist/core/multicam.test.d.ts +2 -0
- package/dist/core/multicam.test.d.ts.map +1 -0
- package/dist/core/multicam.test.js +56 -0
- package/dist/core/multicam.test.js.map +1 -0
- package/dist/core/punch-in.d.ts +72 -0
- package/dist/core/punch-in.d.ts.map +1 -0
- package/dist/core/punch-in.js +133 -0
- package/dist/core/punch-in.js.map +1 -0
- package/dist/core/punch-in.test.d.ts +2 -0
- package/dist/core/punch-in.test.d.ts.map +1 -0
- package/dist/core/punch-in.test.js +118 -0
- package/dist/core/punch-in.test.js.map +1 -0
- package/dist/core/reformat.d.ts +26 -0
- package/dist/core/reformat.d.ts.map +1 -0
- package/dist/core/reformat.js +31 -0
- package/dist/core/reformat.js.map +1 -0
- package/dist/core/reformat.test.d.ts +2 -0
- package/dist/core/reformat.test.d.ts.map +1 -0
- package/dist/core/reformat.test.js +29 -0
- package/dist/core/reformat.test.js.map +1 -0
- package/dist/core/reorder.d.ts +42 -0
- package/dist/core/reorder.d.ts.map +1 -0
- package/dist/core/reorder.js +80 -0
- package/dist/core/reorder.js.map +1 -0
- package/dist/core/reorder.test.d.ts +2 -0
- package/dist/core/reorder.test.d.ts.map +1 -0
- package/dist/core/reorder.test.js +88 -0
- package/dist/core/reorder.test.js.map +1 -0
- package/dist/core/review.d.ts +38 -0
- package/dist/core/review.d.ts.map +1 -0
- package/dist/core/review.js +128 -0
- package/dist/core/review.js.map +1 -0
- package/dist/core/review.test.d.ts +2 -0
- package/dist/core/review.test.d.ts.map +1 -0
- package/dist/core/review.test.js +76 -0
- package/dist/core/review.test.js.map +1 -0
- package/dist/core/sessions.d.ts +40 -0
- package/dist/core/sessions.d.ts.map +1 -0
- package/dist/core/sessions.js +61 -0
- package/dist/core/sessions.js.map +1 -0
- package/dist/core/sfx-on-cuts.d.ts +60 -0
- package/dist/core/sfx-on-cuts.d.ts.map +1 -0
- package/dist/core/sfx-on-cuts.js +90 -0
- package/dist/core/sfx-on-cuts.js.map +1 -0
- package/dist/core/sfx-on-cuts.test.d.ts +2 -0
- package/dist/core/sfx-on-cuts.test.d.ts.map +1 -0
- package/dist/core/sfx-on-cuts.test.js +53 -0
- package/dist/core/sfx-on-cuts.test.js.map +1 -0
- package/dist/core/silence.d.ts +41 -0
- package/dist/core/silence.d.ts.map +1 -0
- package/dist/core/silence.js +104 -0
- package/dist/core/silence.js.map +1 -0
- package/dist/core/silence.test.d.ts +2 -0
- package/dist/core/silence.test.d.ts.map +1 -0
- package/dist/core/silence.test.js +143 -0
- package/dist/core/silence.test.js.map +1 -0
- package/dist/core/skills-loader.d.ts +34 -0
- package/dist/core/skills-loader.d.ts.map +1 -0
- package/dist/core/skills-loader.js +80 -0
- package/dist/core/skills-loader.js.map +1 -0
- package/dist/core/skills-loader.test.d.ts +2 -0
- package/dist/core/skills-loader.test.d.ts.map +1 -0
- package/dist/core/skills-loader.test.js +68 -0
- package/dist/core/skills-loader.test.js.map +1 -0
- package/dist/core/skin-grade.d.ts +62 -0
- package/dist/core/skin-grade.d.ts.map +1 -0
- package/dist/core/skin-grade.js +270 -0
- package/dist/core/skin-grade.js.map +1 -0
- package/dist/core/skin-grade.test.d.ts +2 -0
- package/dist/core/skin-grade.test.d.ts.map +1 -0
- package/dist/core/skin-grade.test.js +182 -0
- package/dist/core/skin-grade.test.js.map +1 -0
- package/dist/core/speaker-changes.d.ts +30 -0
- package/dist/core/speaker-changes.d.ts.map +1 -0
- package/dist/core/speaker-changes.js +19 -0
- package/dist/core/speaker-changes.js.map +1 -0
- package/dist/core/speaker-changes.test.d.ts +2 -0
- package/dist/core/speaker-changes.test.d.ts.map +1 -0
- package/dist/core/speaker-changes.test.js +46 -0
- package/dist/core/speaker-changes.test.js.map +1 -0
- package/dist/core/speed-ramp.d.ts +60 -0
- package/dist/core/speed-ramp.d.ts.map +1 -0
- package/dist/core/speed-ramp.js +113 -0
- package/dist/core/speed-ramp.js.map +1 -0
- package/dist/core/speed-ramp.test.d.ts +2 -0
- package/dist/core/speed-ramp.test.d.ts.map +1 -0
- package/dist/core/speed-ramp.test.js +74 -0
- package/dist/core/speed-ramp.test.js.map +1 -0
- package/dist/core/srt.d.ts +56 -0
- package/dist/core/srt.d.ts.map +1 -0
- package/dist/core/srt.js +90 -0
- package/dist/core/srt.js.map +1 -0
- package/dist/core/srt.test.d.ts +2 -0
- package/dist/core/srt.test.d.ts.map +1 -0
- package/dist/core/srt.test.js +107 -0
- package/dist/core/srt.test.js.map +1 -0
- package/dist/core/stabilize.d.ts +15 -0
- package/dist/core/stabilize.d.ts.map +1 -0
- package/dist/core/stabilize.js +69 -0
- package/dist/core/stabilize.js.map +1 -0
- package/dist/core/styles-loader.d.ts +33 -0
- package/dist/core/styles-loader.d.ts.map +1 -0
- package/dist/core/styles-loader.js +67 -0
- package/dist/core/styles-loader.js.map +1 -0
- package/dist/core/styles-loader.test.d.ts +2 -0
- package/dist/core/styles-loader.test.d.ts.map +1 -0
- package/dist/core/styles-loader.test.js +72 -0
- package/dist/core/styles-loader.test.js.map +1 -0
- package/dist/core/text-overlay.d.ts +76 -0
- package/dist/core/text-overlay.d.ts.map +1 -0
- package/dist/core/text-overlay.js +233 -0
- package/dist/core/text-overlay.js.map +1 -0
- package/dist/core/text-overlay.test.d.ts +2 -0
- package/dist/core/text-overlay.test.d.ts.map +1 -0
- package/dist/core/text-overlay.test.js +103 -0
- package/dist/core/text-overlay.test.js.map +1 -0
- package/dist/core/vision.d.ts +53 -0
- package/dist/core/vision.d.ts.map +1 -0
- package/dist/core/vision.js +150 -0
- package/dist/core/vision.js.map +1 -0
- package/dist/core/vision.test.d.ts +2 -0
- package/dist/core/vision.test.d.ts.map +1 -0
- package/dist/core/vision.test.js +76 -0
- package/dist/core/vision.test.js.map +1 -0
- package/dist/core/whisper.d.ts +188 -0
- package/dist/core/whisper.d.ts.map +1 -0
- package/dist/core/whisper.js +380 -0
- package/dist/core/whisper.js.map +1 -0
- package/dist/core/whisper.test.d.ts +2 -0
- package/dist/core/whisper.test.d.ts.map +1 -0
- package/dist/core/whisper.test.js +262 -0
- package/dist/core/whisper.test.js.map +1 -0
- package/dist/director/delegate-tool.d.ts +22 -0
- package/dist/director/delegate-tool.d.ts.map +1 -0
- package/dist/director/delegate-tool.js +62 -0
- package/dist/director/delegate-tool.js.map +1 -0
- package/dist/director/delegate-tool.test.d.ts +2 -0
- package/dist/director/delegate-tool.test.d.ts.map +1 -0
- package/dist/director/delegate-tool.test.js +38 -0
- package/dist/director/delegate-tool.test.js.map +1 -0
- package/dist/director/director-prompt.d.ts +7 -0
- package/dist/director/director-prompt.d.ts.map +1 -0
- package/dist/director/director-prompt.js +52 -0
- package/dist/director/director-prompt.js.map +1 -0
- package/dist/director/director.d.ts +16 -0
- package/dist/director/director.d.ts.map +1 -0
- package/dist/director/director.js +28 -0
- package/dist/director/director.js.map +1 -0
- package/dist/director/executor.d.ts +19 -0
- package/dist/director/executor.d.ts.map +1 -0
- package/dist/director/executor.js +93 -0
- package/dist/director/executor.js.map +1 -0
- package/dist/director/index.d.ts +6 -0
- package/dist/director/index.d.ts.map +1 -0
- package/dist/director/index.js +5 -0
- package/dist/director/index.js.map +1 -0
- package/dist/director/types.d.ts +38 -0
- package/dist/director/types.d.ts.map +1 -0
- package/dist/director/types.js +2 -0
- package/dist/director/types.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/skills.d.ts +18 -0
- package/dist/skills.d.ts.map +1 -0
- package/dist/skills.js +674 -0
- package/dist/skills.js.map +1 -0
- package/dist/system-prompt.d.ts +35 -0
- package/dist/system-prompt.d.ts.map +1 -0
- package/dist/system-prompt.js +478 -0
- package/dist/system-prompt.js.map +1 -0
- package/dist/system-prompt.test.d.ts +2 -0
- package/dist/system-prompt.test.d.ts.map +1 -0
- package/dist/system-prompt.test.js +87 -0
- package/dist/system-prompt.test.js.map +1 -0
- package/dist/tools/add-fades.d.ts +13 -0
- package/dist/tools/add-fades.d.ts.map +1 -0
- package/dist/tools/add-fades.js +88 -0
- package/dist/tools/add-fades.js.map +1 -0
- package/dist/tools/add-marker.d.ts +31 -0
- package/dist/tools/add-marker.d.ts.map +1 -0
- package/dist/tools/add-marker.js +56 -0
- package/dist/tools/add-marker.js.map +1 -0
- package/dist/tools/add-sfx-at-cuts.d.ts +24 -0
- package/dist/tools/add-sfx-at-cuts.d.ts.map +1 -0
- package/dist/tools/add-sfx-at-cuts.js +120 -0
- package/dist/tools/add-sfx-at-cuts.js.map +1 -0
- package/dist/tools/add-track.d.ts +13 -0
- package/dist/tools/add-track.d.ts.map +1 -0
- package/dist/tools/add-track.js +26 -0
- package/dist/tools/add-track.js.map +1 -0
- package/dist/tools/analyze-hook.d.ts +28 -0
- package/dist/tools/analyze-hook.d.ts.map +1 -0
- package/dist/tools/analyze-hook.js +126 -0
- package/dist/tools/analyze-hook.js.map +1 -0
- package/dist/tools/append-clip.d.ts +10 -0
- package/dist/tools/append-clip.d.ts.map +1 -0
- package/dist/tools/append-clip.js +27 -0
- package/dist/tools/append-clip.js.map +1 -0
- package/dist/tools/apply-lut.d.ts +11 -0
- package/dist/tools/apply-lut.d.ts.map +1 -0
- package/dist/tools/apply-lut.js +33 -0
- package/dist/tools/apply-lut.js.map +1 -0
- package/dist/tools/burn-subtitles.d.ts +28 -0
- package/dist/tools/burn-subtitles.d.ts.map +1 -0
- package/dist/tools/burn-subtitles.js +87 -0
- package/dist/tools/burn-subtitles.js.map +1 -0
- package/dist/tools/clean-audio.d.ts +18 -0
- package/dist/tools/clean-audio.d.ts.map +1 -0
- package/dist/tools/clean-audio.js +54 -0
- package/dist/tools/clean-audio.js.map +1 -0
- package/dist/tools/clone-timeline.d.ts +9 -0
- package/dist/tools/clone-timeline.d.ts.map +1 -0
- package/dist/tools/clone-timeline.js +28 -0
- package/dist/tools/clone-timeline.js.map +1 -0
- package/dist/tools/cluster-takes.d.ts +11 -0
- package/dist/tools/cluster-takes.d.ts.map +1 -0
- package/dist/tools/cluster-takes.js +71 -0
- package/dist/tools/cluster-takes.js.map +1 -0
- package/dist/tools/color-match.d.ts +16 -0
- package/dist/tools/color-match.d.ts.map +1 -0
- package/dist/tools/color-match.js +55 -0
- package/dist/tools/color-match.js.map +1 -0
- package/dist/tools/compose-layered.d.ts +47 -0
- package/dist/tools/compose-layered.d.ts.map +1 -0
- package/dist/tools/compose-layered.js +103 -0
- package/dist/tools/compose-layered.js.map +1 -0
- package/dist/tools/compose-thumbnail.d.ts +35 -0
- package/dist/tools/compose-thumbnail.d.ts.map +1 -0
- package/dist/tools/compose-thumbnail.js +130 -0
- package/dist/tools/compose-thumbnail.js.map +1 -0
- package/dist/tools/concat-videos.d.ts +18 -0
- package/dist/tools/concat-videos.d.ts.map +1 -0
- package/dist/tools/concat-videos.js +79 -0
- package/dist/tools/concat-videos.js.map +1 -0
- package/dist/tools/copy-grade.d.ts +10 -0
- package/dist/tools/copy-grade.d.ts.map +1 -0
- package/dist/tools/copy-grade.js +29 -0
- package/dist/tools/copy-grade.js.map +1 -0
- package/dist/tools/create-timeline.d.ts +12 -0
- package/dist/tools/create-timeline.d.ts.map +1 -0
- package/dist/tools/create-timeline.js +35 -0
- package/dist/tools/create-timeline.js.map +1 -0
- package/dist/tools/crossfade-videos.d.ts +49 -0
- package/dist/tools/crossfade-videos.d.ts.map +1 -0
- package/dist/tools/crossfade-videos.js +121 -0
- package/dist/tools/crossfade-videos.js.map +1 -0
- package/dist/tools/cut-at.d.ts +10 -0
- package/dist/tools/cut-at.d.ts.map +1 -0
- package/dist/tools/cut-at.js +24 -0
- package/dist/tools/cut-at.js.map +1 -0
- package/dist/tools/cut-filler-words.d.ts +27 -0
- package/dist/tools/cut-filler-words.d.ts.map +1 -0
- package/dist/tools/cut-filler-words.js +165 -0
- package/dist/tools/cut-filler-words.js.map +1 -0
- package/dist/tools/detect-silence.d.ts +13 -0
- package/dist/tools/detect-silence.d.ts.map +1 -0
- package/dist/tools/detect-silence.js +98 -0
- package/dist/tools/detect-silence.js.map +1 -0
- package/dist/tools/detect-speaker-changes.d.ts +9 -0
- package/dist/tools/detect-speaker-changes.d.ts.map +1 -0
- package/dist/tools/detect-speaker-changes.js +42 -0
- package/dist/tools/detect-speaker-changes.js.map +1 -0
- package/dist/tools/dry-run.d.ts +23 -0
- package/dist/tools/dry-run.d.ts.map +1 -0
- package/dist/tools/dry-run.js +66 -0
- package/dist/tools/dry-run.js.map +1 -0
- package/dist/tools/dry-run.test.d.ts +2 -0
- package/dist/tools/dry-run.test.d.ts.map +1 -0
- package/dist/tools/dry-run.test.js +66 -0
- package/dist/tools/dry-run.test.js.map +1 -0
- package/dist/tools/duck-audio.d.ts +16 -0
- package/dist/tools/duck-audio.d.ts.map +1 -0
- package/dist/tools/duck-audio.js +73 -0
- package/dist/tools/duck-audio.js.map +1 -0
- package/dist/tools/extract-audio.d.ts +10 -0
- package/dist/tools/extract-audio.d.ts.map +1 -0
- package/dist/tools/extract-audio.js +30 -0
- package/dist/tools/extract-audio.js.map +1 -0
- package/dist/tools/extract-frame.d.ts +12 -0
- package/dist/tools/extract-frame.d.ts.map +1 -0
- package/dist/tools/extract-frame.js +63 -0
- package/dist/tools/extract-frame.js.map +1 -0
- package/dist/tools/generate-gif.d.ts +13 -0
- package/dist/tools/generate-gif.d.ts.map +1 -0
- package/dist/tools/generate-gif.js +94 -0
- package/dist/tools/generate-gif.js.map +1 -0
- package/dist/tools/get-markers.d.ts +13 -0
- package/dist/tools/get-markers.d.ts.map +1 -0
- package/dist/tools/get-markers.js +71 -0
- package/dist/tools/get-markers.js.map +1 -0
- package/dist/tools/get-timeline.d.ts +9 -0
- package/dist/tools/get-timeline.d.ts.map +1 -0
- package/dist/tools/get-timeline.js +43 -0
- package/dist/tools/get-timeline.js.map +1 -0
- package/dist/tools/grade-skin-tones.d.ts +31 -0
- package/dist/tools/grade-skin-tones.d.ts.map +1 -0
- package/dist/tools/grade-skin-tones.js +92 -0
- package/dist/tools/grade-skin-tones.js.map +1 -0
- package/dist/tools/host-info.d.ts +7 -0
- package/dist/tools/host-info.d.ts.map +1 -0
- package/dist/tools/host-info.js +33 -0
- package/dist/tools/host-info.js.map +1 -0
- package/dist/tools/host-tools.test.d.ts +2 -0
- package/dist/tools/host-tools.test.d.ts.map +1 -0
- package/dist/tools/host-tools.test.js +83 -0
- package/dist/tools/host-tools.test.js.map +1 -0
- package/dist/tools/import-edl.d.ts +9 -0
- package/dist/tools/import-edl.d.ts.map +1 -0
- package/dist/tools/import-edl.js +25 -0
- package/dist/tools/import-edl.js.map +1 -0
- package/dist/tools/import-subtitles.d.ts +9 -0
- package/dist/tools/import-subtitles.d.ts.map +1 -0
- package/dist/tools/import-subtitles.js +31 -0
- package/dist/tools/import-subtitles.js.map +1 -0
- package/dist/tools/import-to-media-pool.d.ts +10 -0
- package/dist/tools/import-to-media-pool.d.ts.map +1 -0
- package/dist/tools/import-to-media-pool.js +27 -0
- package/dist/tools/import-to-media-pool.js.map +1 -0
- package/dist/tools/index.d.ts +94 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +242 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/index.test.d.ts +2 -0
- package/dist/tools/index.test.d.ts.map +1 -0
- package/dist/tools/index.test.js +128 -0
- package/dist/tools/index.test.js.map +1 -0
- package/dist/tools/insert-broll.d.ts +13 -0
- package/dist/tools/insert-broll.d.ts.map +1 -0
- package/dist/tools/insert-broll.js +56 -0
- package/dist/tools/insert-broll.js.map +1 -0
- package/dist/tools/ken-burns.d.ts +26 -0
- package/dist/tools/ken-burns.d.ts.map +1 -0
- package/dist/tools/ken-burns.js +125 -0
- package/dist/tools/ken-burns.js.map +1 -0
- package/dist/tools/list-render-presets.d.ts +7 -0
- package/dist/tools/list-render-presets.d.ts.map +1 -0
- package/dist/tools/list-render-presets.js +30 -0
- package/dist/tools/list-render-presets.js.map +1 -0
- package/dist/tools/match-clip-color.d.ts +29 -0
- package/dist/tools/match-clip-color.d.ts.map +1 -0
- package/dist/tools/match-clip-color.js +99 -0
- package/dist/tools/match-clip-color.js.map +1 -0
- package/dist/tools/measure-loudness.d.ts +8 -0
- package/dist/tools/measure-loudness.d.ts.map +1 -0
- package/dist/tools/measure-loudness.js +40 -0
- package/dist/tools/measure-loudness.js.map +1 -0
- package/dist/tools/mix-audio.d.ts +46 -0
- package/dist/tools/mix-audio.d.ts.map +1 -0
- package/dist/tools/mix-audio.js +101 -0
- package/dist/tools/mix-audio.js.map +1 -0
- package/dist/tools/multicam-sync.d.ts +14 -0
- package/dist/tools/multicam-sync.d.ts.map +1 -0
- package/dist/tools/multicam-sync.js +75 -0
- package/dist/tools/multicam-sync.js.map +1 -0
- package/dist/tools/new-tools.test.d.ts +2 -0
- package/dist/tools/new-tools.test.d.ts.map +1 -0
- package/dist/tools/new-tools.test.js +511 -0
- package/dist/tools/new-tools.test.js.map +1 -0
- package/dist/tools/normalize-loudness.d.ts +21 -0
- package/dist/tools/normalize-loudness.d.ts.map +1 -0
- package/dist/tools/normalize-loudness.js +94 -0
- package/dist/tools/normalize-loudness.js.map +1 -0
- package/dist/tools/open-page.d.ts +17 -0
- package/dist/tools/open-page.d.ts.map +1 -0
- package/dist/tools/open-page.js +27 -0
- package/dist/tools/open-page.js.map +1 -0
- package/dist/tools/overlay-watermark.d.ts +28 -0
- package/dist/tools/overlay-watermark.d.ts.map +1 -0
- package/dist/tools/overlay-watermark.js +98 -0
- package/dist/tools/overlay-watermark.js.map +1 -0
- package/dist/tools/pick-best-takes.d.ts +20 -0
- package/dist/tools/pick-best-takes.d.ts.map +1 -0
- package/dist/tools/pick-best-takes.js +147 -0
- package/dist/tools/pick-best-takes.js.map +1 -0
- package/dist/tools/post-tools.test.d.ts +2 -0
- package/dist/tools/post-tools.test.d.ts.map +1 -0
- package/dist/tools/post-tools.test.js +83 -0
- package/dist/tools/post-tools.test.js.map +1 -0
- package/dist/tools/pre-render-check.d.ts +23 -0
- package/dist/tools/pre-render-check.d.ts.map +1 -0
- package/dist/tools/pre-render-check.js +134 -0
- package/dist/tools/pre-render-check.js.map +1 -0
- package/dist/tools/probe-media.d.ts +8 -0
- package/dist/tools/probe-media.d.ts.map +1 -0
- package/dist/tools/probe-media.js +32 -0
- package/dist/tools/probe-media.js.map +1 -0
- package/dist/tools/punch-in.d.ts +30 -0
- package/dist/tools/punch-in.d.ts.map +1 -0
- package/dist/tools/punch-in.js +130 -0
- package/dist/tools/punch-in.js.map +1 -0
- package/dist/tools/read-skill.d.ts +9 -0
- package/dist/tools/read-skill.d.ts.map +1 -0
- package/dist/tools/read-skill.js +24 -0
- package/dist/tools/read-skill.js.map +1 -0
- package/dist/tools/read-transcript.d.ts +14 -0
- package/dist/tools/read-transcript.d.ts.map +1 -0
- package/dist/tools/read-transcript.js +85 -0
- package/dist/tools/read-transcript.js.map +1 -0
- package/dist/tools/read-transcript.test.d.ts +2 -0
- package/dist/tools/read-transcript.test.d.ts.map +1 -0
- package/dist/tools/read-transcript.test.js +136 -0
- package/dist/tools/read-transcript.test.js.map +1 -0
- package/dist/tools/reformat-timeline.d.ts +25 -0
- package/dist/tools/reformat-timeline.d.ts.map +1 -0
- package/dist/tools/reformat-timeline.js +60 -0
- package/dist/tools/reformat-timeline.js.map +1 -0
- package/dist/tools/render.d.ts +10 -0
- package/dist/tools/render.d.ts.map +1 -0
- package/dist/tools/render.js +26 -0
- package/dist/tools/render.js.map +1 -0
- package/dist/tools/reorder-timeline.d.ts +12 -0
- package/dist/tools/reorder-timeline.d.ts.map +1 -0
- package/dist/tools/reorder-timeline.js +65 -0
- package/dist/tools/reorder-timeline.js.map +1 -0
- package/dist/tools/replace-clip.d.ts +10 -0
- package/dist/tools/replace-clip.d.ts.map +1 -0
- package/dist/tools/replace-clip.js +28 -0
- package/dist/tools/replace-clip.js.map +1 -0
- package/dist/tools/review-edit.d.ts +23 -0
- package/dist/tools/review-edit.d.ts.map +1 -0
- package/dist/tools/review-edit.js +47 -0
- package/dist/tools/review-edit.js.map +1 -0
- package/dist/tools/ripple-delete.d.ts +11 -0
- package/dist/tools/ripple-delete.d.ts.map +1 -0
- package/dist/tools/ripple-delete.js +27 -0
- package/dist/tools/ripple-delete.js.map +1 -0
- package/dist/tools/save-project.d.ts +7 -0
- package/dist/tools/save-project.d.ts.map +1 -0
- package/dist/tools/save-project.js +22 -0
- package/dist/tools/save-project.js.map +1 -0
- package/dist/tools/score-shot.d.ts +18 -0
- package/dist/tools/score-shot.d.ts.map +1 -0
- package/dist/tools/score-shot.js +127 -0
- package/dist/tools/score-shot.js.map +1 -0
- package/dist/tools/set-clip-speed.d.ts +10 -0
- package/dist/tools/set-clip-speed.d.ts.map +1 -0
- package/dist/tools/set-clip-speed.js +28 -0
- package/dist/tools/set-clip-speed.js.map +1 -0
- package/dist/tools/set-clip-volume.d.ts +10 -0
- package/dist/tools/set-clip-volume.d.ts.map +1 -0
- package/dist/tools/set-clip-volume.js +33 -0
- package/dist/tools/set-clip-volume.js.map +1 -0
- package/dist/tools/set-primary-correction.d.ts +14 -0
- package/dist/tools/set-primary-correction.d.ts.map +1 -0
- package/dist/tools/set-primary-correction.js +45 -0
- package/dist/tools/set-primary-correction.js.map +1 -0
- package/dist/tools/smart-reframe.d.ts +22 -0
- package/dist/tools/smart-reframe.d.ts.map +1 -0
- package/dist/tools/smart-reframe.js +39 -0
- package/dist/tools/smart-reframe.js.map +1 -0
- package/dist/tools/speed-ramp.d.ts +14 -0
- package/dist/tools/speed-ramp.d.ts.map +1 -0
- package/dist/tools/speed-ramp.js +71 -0
- package/dist/tools/speed-ramp.js.map +1 -0
- package/dist/tools/stabilize-video.d.ts +12 -0
- package/dist/tools/stabilize-video.d.ts.map +1 -0
- package/dist/tools/stabilize-video.js +63 -0
- package/dist/tools/stabilize-video.js.map +1 -0
- package/dist/tools/transcribe.d.ts +29 -0
- package/dist/tools/transcribe.d.ts.map +1 -0
- package/dist/tools/transcribe.js +116 -0
- package/dist/tools/transcribe.js.map +1 -0
- package/dist/tools/transition-videos.d.ts +29 -0
- package/dist/tools/transition-videos.d.ts.map +1 -0
- package/dist/tools/transition-videos.js +129 -0
- package/dist/tools/transition-videos.js.map +1 -0
- package/dist/tools/write-ass.d.ts +34 -0
- package/dist/tools/write-ass.d.ts.map +1 -0
- package/dist/tools/write-ass.js +101 -0
- package/dist/tools/write-ass.js.map +1 -0
- package/dist/tools/write-edl.d.ts +24 -0
- package/dist/tools/write-edl.d.ts.map +1 -0
- package/dist/tools/write-edl.js +59 -0
- package/dist/tools/write-edl.js.map +1 -0
- package/dist/tools/write-fcpxml.d.ts +20 -0
- package/dist/tools/write-fcpxml.d.ts.map +1 -0
- package/dist/tools/write-fcpxml.js +52 -0
- package/dist/tools/write-fcpxml.js.map +1 -0
- package/dist/tools/write-keyword-captions.d.ts +36 -0
- package/dist/tools/write-keyword-captions.d.ts.map +1 -0
- package/dist/tools/write-keyword-captions.js +183 -0
- package/dist/tools/write-keyword-captions.js.map +1 -0
- package/dist/tools/write-lower-third.d.ts +34 -0
- package/dist/tools/write-lower-third.d.ts.map +1 -0
- package/dist/tools/write-lower-third.js +52 -0
- package/dist/tools/write-lower-third.js.map +1 -0
- package/dist/tools/write-srt.d.ts +20 -0
- package/dist/tools/write-srt.d.ts.map +1 -0
- package/dist/tools/write-srt.js +72 -0
- package/dist/tools/write-srt.js.map +1 -0
- package/dist/tools/write-title-card.d.ts +25 -0
- package/dist/tools/write-title-card.d.ts.map +1 -0
- package/dist/tools/write-title-card.js +57 -0
- package/dist/tools/write-title-card.js.map +1 -0
- package/dist/types.d.ts +83 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/ui/App.d.ts +44 -0
- package/dist/ui/App.d.ts.map +1 -0
- package/dist/ui/App.js +454 -0
- package/dist/ui/App.js.map +1 -0
- package/dist/ui/components/Banner.d.ts +13 -0
- package/dist/ui/components/Banner.d.ts.map +1 -0
- package/dist/ui/components/Banner.js +59 -0
- package/dist/ui/components/Banner.js.map +1 -0
- package/dist/ui/components/Footer.d.ts +19 -0
- package/dist/ui/components/Footer.d.ts.map +1 -0
- package/dist/ui/components/Footer.js +20 -0
- package/dist/ui/components/Footer.js.map +1 -0
- package/dist/ui/components/Header.d.ts +16 -0
- package/dist/ui/components/Header.d.ts.map +1 -0
- package/dist/ui/components/Header.js +12 -0
- package/dist/ui/components/Header.js.map +1 -0
- package/dist/ui/components/InputBox.d.ts +21 -0
- package/dist/ui/components/InputBox.d.ts.map +1 -0
- package/dist/ui/components/InputBox.js +81 -0
- package/dist/ui/components/InputBox.js.map +1 -0
- package/dist/ui/components/Message.d.ts +14 -0
- package/dist/ui/components/Message.d.ts.map +1 -0
- package/dist/ui/components/Message.js +24 -0
- package/dist/ui/components/Message.js.map +1 -0
- package/dist/ui/components/SlashMenu.d.ts +19 -0
- package/dist/ui/components/SlashMenu.d.ts.map +1 -0
- package/dist/ui/components/SlashMenu.js +33 -0
- package/dist/ui/components/SlashMenu.js.map +1 -0
- package/dist/ui/components/SlashMenu.test.d.ts +2 -0
- package/dist/ui/components/SlashMenu.test.d.ts.map +1 -0
- package/dist/ui/components/SlashMenu.test.js +23 -0
- package/dist/ui/components/SlashMenu.test.js.map +1 -0
- package/dist/ui/components/Spinner.d.ts +6 -0
- package/dist/ui/components/Spinner.d.ts.map +1 -0
- package/dist/ui/components/Spinner.js +16 -0
- package/dist/ui/components/Spinner.js.map +1 -0
- package/dist/ui/components/ToolCallLine.d.ts +16 -0
- package/dist/ui/components/ToolCallLine.d.ts.map +1 -0
- package/dist/ui/components/ToolCallLine.js +35 -0
- package/dist/ui/components/ToolCallLine.js.map +1 -0
- package/dist/ui/render.d.ts +9 -0
- package/dist/ui/render.d.ts.map +1 -0
- package/dist/ui/render.js +56 -0
- package/dist/ui/render.js.map +1 -0
- package/dist/ui/spinner-frames.d.ts +3 -0
- package/dist/ui/spinner-frames.d.ts.map +1 -0
- package/dist/ui/spinner-frames.js +16 -0
- package/dist/ui/spinner-frames.js.map +1 -0
- package/dist/ui/theme.d.ts +27 -0
- package/dist/ui/theme.d.ts.map +1 -0
- package/dist/ui/theme.js +26 -0
- package/dist/ui/theme.js.map +1 -0
- package/package.json +50 -0
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filler-word detection on word-timestamped transcripts.
|
|
3
|
+
*
|
|
4
|
+
* The single biggest creator-time-saver in long-form editing: scan the
|
|
5
|
+
* transcript word-by-word, mark every "um" / "uh" / "like" / "you know"
|
|
6
|
+
* range, then EMIT KEEP RANGES (the inverse). That keep list goes
|
|
7
|
+
* straight into write_edl → import_edl → done.
|
|
8
|
+
*
|
|
9
|
+
* What counts as a "filler" is configurable. The defaults reflect the
|
|
10
|
+
* canonical short list every YouTube auto-cutter (FireCut, Wisecut,
|
|
11
|
+
* Descript) ships with. We also support multi-word phrases ("you know",
|
|
12
|
+
* "i mean", "kind of") because the most distracting fillers are
|
|
13
|
+
* two-word verbal tics.
|
|
14
|
+
*
|
|
15
|
+
* Pure logic only — no I/O. The tool wrapper handles transcript loading
|
|
16
|
+
* and EDL emission.
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Default filler vocabulary. Single words and common multi-word verbal
|
|
20
|
+
* tics. The matcher normalizes punctuation and case, so we list bare
|
|
21
|
+
* surface forms.
|
|
22
|
+
*/
|
|
23
|
+
export const DEFAULT_FILLERS = [
|
|
24
|
+
"um",
|
|
25
|
+
"uh",
|
|
26
|
+
"uhm",
|
|
27
|
+
"umm",
|
|
28
|
+
"uhh",
|
|
29
|
+
"er",
|
|
30
|
+
"ah",
|
|
31
|
+
"hmm",
|
|
32
|
+
"you know",
|
|
33
|
+
"i mean",
|
|
34
|
+
"kind of",
|
|
35
|
+
"sort of",
|
|
36
|
+
"like",
|
|
37
|
+
"actually",
|
|
38
|
+
"basically",
|
|
39
|
+
"literally",
|
|
40
|
+
"honestly",
|
|
41
|
+
"right",
|
|
42
|
+
"so",
|
|
43
|
+
];
|
|
44
|
+
const NON_AGGRESSIVE_SAFE_LIST = new Set([
|
|
45
|
+
"um",
|
|
46
|
+
"uh",
|
|
47
|
+
"uhm",
|
|
48
|
+
"umm",
|
|
49
|
+
"uhh",
|
|
50
|
+
"er",
|
|
51
|
+
"ah",
|
|
52
|
+
"hmm",
|
|
53
|
+
"you know",
|
|
54
|
+
"i mean",
|
|
55
|
+
"kind of",
|
|
56
|
+
"sort of",
|
|
57
|
+
]);
|
|
58
|
+
/**
|
|
59
|
+
* Find filler-word ranges across the whole transcript. Requires
|
|
60
|
+
* word-level timestamps (transcribe with wordTimestamps=true).
|
|
61
|
+
*
|
|
62
|
+
* Returns ranges in temporal order with no overlaps; adjacent ranges
|
|
63
|
+
* within `mergeGapMs` are merged into a single cut.
|
|
64
|
+
*/
|
|
65
|
+
export function detectFillerRanges(transcript, opts = {}) {
|
|
66
|
+
const padStart = (opts.paddingStartMs ?? 20) / 1000;
|
|
67
|
+
const padEnd = (opts.paddingEndMs ?? 20) / 1000;
|
|
68
|
+
const mergeGap = (opts.mergeGapMs ?? 150) / 1000;
|
|
69
|
+
const aggressive = opts.aggressiveSingleWords ?? true;
|
|
70
|
+
const vocab = (opts.fillers ?? DEFAULT_FILLERS)
|
|
71
|
+
.map((f) => f.trim().toLowerCase())
|
|
72
|
+
.filter((f) => f.length > 0)
|
|
73
|
+
.filter((f) => aggressive || NON_AGGRESSIVE_SAFE_LIST.has(f));
|
|
74
|
+
// Sort so multi-word phrases match before single-word ones at the same
|
|
75
|
+
// position. Otherwise "you" + "know" gets matched as two single words.
|
|
76
|
+
const sortedVocab = [...vocab].sort((a, b) => b.split(/\s+/).length - a.split(/\s+/).length);
|
|
77
|
+
const out = [];
|
|
78
|
+
for (const segment of transcript.segments) {
|
|
79
|
+
const words = segment.words;
|
|
80
|
+
if (!words || words.length === 0)
|
|
81
|
+
continue;
|
|
82
|
+
const normalized = words.map((w) => normalizeWord(w.text));
|
|
83
|
+
let i = 0;
|
|
84
|
+
while (i < words.length) {
|
|
85
|
+
const match = findVocabMatch(sortedVocab, normalized, i);
|
|
86
|
+
if (!match) {
|
|
87
|
+
i++;
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
const startWord = words[i];
|
|
91
|
+
const endWord = words[i + match.length - 1];
|
|
92
|
+
const startSec = Math.max(0, startWord.start - padStart);
|
|
93
|
+
const endSec = endWord.end + padEnd;
|
|
94
|
+
out.push({
|
|
95
|
+
startSec,
|
|
96
|
+
endSec,
|
|
97
|
+
text: match.phrase,
|
|
98
|
+
startWordIndex: i,
|
|
99
|
+
endWordIndex: i + match.length,
|
|
100
|
+
});
|
|
101
|
+
i += match.length;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return mergeOverlappingFillers(out, mergeGap);
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Compute KEEP ranges between fillers. The returned list is what you
|
|
108
|
+
* pass into write_edl as a sequence of source-in / source-out pairs.
|
|
109
|
+
*
|
|
110
|
+
* Adjacent keep ranges with a tiny gap (< minKeepDurSec) get dropped —
|
|
111
|
+
* a 40ms keep clip between two filler cuts is just noise.
|
|
112
|
+
*/
|
|
113
|
+
export function keepRangesFromFillers(fillers, totalSec, minKeepDurSec = 0.05) {
|
|
114
|
+
if (totalSec <= 0)
|
|
115
|
+
return [];
|
|
116
|
+
const sorted = [...fillers].sort((a, b) => a.startSec - b.startSec);
|
|
117
|
+
const keeps = [];
|
|
118
|
+
let cursor = 0;
|
|
119
|
+
for (const f of sorted) {
|
|
120
|
+
if (f.startSec > cursor) {
|
|
121
|
+
const start = cursor;
|
|
122
|
+
const end = Math.min(totalSec, f.startSec);
|
|
123
|
+
if (end - start >= minKeepDurSec) {
|
|
124
|
+
keeps.push({ startSec: start, endSec: end });
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
cursor = Math.max(cursor, Math.min(totalSec, f.endSec));
|
|
128
|
+
}
|
|
129
|
+
if (cursor < totalSec) {
|
|
130
|
+
const dur = totalSec - cursor;
|
|
131
|
+
if (dur >= minKeepDurSec) {
|
|
132
|
+
keeps.push({ startSec: cursor, endSec: totalSec });
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return keeps;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Frame-align keep ranges. Rounds INWARD (start ceils, end floors) so
|
|
139
|
+
* cuts never extend into a filler.
|
|
140
|
+
*/
|
|
141
|
+
export function keepRangesToFrameRanges(keeps, fps) {
|
|
142
|
+
const out = [];
|
|
143
|
+
for (const k of keeps) {
|
|
144
|
+
const sf = Math.ceil(k.startSec * fps);
|
|
145
|
+
const ef = Math.floor(k.endSec * fps);
|
|
146
|
+
if (ef > sf)
|
|
147
|
+
out.push({ startFrame: sf, endFrame: ef });
|
|
148
|
+
}
|
|
149
|
+
return out;
|
|
150
|
+
}
|
|
151
|
+
// ── Internal ─────────────────────────────────────────────────
|
|
152
|
+
function normalizeWord(text) {
|
|
153
|
+
// Lowercase and strip non-letter trailing/leading punctuation.
|
|
154
|
+
// We keep apostrophes inside words ("don't", "i'm").
|
|
155
|
+
return text
|
|
156
|
+
.toLowerCase()
|
|
157
|
+
.trim()
|
|
158
|
+
.replace(/^[^a-z']+/u, "")
|
|
159
|
+
.replace(/[^a-z']+$/u, "");
|
|
160
|
+
}
|
|
161
|
+
function findVocabMatch(sortedVocab, normalized, startIndex) {
|
|
162
|
+
for (const phrase of sortedVocab) {
|
|
163
|
+
const parts = phrase.split(/\s+/);
|
|
164
|
+
if (startIndex + parts.length > normalized.length)
|
|
165
|
+
continue;
|
|
166
|
+
let ok = true;
|
|
167
|
+
for (let j = 0; j < parts.length; j++) {
|
|
168
|
+
if (normalized[startIndex + j] !== parts[j]) {
|
|
169
|
+
ok = false;
|
|
170
|
+
break;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
if (ok)
|
|
174
|
+
return { phrase, length: parts.length };
|
|
175
|
+
}
|
|
176
|
+
return undefined;
|
|
177
|
+
}
|
|
178
|
+
function mergeOverlappingFillers(ranges, mergeGap) {
|
|
179
|
+
if (ranges.length <= 1)
|
|
180
|
+
return ranges;
|
|
181
|
+
const sorted = [...ranges].sort((a, b) => a.startSec - b.startSec);
|
|
182
|
+
const out = [sorted[0]];
|
|
183
|
+
for (let i = 1; i < sorted.length; i++) {
|
|
184
|
+
const prev = out[out.length - 1];
|
|
185
|
+
const cur = sorted[i];
|
|
186
|
+
if (cur.startSec - prev.endSec <= mergeGap) {
|
|
187
|
+
out[out.length - 1] = {
|
|
188
|
+
startSec: prev.startSec,
|
|
189
|
+
endSec: Math.max(prev.endSec, cur.endSec),
|
|
190
|
+
text: `${prev.text} + ${cur.text}`,
|
|
191
|
+
startWordIndex: prev.startWordIndex,
|
|
192
|
+
endWordIndex: cur.endWordIndex,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
out.push(cur);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return out;
|
|
200
|
+
}
|
|
201
|
+
export function summarizeFillers(fillers) {
|
|
202
|
+
const counts = new Map();
|
|
203
|
+
let totalRemovedSec = 0;
|
|
204
|
+
for (const f of fillers) {
|
|
205
|
+
totalRemovedSec += f.endSec - f.startSec;
|
|
206
|
+
// For merged ranges the .text is "a + b" — we count each token.
|
|
207
|
+
for (const piece of f.text.split(/\s*\+\s*/)) {
|
|
208
|
+
counts.set(piece, (counts.get(piece) ?? 0) + 1);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
const topFillers = [...counts.entries()]
|
|
212
|
+
.map(([text, count]) => ({ text, count }))
|
|
213
|
+
.sort((a, b) => b.count - a.count)
|
|
214
|
+
.slice(0, 5);
|
|
215
|
+
return {
|
|
216
|
+
count: fillers.length,
|
|
217
|
+
totalRemovedSec: +totalRemovedSec.toFixed(3),
|
|
218
|
+
topFillers,
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
//# sourceMappingURL=filler-words.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filler-words.js","sourceRoot":"","sources":["../../src/core/filler-words.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filler-words.test.d.ts","sourceRoot":"","sources":["../../src/core/filler-words.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { detectFillerRanges, keepRangesFromFillers, keepRangesToFrameRanges, summarizeFillers, } from "./filler-words.js";
|
|
3
|
+
/**
|
|
4
|
+
* Build a synthetic transcript whose words have known timing. Each word
|
|
5
|
+
* is 0.3s long with a 0.05s gap between, starting at `startAt`.
|
|
6
|
+
*/
|
|
7
|
+
function makeTranscript(text, startAt = 0) {
|
|
8
|
+
const tokens = text.split(/\s+/).filter(Boolean);
|
|
9
|
+
let t = startAt;
|
|
10
|
+
const words = tokens.map((tok) => {
|
|
11
|
+
const start = t;
|
|
12
|
+
const end = t + 0.3;
|
|
13
|
+
t = end + 0.05;
|
|
14
|
+
return { start, end, text: tok };
|
|
15
|
+
});
|
|
16
|
+
return {
|
|
17
|
+
language: "en",
|
|
18
|
+
durationSec: t,
|
|
19
|
+
segments: [
|
|
20
|
+
{
|
|
21
|
+
start: words[0]?.start ?? 0,
|
|
22
|
+
end: words[words.length - 1]?.end ?? 0,
|
|
23
|
+
text: tokens.join(" "),
|
|
24
|
+
words,
|
|
25
|
+
},
|
|
26
|
+
],
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
describe("detectFillerRanges", () => {
|
|
30
|
+
it("finds single-word fillers (um, uh)", () => {
|
|
31
|
+
const t = makeTranscript("hello um world uh goodbye");
|
|
32
|
+
const fillers = detectFillerRanges(t);
|
|
33
|
+
expect(fillers).toHaveLength(2);
|
|
34
|
+
expect(fillers[0].text).toBe("um");
|
|
35
|
+
expect(fillers[1].text).toBe("uh");
|
|
36
|
+
});
|
|
37
|
+
it("matches multi-word phrases (you know)", () => {
|
|
38
|
+
const t = makeTranscript("the answer you know is forty two");
|
|
39
|
+
const fillers = detectFillerRanges(t);
|
|
40
|
+
expect(fillers).toHaveLength(1);
|
|
41
|
+
expect(fillers[0].text).toBe("you know");
|
|
42
|
+
// The cut should span both words.
|
|
43
|
+
const word2 = t.segments[0].words[2]; // "you"
|
|
44
|
+
const word3 = t.segments[0].words[3]; // "know"
|
|
45
|
+
expect(fillers[0].startSec).toBeLessThanOrEqual(word2.start);
|
|
46
|
+
expect(fillers[0].endSec).toBeGreaterThanOrEqual(word3.end);
|
|
47
|
+
});
|
|
48
|
+
it("multi-word phrases match before single-word substrings", () => {
|
|
49
|
+
// 'you know' is multi-word filler. 'know' alone is not.
|
|
50
|
+
const t = makeTranscript("you know about it");
|
|
51
|
+
const fillers = detectFillerRanges(t);
|
|
52
|
+
expect(fillers).toHaveLength(1);
|
|
53
|
+
expect(fillers[0].text).toBe("you know");
|
|
54
|
+
expect(fillers[0].endWordIndex - fillers[0].startWordIndex).toBe(2);
|
|
55
|
+
});
|
|
56
|
+
it("strips punctuation when matching ('Um,' → 'um')", () => {
|
|
57
|
+
const t = makeTranscript("Hello Um, world.");
|
|
58
|
+
const fillers = detectFillerRanges(t);
|
|
59
|
+
expect(fillers).toHaveLength(1);
|
|
60
|
+
expect(fillers[0].text).toBe("um");
|
|
61
|
+
});
|
|
62
|
+
it("merges adjacent fillers within mergeGapMs", () => {
|
|
63
|
+
// "um uh" with a 0.05s gap between words — well within default 150ms.
|
|
64
|
+
const t = makeTranscript("um uh hello");
|
|
65
|
+
const fillers = detectFillerRanges(t);
|
|
66
|
+
expect(fillers).toHaveLength(1);
|
|
67
|
+
expect(fillers[0].text).toContain("um");
|
|
68
|
+
expect(fillers[0].text).toContain("uh");
|
|
69
|
+
});
|
|
70
|
+
it("respects custom vocabulary", () => {
|
|
71
|
+
const t = makeTranscript("hello banana world");
|
|
72
|
+
const fillers = detectFillerRanges(t, { fillers: ["banana"] });
|
|
73
|
+
expect(fillers).toHaveLength(1);
|
|
74
|
+
expect(fillers[0].text).toBe("banana");
|
|
75
|
+
});
|
|
76
|
+
it("aggressiveSingleWords=false skips 'like' / 'so' / 'actually'", () => {
|
|
77
|
+
const t = makeTranscript("i like the so called actually working idea");
|
|
78
|
+
// Default: aggressive=true → these match.
|
|
79
|
+
expect(detectFillerRanges(t).length).toBeGreaterThan(0);
|
|
80
|
+
// Off: only the safe-list filler vocabulary applies.
|
|
81
|
+
const safe = detectFillerRanges(t, { aggressiveSingleWords: false });
|
|
82
|
+
expect(safe).toHaveLength(0);
|
|
83
|
+
});
|
|
84
|
+
it("returns empty when transcript has no word timings", () => {
|
|
85
|
+
const t = {
|
|
86
|
+
language: "en",
|
|
87
|
+
durationSec: 5,
|
|
88
|
+
segments: [{ start: 0, end: 5, text: "um hello uh world" }],
|
|
89
|
+
};
|
|
90
|
+
expect(detectFillerRanges(t)).toEqual([]);
|
|
91
|
+
});
|
|
92
|
+
it("applies start/end padding to cut ranges", () => {
|
|
93
|
+
const t = makeTranscript("hello um world");
|
|
94
|
+
const um = t.segments[0].words[1];
|
|
95
|
+
const fillers = detectFillerRanges(t, { paddingStartMs: 50, paddingEndMs: 50 });
|
|
96
|
+
expect(fillers[0].startSec).toBeCloseTo(um.start - 0.05, 3);
|
|
97
|
+
expect(fillers[0].endSec).toBeCloseTo(um.end + 0.05, 3);
|
|
98
|
+
});
|
|
99
|
+
it("clamps the start padding so it never goes negative", () => {
|
|
100
|
+
const t = makeTranscript("um hello world");
|
|
101
|
+
const fillers = detectFillerRanges(t, { paddingStartMs: 9999 });
|
|
102
|
+
expect(fillers[0].startSec).toBe(0);
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
describe("keepRangesFromFillers", () => {
|
|
106
|
+
it("emits the inverse of filler ranges", () => {
|
|
107
|
+
const fillers = [
|
|
108
|
+
{ startSec: 1, endSec: 2, text: "um", startWordIndex: 0, endWordIndex: 1 },
|
|
109
|
+
{ startSec: 4, endSec: 5, text: "uh", startWordIndex: 0, endWordIndex: 1 },
|
|
110
|
+
];
|
|
111
|
+
const keeps = keepRangesFromFillers(fillers, 7);
|
|
112
|
+
expect(keeps).toEqual([
|
|
113
|
+
{ startSec: 0, endSec: 1 },
|
|
114
|
+
{ startSec: 2, endSec: 4 },
|
|
115
|
+
{ startSec: 5, endSec: 7 },
|
|
116
|
+
]);
|
|
117
|
+
});
|
|
118
|
+
it("returns the whole timeline when there are no fillers", () => {
|
|
119
|
+
expect(keepRangesFromFillers([], 10)).toEqual([{ startSec: 0, endSec: 10 }]);
|
|
120
|
+
});
|
|
121
|
+
it("handles fillers at the very start and end", () => {
|
|
122
|
+
const fillers = [
|
|
123
|
+
{ startSec: 0, endSec: 0.5, text: "um", startWordIndex: 0, endWordIndex: 1 },
|
|
124
|
+
{ startSec: 4.5, endSec: 5, text: "uh", startWordIndex: 0, endWordIndex: 1 },
|
|
125
|
+
];
|
|
126
|
+
const keeps = keepRangesFromFillers(fillers, 5);
|
|
127
|
+
expect(keeps).toEqual([{ startSec: 0.5, endSec: 4.5 }]);
|
|
128
|
+
});
|
|
129
|
+
it("drops sub-minimum keep ranges", () => {
|
|
130
|
+
const fillers = [
|
|
131
|
+
{ startSec: 1, endSec: 2, text: "um", startWordIndex: 0, endWordIndex: 1 },
|
|
132
|
+
{ startSec: 2.02, endSec: 3, text: "uh", startWordIndex: 0, endWordIndex: 1 },
|
|
133
|
+
];
|
|
134
|
+
const keeps = keepRangesFromFillers(fillers, 5, 0.05);
|
|
135
|
+
// The 0.02s gap between the two fillers should be dropped.
|
|
136
|
+
expect(keeps).toEqual([
|
|
137
|
+
{ startSec: 0, endSec: 1 },
|
|
138
|
+
{ startSec: 3, endSec: 5 },
|
|
139
|
+
]);
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
describe("keepRangesToFrameRanges", () => {
|
|
143
|
+
it("rounds inward (ceil start, floor end)", () => {
|
|
144
|
+
const keeps = [{ startSec: 0.4, endSec: 1.6 }];
|
|
145
|
+
const frames = keepRangesToFrameRanges(keeps, 30);
|
|
146
|
+
expect(frames).toEqual([{ startFrame: 12, endFrame: 48 }]);
|
|
147
|
+
});
|
|
148
|
+
it("drops zero-frame ranges after rounding", () => {
|
|
149
|
+
// ceil(0.97 * 30) = 30; floor(1.0 * 30) = 30 — zero-frame range, dropped.
|
|
150
|
+
const keeps = [{ startSec: 0.97, endSec: 1.0 }];
|
|
151
|
+
const frames = keepRangesToFrameRanges(keeps, 30);
|
|
152
|
+
expect(frames).toEqual([]);
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
describe("summarizeFillers", () => {
|
|
156
|
+
it("counts occurrences and total removed time", () => {
|
|
157
|
+
const fillers = [
|
|
158
|
+
{ startSec: 0, endSec: 0.3, text: "um", startWordIndex: 0, endWordIndex: 1 },
|
|
159
|
+
{ startSec: 1, endSec: 1.5, text: "um", startWordIndex: 0, endWordIndex: 1 },
|
|
160
|
+
{ startSec: 2, endSec: 2.5, text: "uh", startWordIndex: 0, endWordIndex: 1 },
|
|
161
|
+
];
|
|
162
|
+
const stats = summarizeFillers(fillers);
|
|
163
|
+
expect(stats.count).toBe(3);
|
|
164
|
+
expect(stats.totalRemovedSec).toBeCloseTo(1.3, 3);
|
|
165
|
+
expect(stats.topFillers[0]).toEqual({ text: "um", count: 2 });
|
|
166
|
+
expect(stats.topFillers[1]).toEqual({ text: "uh", count: 1 });
|
|
167
|
+
});
|
|
168
|
+
it("splits merged fillers when counting", () => {
|
|
169
|
+
const fillers = [
|
|
170
|
+
{ startSec: 0, endSec: 0.5, text: "um + uh", startWordIndex: 0, endWordIndex: 2 },
|
|
171
|
+
];
|
|
172
|
+
const stats = summarizeFillers(fillers);
|
|
173
|
+
const counts = Object.fromEntries(stats.topFillers.map((f) => [f.text, f.count]));
|
|
174
|
+
expect(counts).toEqual({ um: 1, uh: 1 });
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
//# sourceMappingURL=filler-words.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filler-words.test.js","sourceRoot":"","sources":["../../src/core/filler-words.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Output formatters — all tool results pass through here.
|
|
3
|
+
*
|
|
4
|
+
* Design rule: tool output is consumed by an LLM, never a human directly.
|
|
5
|
+
* Optimize for token economy and machine parsability:
|
|
6
|
+
* - No prose filler ("I successfully did X").
|
|
7
|
+
* - No labels the LLM can already infer from the call it just made.
|
|
8
|
+
* - JSON when fields > 1; bare value when result is a single fact.
|
|
9
|
+
* - Errors: "error: <cause>; fix: <next-step>" — one line, actionable.
|
|
10
|
+
* - Cap unbounded lists with a summary header.
|
|
11
|
+
*/
|
|
12
|
+
/** Render a value as compact JSON (no whitespace). Drops null/undefined keys. */
|
|
13
|
+
export declare function compact(value: unknown): string;
|
|
14
|
+
/** Standard one-line error format. */
|
|
15
|
+
export declare function err(cause: string, fix?: string): string;
|
|
16
|
+
/**
|
|
17
|
+
* Frames → SMPTE timecode (HH:MM:SS:FF). Used for EDL emission.
|
|
18
|
+
* Non-drop frame; agent is responsible for fps choice.
|
|
19
|
+
*/
|
|
20
|
+
export declare function framesToTimecode(frames: number, fps: number): string;
|
|
21
|
+
/**
|
|
22
|
+
* Truncate a list with a summary header when it exceeds `keep`. Always shows
|
|
23
|
+
* the first and last `keep/2` items so the LLM sees both endpoints.
|
|
24
|
+
*
|
|
25
|
+
* summarizeList([1,2,…,200], 10) →
|
|
26
|
+
* { head: [1..5], tail: [196..200], total: 200, omitted: 190 }
|
|
27
|
+
*/
|
|
28
|
+
export declare function summarizeList<T>(items: T[], keep?: number): {
|
|
29
|
+
head: T[];
|
|
30
|
+
tail: T[];
|
|
31
|
+
total: number;
|
|
32
|
+
omitted: number;
|
|
33
|
+
};
|
|
34
|
+
/** Cap a string at `max` chars with a single-char ellipsis suffix. */
|
|
35
|
+
export declare function clip(s: string, max: number): string;
|
|
36
|
+
//# sourceMappingURL=format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/core/format.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,iFAAiF;AACjF,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAE9C;AAED,sCAAsC;AACtC,wBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CASpE;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAC7B,KAAK,EAAE,CAAC,EAAE,EACV,IAAI,SAAK,GACR;IACD,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB,CASA;AAED,sEAAsE;AACtE,wBAAgB,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAEnD"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Output formatters — all tool results pass through here.
|
|
3
|
+
*
|
|
4
|
+
* Design rule: tool output is consumed by an LLM, never a human directly.
|
|
5
|
+
* Optimize for token economy and machine parsability:
|
|
6
|
+
* - No prose filler ("I successfully did X").
|
|
7
|
+
* - No labels the LLM can already infer from the call it just made.
|
|
8
|
+
* - JSON when fields > 1; bare value when result is a single fact.
|
|
9
|
+
* - Errors: "error: <cause>; fix: <next-step>" — one line, actionable.
|
|
10
|
+
* - Cap unbounded lists with a summary header.
|
|
11
|
+
*/
|
|
12
|
+
/** Render a value as compact JSON (no whitespace). Drops null/undefined keys. */
|
|
13
|
+
export function compact(value) {
|
|
14
|
+
return JSON.stringify(value, (_k, v) => (v === null || v === undefined ? undefined : v));
|
|
15
|
+
}
|
|
16
|
+
/** Standard one-line error format. */
|
|
17
|
+
export function err(cause, fix) {
|
|
18
|
+
return fix ? `error: ${cause}; fix: ${fix}` : `error: ${cause}`;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Frames → SMPTE timecode (HH:MM:SS:FF). Used for EDL emission.
|
|
22
|
+
* Non-drop frame; agent is responsible for fps choice.
|
|
23
|
+
*/
|
|
24
|
+
export function framesToTimecode(frames, fps) {
|
|
25
|
+
if (frames < 0)
|
|
26
|
+
frames = 0;
|
|
27
|
+
const ifps = Math.round(fps); // EDL uses integer fps; 23.976 → 24, 29.97 → 30
|
|
28
|
+
const totalSec = Math.floor(frames / ifps);
|
|
29
|
+
const ff = frames % ifps;
|
|
30
|
+
const hh = Math.floor(totalSec / 3600);
|
|
31
|
+
const mm = Math.floor((totalSec % 3600) / 60);
|
|
32
|
+
const ss = totalSec % 60;
|
|
33
|
+
return [hh, mm, ss, ff].map((n) => String(n).padStart(2, "0")).join(":");
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Truncate a list with a summary header when it exceeds `keep`. Always shows
|
|
37
|
+
* the first and last `keep/2` items so the LLM sees both endpoints.
|
|
38
|
+
*
|
|
39
|
+
* summarizeList([1,2,…,200], 10) →
|
|
40
|
+
* { head: [1..5], tail: [196..200], total: 200, omitted: 190 }
|
|
41
|
+
*/
|
|
42
|
+
export function summarizeList(items, keep = 20) {
|
|
43
|
+
if (items.length <= keep)
|
|
44
|
+
return { head: items, tail: [], total: items.length, omitted: 0 };
|
|
45
|
+
const half = Math.floor(keep / 2);
|
|
46
|
+
return {
|
|
47
|
+
head: items.slice(0, half),
|
|
48
|
+
tail: items.slice(-half),
|
|
49
|
+
total: items.length,
|
|
50
|
+
omitted: items.length - half * 2,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/** Cap a string at `max` chars with a single-char ellipsis suffix. */
|
|
54
|
+
export function clip(s, max) {
|
|
55
|
+
return s.length <= max ? s : s.slice(0, max - 1) + "…";
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/core/format.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,iFAAiF;AACjF,MAAM,UAAU,OAAO,CAAC,KAAc;IACpC,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3F,CAAC;AAED,sCAAsC;AACtC,MAAM,UAAU,GAAG,CAAC,KAAa,EAAE,GAAY;IAC7C,OAAO,GAAG,CAAC,CAAC,CAAC,UAAU,KAAK,UAAU,GAAG,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,EAAE,CAAC;AAClE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAc,EAAE,GAAW;IAC1D,IAAI,MAAM,GAAG,CAAC;QAAE,MAAM,GAAG,CAAC,CAAC;IAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,gDAAgD;IAC9E,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC3C,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;IACvC,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IAC9C,MAAM,EAAE,GAAG,QAAQ,GAAG,EAAE,CAAC;IACzB,OAAO,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC3E,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAC3B,KAAU,EACV,IAAI,GAAG,EAAE;IAOT,IAAI,KAAK,CAAC,MAAM,IAAI,IAAI;QAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;IAC5F,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;IAClC,OAAO;QACL,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC;QAC1B,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC;QACxB,KAAK,EAAE,KAAK,CAAC,MAAM;QACnB,OAAO,EAAE,KAAK,CAAC,MAAM,GAAG,IAAI,GAAG,CAAC;KACjC,CAAC;AACJ,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,IAAI,CAAC,CAAS,EAAE,GAAW;IACzC,OAAO,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;AACzD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.test.d.ts","sourceRoot":"","sources":["../../src/core/format.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { clip, compact, err, framesToTimecode, summarizeList } from "./format.js";
|
|
3
|
+
describe("compact", () => {
|
|
4
|
+
it("emits no whitespace", () => {
|
|
5
|
+
expect(compact({ a: 1, b: "x" })).toBe('{"a":1,"b":"x"}');
|
|
6
|
+
});
|
|
7
|
+
it("strips null/undefined fields", () => {
|
|
8
|
+
expect(compact({ a: 1, b: null, c: undefined, d: 2 })).toBe('{"a":1,"d":2}');
|
|
9
|
+
});
|
|
10
|
+
});
|
|
11
|
+
describe("err", () => {
|
|
12
|
+
it("formats cause only", () => {
|
|
13
|
+
expect(err("bad input")).toBe("error: bad input");
|
|
14
|
+
});
|
|
15
|
+
it("formats cause + fix", () => {
|
|
16
|
+
expect(err("no python", "install python3")).toBe("error: no python; fix: install python3");
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
describe("framesToTimecode", () => {
|
|
20
|
+
it("formats zero", () => {
|
|
21
|
+
expect(framesToTimecode(0, 30)).toBe("00:00:00:00");
|
|
22
|
+
});
|
|
23
|
+
it("formats one second", () => {
|
|
24
|
+
expect(framesToTimecode(30, 30)).toBe("00:00:01:00");
|
|
25
|
+
});
|
|
26
|
+
it("formats sub-second remainder", () => {
|
|
27
|
+
expect(framesToTimecode(45, 30)).toBe("00:00:01:15");
|
|
28
|
+
});
|
|
29
|
+
it("formats hours/minutes", () => {
|
|
30
|
+
expect(framesToTimecode(30 * 3725, 30)).toBe("01:02:05:00");
|
|
31
|
+
});
|
|
32
|
+
it("rounds fractional fps", () => {
|
|
33
|
+
expect(framesToTimecode(24, 23.976)).toBe("00:00:01:00");
|
|
34
|
+
});
|
|
35
|
+
it("clamps negative frames to zero", () => {
|
|
36
|
+
// The CMX 3600 spec doesn't allow negative timecode; we clamp instead of
|
|
37
|
+
// emitting a malformed string.
|
|
38
|
+
expect(framesToTimecode(-30, 30)).toBe("00:00:00:00");
|
|
39
|
+
});
|
|
40
|
+
it("handles 24 hours of footage at 30fps without overflow into 3-digit hours", () => {
|
|
41
|
+
// 24 hours = 24 * 3600 * 30 = 2,592,000 frames — should land at 24:00:00:00.
|
|
42
|
+
expect(framesToTimecode(2592000, 30)).toBe("24:00:00:00");
|
|
43
|
+
});
|
|
44
|
+
it("emits 3-digit hour fields when needed (no truncation)", () => {
|
|
45
|
+
// 100 hours — padStart(2) doesn't TRUNCATE, so we get "100:00:00:00".
|
|
46
|
+
// Out-of-spec for strict CMX 3600 but the most defensive choice.
|
|
47
|
+
const r = framesToTimecode(100 * 3600 * 30, 30);
|
|
48
|
+
expect(r).toBe("100:00:00:00");
|
|
49
|
+
});
|
|
50
|
+
it("frame field never overflows the integer fps (no '60' frames at 30fps)", () => {
|
|
51
|
+
// 30 frames at 30fps must roll into 1 second, NOT show ff=30.
|
|
52
|
+
expect(framesToTimecode(30, 30)).toBe("00:00:01:00");
|
|
53
|
+
// 59 frames at 30fps = 1 sec + 29 frames
|
|
54
|
+
expect(framesToTimecode(59, 30)).toBe("00:00:01:29");
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
describe("summarizeList", () => {
|
|
58
|
+
it("returns head only when under keep", () => {
|
|
59
|
+
const r = summarizeList([1, 2, 3], 10);
|
|
60
|
+
expect(r.total).toBe(3);
|
|
61
|
+
expect(r.omitted).toBe(0);
|
|
62
|
+
expect(r.head).toEqual([1, 2, 3]);
|
|
63
|
+
expect(r.tail).toEqual([]);
|
|
64
|
+
});
|
|
65
|
+
it("splits head/tail when over keep", () => {
|
|
66
|
+
const r = summarizeList(Array.from({ length: 100 }, (_, i) => i + 1), 10);
|
|
67
|
+
expect(r.total).toBe(100);
|
|
68
|
+
expect(r.omitted).toBe(90);
|
|
69
|
+
expect(r.head).toEqual([1, 2, 3, 4, 5]);
|
|
70
|
+
expect(r.tail).toEqual([96, 97, 98, 99, 100]);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
describe("clip", () => {
|
|
74
|
+
it("returns input when short", () => {
|
|
75
|
+
expect(clip("hi", 10)).toBe("hi");
|
|
76
|
+
});
|
|
77
|
+
it("ellipsizes when long", () => {
|
|
78
|
+
expect(clip("0123456789", 5)).toBe("0123…");
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
//# sourceMappingURL=format.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.test.js","sourceRoot":"","sources":["../../src/core/format.test.ts"],"names":[],"mappings":"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"}
|