@kenkaiiii/gg-editor 0.6.7 → 0.7.1
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/dist/cli.js +64 -1
- package/dist/cli.js.map +1 -1
- package/dist/core/audio-mix.d.ts.map +1 -1
- package/dist/core/audio-mix.js +8 -1
- package/dist/core/audio-mix.js.map +1 -1
- package/dist/core/audio-mix.test.js +1 -1
- package/dist/core/audio-mix.test.js.map +1 -1
- package/dist/core/auth/api-keys.d.ts +1 -1
- package/dist/core/auth/api-keys.d.ts.map +1 -1
- package/dist/core/auth/api-keys.js +2 -1
- package/dist/core/auth/api-keys.js.map +1 -1
- package/dist/core/auth/index.d.ts +18 -5
- package/dist/core/auth/index.d.ts.map +1 -1
- package/dist/core/auth/index.js +16 -4
- package/dist/core/auth/index.js.map +1 -1
- package/dist/core/auth/login.d.ts.map +1 -1
- package/dist/core/auth/login.js +4 -31
- package/dist/core/auth/login.js.map +1 -1
- package/dist/core/beats.d.ts +59 -0
- package/dist/core/beats.d.ts.map +1 -0
- package/dist/core/beats.js +122 -0
- package/dist/core/beats.js.map +1 -0
- package/dist/core/beats.test.d.ts +2 -0
- package/dist/core/beats.test.d.ts.map +1 -0
- package/dist/core/beats.test.js +86 -0
- package/dist/core/beats.test.js.map +1 -0
- package/dist/core/brand-kit.d.ts +80 -0
- package/dist/core/brand-kit.d.ts.map +1 -0
- package/dist/core/brand-kit.js +96 -0
- package/dist/core/brand-kit.js.map +1 -0
- package/dist/core/brand-kit.test.d.ts +2 -0
- package/dist/core/brand-kit.test.d.ts.map +1 -0
- package/dist/core/brand-kit.test.js +76 -0
- package/dist/core/brand-kit.test.js.map +1 -0
- package/dist/core/bundled-sfx.d.ts +64 -0
- package/dist/core/bundled-sfx.d.ts.map +1 -0
- package/dist/core/bundled-sfx.js +218 -0
- package/dist/core/bundled-sfx.js.map +1 -0
- package/dist/core/bundled-sfx.test.d.ts +2 -0
- package/dist/core/bundled-sfx.test.d.ts.map +1 -0
- package/dist/core/bundled-sfx.test.js +81 -0
- package/dist/core/bundled-sfx.test.js.map +1 -0
- package/dist/core/child-abort.d.ts +57 -0
- package/dist/core/child-abort.d.ts.map +1 -0
- package/dist/core/child-abort.js +95 -0
- package/dist/core/child-abort.js.map +1 -0
- package/dist/core/child-abort.test.d.ts +2 -0
- package/dist/core/child-abort.test.d.ts.map +1 -0
- package/dist/core/child-abort.test.js +88 -0
- package/dist/core/child-abort.test.js.map +1 -0
- package/dist/core/clip-scoring.d.ts +44 -0
- package/dist/core/clip-scoring.d.ts.map +1 -0
- package/dist/core/clip-scoring.js +165 -0
- package/dist/core/clip-scoring.js.map +1 -0
- package/dist/core/clip-scoring.test.d.ts +2 -0
- package/dist/core/clip-scoring.test.d.ts.map +1 -0
- package/dist/core/clip-scoring.test.js +113 -0
- package/dist/core/clip-scoring.test.js.map +1 -0
- package/dist/core/emoji-captions.d.ts +45 -0
- package/dist/core/emoji-captions.d.ts.map +1 -0
- package/dist/core/emoji-captions.js +121 -0
- package/dist/core/emoji-captions.js.map +1 -0
- package/dist/core/face-reframe.d.ts +91 -0
- package/dist/core/face-reframe.d.ts.map +1 -0
- package/dist/core/face-reframe.js +141 -0
- package/dist/core/face-reframe.js.map +1 -0
- package/dist/core/face-reframe.test.d.ts +2 -0
- package/dist/core/face-reframe.test.d.ts.map +1 -0
- package/dist/core/face-reframe.test.js +171 -0
- package/dist/core/face-reframe.test.js.map +1 -0
- package/dist/core/filler-words.d.ts +57 -9
- package/dist/core/filler-words.d.ts.map +1 -1
- package/dist/core/filler-words.js +61 -9
- package/dist/core/filler-words.js.map +1 -1
- package/dist/core/filler-words.test.js +91 -17
- package/dist/core/filler-words.test.js.map +1 -1
- package/dist/core/hook-rewrite.d.ts +48 -0
- package/dist/core/hook-rewrite.d.ts.map +1 -0
- package/dist/core/hook-rewrite.js +151 -0
- package/dist/core/hook-rewrite.js.map +1 -0
- package/dist/core/hook-rewrite.test.d.ts +2 -0
- package/dist/core/hook-rewrite.test.d.ts.map +1 -0
- package/dist/core/hook-rewrite.test.js +58 -0
- package/dist/core/hook-rewrite.test.js.map +1 -0
- package/dist/core/hosts/lazy.d.ts.map +1 -1
- package/dist/core/hosts/lazy.js +2 -0
- package/dist/core/hosts/lazy.js.map +1 -1
- package/dist/core/hosts/premiere/adapter.d.ts +1 -0
- package/dist/core/hosts/premiere/adapter.d.ts.map +1 -1
- package/dist/core/hosts/premiere/adapter.js.map +1 -1
- package/dist/core/hosts/premiere/bridge-source.d.ts.map +1 -1
- package/dist/core/hosts/premiere/bridge-source.js +6 -3
- package/dist/core/hosts/premiere/bridge-source.js.map +1 -1
- package/dist/core/hosts/resolve/adapter.d.ts +1 -0
- package/dist/core/hosts/resolve/adapter.d.ts.map +1 -1
- package/dist/core/hosts/resolve/adapter.js.map +1 -1
- package/dist/core/hosts/resolve/bridge-source.d.ts.map +1 -1
- package/dist/core/hosts/resolve/bridge-source.js +31 -4
- package/dist/core/hosts/resolve/bridge-source.js.map +1 -1
- package/dist/core/hosts/resolve/bridge.d.ts +2 -19
- package/dist/core/hosts/resolve/bridge.d.ts.map +1 -1
- package/dist/core/hosts/resolve/bridge.js +70 -41
- package/dist/core/hosts/resolve/bridge.js.map +1 -1
- package/dist/core/hosts/resolve/bridge.test.js +130 -0
- package/dist/core/hosts/resolve/bridge.test.js.map +1 -1
- package/dist/core/hosts/types.d.ts +6 -0
- package/dist/core/hosts/types.d.ts.map +1 -1
- package/dist/core/hosts/types.js.map +1 -1
- package/dist/core/logger.d.ts +32 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +188 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/loop-match.d.ts +57 -0
- package/dist/core/loop-match.d.ts.map +1 -0
- package/dist/core/loop-match.js +91 -0
- package/dist/core/loop-match.js.map +1 -0
- package/dist/core/media/ffmpeg.d.ts.map +1 -1
- package/dist/core/media/ffmpeg.js +14 -3
- package/dist/core/media/ffmpeg.js.map +1 -1
- package/dist/core/multi-format.d.ts +67 -0
- package/dist/core/multi-format.d.ts.map +1 -0
- package/dist/core/multi-format.js +127 -0
- package/dist/core/multi-format.js.map +1 -0
- package/dist/core/multi-format.test.d.ts +2 -0
- package/dist/core/multi-format.test.d.ts.map +1 -0
- package/dist/core/multi-format.test.js +151 -0
- package/dist/core/multi-format.test.js.map +1 -0
- package/dist/core/python/beats.py +61 -0
- package/dist/core/python/face_reframe.py +163 -0
- package/dist/core/python/sidecar-path.d.ts +13 -0
- package/dist/core/python/sidecar-path.d.ts.map +1 -0
- package/dist/core/python/sidecar-path.js +24 -0
- package/dist/core/python/sidecar-path.js.map +1 -0
- package/dist/core/python.d.ts +57 -0
- package/dist/core/python.d.ts.map +1 -0
- package/dist/core/python.js +107 -0
- package/dist/core/python.js.map +1 -0
- package/dist/core/python.test.d.ts +2 -0
- package/dist/core/python.test.d.ts.map +1 -0
- package/dist/core/python.test.js +129 -0
- package/dist/core/python.test.js.map +1 -0
- package/dist/core/retention-structure.d.ts +81 -0
- package/dist/core/retention-structure.d.ts.map +1 -0
- package/dist/core/retention-structure.js +206 -0
- package/dist/core/retention-structure.js.map +1 -0
- package/dist/core/retention-structure.test.d.ts +2 -0
- package/dist/core/retention-structure.test.d.ts.map +1 -0
- package/dist/core/retention-structure.test.js +88 -0
- package/dist/core/retention-structure.test.js.map +1 -0
- package/dist/core/review.d.ts +17 -0
- package/dist/core/review.d.ts.map +1 -1
- package/dist/core/review.js +20 -24
- package/dist/core/review.js.map +1 -1
- package/dist/core/safe-paths.d.ts +11 -0
- package/dist/core/safe-paths.d.ts.map +1 -1
- package/dist/core/safe-paths.js +26 -10
- package/dist/core/safe-paths.js.map +1 -1
- package/dist/core/safe-paths.test.js +16 -0
- package/dist/core/safe-paths.test.js.map +1 -1
- package/dist/core/skills-loader.d.ts +48 -2
- package/dist/core/skills-loader.d.ts.map +1 -1
- package/dist/core/skills-loader.js +97 -19
- package/dist/core/skills-loader.js.map +1 -1
- package/dist/core/skills-loader.test.js +63 -1
- package/dist/core/skills-loader.test.js.map +1 -1
- package/dist/core/srt.d.ts +42 -7
- package/dist/core/srt.d.ts.map +1 -1
- package/dist/core/srt.js +101 -32
- package/dist/core/srt.js.map +1 -1
- package/dist/core/srt.test.js +54 -1
- package/dist/core/srt.test.js.map +1 -1
- package/dist/core/thumbnail-compose.d.ts +58 -0
- package/dist/core/thumbnail-compose.d.ts.map +1 -0
- package/dist/core/thumbnail-compose.js +101 -0
- package/dist/core/thumbnail-compose.js.map +1 -0
- package/dist/core/thumbnail-promise.d.ts +46 -0
- package/dist/core/thumbnail-promise.d.ts.map +1 -0
- package/dist/core/thumbnail-promise.js +133 -0
- package/dist/core/thumbnail-promise.js.map +1 -0
- package/dist/core/thumbnail-promise.test.d.ts +2 -0
- package/dist/core/thumbnail-promise.test.d.ts.map +1 -0
- package/dist/core/thumbnail-promise.test.js +52 -0
- package/dist/core/thumbnail-promise.test.js.map +1 -0
- package/dist/core/viral-moments.d.ts +70 -0
- package/dist/core/viral-moments.d.ts.map +1 -0
- package/dist/core/viral-moments.js +192 -0
- package/dist/core/viral-moments.js.map +1 -0
- package/dist/core/viral-moments.test.d.ts +2 -0
- package/dist/core/viral-moments.test.d.ts.map +1 -0
- package/dist/core/viral-moments.test.js +153 -0
- package/dist/core/viral-moments.test.js.map +1 -0
- package/dist/core/whisper.d.ts +16 -0
- package/dist/core/whisper.d.ts.map +1 -1
- package/dist/core/whisper.js +72 -5
- package/dist/core/whisper.js.map +1 -1
- package/dist/core/whisper.test.js +111 -1
- package/dist/core/whisper.test.js.map +1 -1
- package/dist/core/youtube-metadata.d.ts +44 -0
- package/dist/core/youtube-metadata.d.ts.map +1 -0
- package/dist/core/youtube-metadata.js +168 -0
- package/dist/core/youtube-metadata.js.map +1 -0
- package/dist/core/youtube-metadata.test.d.ts +2 -0
- package/dist/core/youtube-metadata.test.d.ts.map +1 -0
- package/dist/core/youtube-metadata.test.js +132 -0
- package/dist/core/youtube-metadata.test.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/prompt-commands.d.ts +24 -0
- package/dist/prompt-commands.d.ts.map +1 -0
- package/dist/prompt-commands.js +243 -0
- package/dist/prompt-commands.js.map +1 -0
- package/dist/prompt-commands.test.d.ts +2 -0
- package/dist/prompt-commands.test.d.ts.map +1 -0
- package/dist/prompt-commands.test.js +46 -0
- package/dist/prompt-commands.test.js.map +1 -0
- package/dist/skills.d.ts +6 -6
- package/dist/skills.d.ts.map +1 -1
- package/dist/skills.js +1426 -445
- package/dist/skills.js.map +1 -1
- package/dist/system-prompt.d.ts.map +1 -1
- package/dist/system-prompt.js +108 -0
- package/dist/system-prompt.js.map +1 -1
- package/dist/tools/add-fades.d.ts.map +1 -1
- package/dist/tools/add-fades.js +2 -1
- package/dist/tools/add-fades.js.map +1 -1
- package/dist/tools/add-sfx-at-cuts.d.ts.map +1 -1
- package/dist/tools/add-sfx-at-cuts.js +36 -11
- package/dist/tools/add-sfx-at-cuts.js.map +1 -1
- package/dist/tools/add-sfx-to-timeline.d.ts +34 -0
- package/dist/tools/add-sfx-to-timeline.d.ts.map +1 -0
- package/dist/tools/add-sfx-to-timeline.js +169 -0
- package/dist/tools/add-sfx-to-timeline.js.map +1 -0
- package/dist/tools/add-sfx-to-timeline.test.d.ts +2 -0
- package/dist/tools/add-sfx-to-timeline.test.d.ts.map +1 -0
- package/dist/tools/add-sfx-to-timeline.test.js +181 -0
- package/dist/tools/add-sfx-to-timeline.test.js.map +1 -0
- package/dist/tools/audit-first-frame.d.ts +36 -0
- package/dist/tools/audit-first-frame.d.ts.map +1 -0
- package/dist/tools/audit-first-frame.js +181 -0
- package/dist/tools/audit-first-frame.js.map +1 -0
- package/dist/tools/audit-retention-structure.d.ts +20 -0
- package/dist/tools/audit-retention-structure.d.ts.map +1 -0
- package/dist/tools/audit-retention-structure.js +95 -0
- package/dist/tools/audit-retention-structure.js.map +1 -0
- package/dist/tools/audit-retention-structure.test.d.ts +2 -0
- package/dist/tools/audit-retention-structure.test.d.ts.map +1 -0
- package/dist/tools/audit-retention-structure.test.js +93 -0
- package/dist/tools/audit-retention-structure.test.js.map +1 -0
- package/dist/tools/bleep-words.d.ts +59 -0
- package/dist/tools/bleep-words.d.ts.map +1 -0
- package/dist/tools/bleep-words.js +211 -0
- package/dist/tools/bleep-words.js.map +1 -0
- package/dist/tools/bleep-words.test.d.ts +2 -0
- package/dist/tools/bleep-words.test.d.ts.map +1 -0
- package/dist/tools/bleep-words.test.js +96 -0
- package/dist/tools/bleep-words.test.js.map +1 -0
- package/dist/tools/burn-subtitles.d.ts.map +1 -1
- package/dist/tools/burn-subtitles.js +10 -5
- package/dist/tools/burn-subtitles.js.map +1 -1
- package/dist/tools/clean-audio.d.ts.map +1 -1
- package/dist/tools/clean-audio.js +2 -1
- package/dist/tools/clean-audio.js.map +1 -1
- package/dist/tools/cluster-takes.js +2 -1
- package/dist/tools/cluster-takes.js.map +1 -1
- package/dist/tools/compose-thumbnail-variants.d.ts +70 -0
- package/dist/tools/compose-thumbnail-variants.d.ts.map +1 -0
- package/dist/tools/compose-thumbnail-variants.js +274 -0
- package/dist/tools/compose-thumbnail-variants.js.map +1 -0
- package/dist/tools/compose-thumbnail.d.ts +6 -13
- package/dist/tools/compose-thumbnail.d.ts.map +1 -1
- package/dist/tools/compose-thumbnail.js +44 -81
- package/dist/tools/compose-thumbnail.js.map +1 -1
- package/dist/tools/concat-videos.d.ts.map +1 -1
- package/dist/tools/concat-videos.js +12 -5
- package/dist/tools/concat-videos.js.map +1 -1
- package/dist/tools/concat-videos.test.d.ts +2 -0
- package/dist/tools/concat-videos.test.d.ts.map +1 -0
- package/dist/tools/concat-videos.test.js +103 -0
- package/dist/tools/concat-videos.test.js.map +1 -0
- package/dist/tools/crossfade-videos.d.ts.map +1 -1
- package/dist/tools/crossfade-videos.js +2 -1
- package/dist/tools/crossfade-videos.js.map +1 -1
- package/dist/tools/cut-filler-words.d.ts.map +1 -1
- package/dist/tools/cut-filler-words.js +24 -8
- package/dist/tools/cut-filler-words.js.map +1 -1
- package/dist/tools/detect-speaker-changes.js +2 -1
- package/dist/tools/detect-speaker-changes.js.map +1 -1
- package/dist/tools/extract-audio.d.ts.map +1 -1
- package/dist/tools/extract-audio.js +13 -7
- package/dist/tools/extract-audio.js.map +1 -1
- package/dist/tools/face-reframe.d.ts +30 -0
- package/dist/tools/face-reframe.d.ts.map +1 -0
- package/dist/tools/face-reframe.js +143 -0
- package/dist/tools/face-reframe.js.map +1 -0
- package/dist/tools/face-reframe.test.d.ts +2 -0
- package/dist/tools/face-reframe.test.d.ts.map +1 -0
- package/dist/tools/face-reframe.test.js +139 -0
- package/dist/tools/face-reframe.test.js.map +1 -0
- package/dist/tools/find-viral-moments.d.ts +23 -0
- package/dist/tools/find-viral-moments.d.ts.map +1 -0
- package/dist/tools/find-viral-moments.js +176 -0
- package/dist/tools/find-viral-moments.js.map +1 -0
- package/dist/tools/find-viral-moments.test.d.ts +2 -0
- package/dist/tools/find-viral-moments.test.d.ts.map +1 -0
- package/dist/tools/find-viral-moments.test.js +144 -0
- package/dist/tools/find-viral-moments.test.js.map +1 -0
- package/dist/tools/generate-gif.d.ts.map +1 -1
- package/dist/tools/generate-gif.js +47 -40
- package/dist/tools/generate-gif.js.map +1 -1
- package/dist/tools/generate-gif.test.d.ts +2 -0
- package/dist/tools/generate-gif.test.d.ts.map +1 -0
- package/dist/tools/generate-gif.test.js +115 -0
- package/dist/tools/generate-gif.test.js.map +1 -0
- package/dist/tools/generate-outro.d.ts +18 -0
- package/dist/tools/generate-outro.d.ts.map +1 -0
- package/dist/tools/generate-outro.js +175 -0
- package/dist/tools/generate-outro.js.map +1 -0
- package/dist/tools/generate-youtube-metadata.d.ts +23 -0
- package/dist/tools/generate-youtube-metadata.d.ts.map +1 -0
- package/dist/tools/generate-youtube-metadata.js +103 -0
- package/dist/tools/generate-youtube-metadata.js.map +1 -0
- package/dist/tools/generate-youtube-metadata.test.d.ts +2 -0
- package/dist/tools/generate-youtube-metadata.test.d.ts.map +1 -0
- package/dist/tools/generate-youtube-metadata.test.js +118 -0
- package/dist/tools/generate-youtube-metadata.test.js.map +1 -0
- package/dist/tools/index.d.ts +14 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +130 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/index.test.js +27 -1
- package/dist/tools/index.test.js.map +1 -1
- package/dist/tools/ken-burns.d.ts.map +1 -1
- package/dist/tools/ken-burns.js +2 -1
- package/dist/tools/ken-burns.js.map +1 -1
- package/dist/tools/loop-match-short.d.ts +22 -0
- package/dist/tools/loop-match-short.d.ts.map +1 -0
- package/dist/tools/loop-match-short.js +107 -0
- package/dist/tools/loop-match-short.js.map +1 -0
- package/dist/tools/mix-audio.d.ts.map +1 -1
- package/dist/tools/mix-audio.js +2 -1
- package/dist/tools/mix-audio.js.map +1 -1
- package/dist/tools/normalize-loudness.d.ts.map +1 -1
- package/dist/tools/normalize-loudness.js +2 -1
- package/dist/tools/normalize-loudness.js.map +1 -1
- package/dist/tools/path-traversal.test.d.ts +15 -0
- package/dist/tools/path-traversal.test.d.ts.map +1 -0
- package/dist/tools/path-traversal.test.js +223 -0
- package/dist/tools/path-traversal.test.js.map +1 -0
- package/dist/tools/pick-best-takes.js +2 -1
- package/dist/tools/pick-best-takes.js.map +1 -1
- package/dist/tools/punch-in.d.ts.map +1 -1
- package/dist/tools/punch-in.js +2 -1
- package/dist/tools/punch-in.js.map +1 -1
- package/dist/tools/read-transcript.js +2 -1
- package/dist/tools/read-transcript.js.map +1 -1
- package/dist/tools/render-multi-format.d.ts +35 -0
- package/dist/tools/render-multi-format.d.ts.map +1 -0
- package/dist/tools/render-multi-format.js +206 -0
- package/dist/tools/render-multi-format.js.map +1 -0
- package/dist/tools/render-multi-format.test.d.ts +2 -0
- package/dist/tools/render-multi-format.test.d.ts.map +1 -0
- package/dist/tools/render-multi-format.test.js +312 -0
- package/dist/tools/render-multi-format.test.js.map +1 -0
- package/dist/tools/render.d.ts.map +1 -1
- package/dist/tools/render.js +2 -2
- package/dist/tools/render.js.map +1 -1
- package/dist/tools/rewrite-hook.d.ts +32 -0
- package/dist/tools/rewrite-hook.d.ts.map +1 -0
- package/dist/tools/rewrite-hook.js +65 -0
- package/dist/tools/rewrite-hook.js.map +1 -0
- package/dist/tools/score-clip.d.ts +30 -0
- package/dist/tools/score-clip.d.ts.map +1 -0
- package/dist/tools/score-clip.js +109 -0
- package/dist/tools/score-clip.js.map +1 -0
- package/dist/tools/score-clip.test.d.ts +2 -0
- package/dist/tools/score-clip.test.d.ts.map +1 -0
- package/dist/tools/score-clip.test.js +110 -0
- package/dist/tools/score-clip.test.js.map +1 -0
- package/dist/tools/search-tools.d.ts +34 -0
- package/dist/tools/search-tools.d.ts.map +1 -0
- package/dist/tools/search-tools.js +86 -0
- package/dist/tools/search-tools.js.map +1 -0
- package/dist/tools/search-tools.test.d.ts +2 -0
- package/dist/tools/search-tools.test.d.ts.map +1 -0
- package/dist/tools/search-tools.test.js +60 -0
- package/dist/tools/search-tools.test.js.map +1 -0
- package/dist/tools/snap-cuts-to-beats.d.ts +18 -0
- package/dist/tools/snap-cuts-to-beats.d.ts.map +1 -0
- package/dist/tools/snap-cuts-to-beats.js +110 -0
- package/dist/tools/snap-cuts-to-beats.js.map +1 -0
- package/dist/tools/snap-cuts-to-beats.test.d.ts +2 -0
- package/dist/tools/snap-cuts-to-beats.test.d.ts.map +1 -0
- package/dist/tools/snap-cuts-to-beats.test.js +99 -0
- package/dist/tools/snap-cuts-to-beats.test.js.map +1 -0
- package/dist/tools/speed-ramp.d.ts.map +1 -1
- package/dist/tools/speed-ramp.js +2 -1
- package/dist/tools/speed-ramp.js.map +1 -1
- package/dist/tools/stabilize-video.d.ts.map +1 -1
- package/dist/tools/stabilize-video.js +2 -1
- package/dist/tools/stabilize-video.js.map +1 -1
- package/dist/tools/suggest-broll.d.ts +34 -0
- package/dist/tools/suggest-broll.d.ts.map +1 -0
- package/dist/tools/suggest-broll.js +367 -0
- package/dist/tools/suggest-broll.js.map +1 -0
- package/dist/tools/suggest-broll.test.d.ts +2 -0
- package/dist/tools/suggest-broll.test.d.ts.map +1 -0
- package/dist/tools/suggest-broll.test.js +217 -0
- package/dist/tools/suggest-broll.test.js.map +1 -0
- package/dist/tools/text-based-cut.d.ts +33 -0
- package/dist/tools/text-based-cut.d.ts.map +1 -0
- package/dist/tools/text-based-cut.js +172 -0
- package/dist/tools/text-based-cut.js.map +1 -0
- package/dist/tools/text-based-cut.test.d.ts +2 -0
- package/dist/tools/text-based-cut.test.d.ts.map +1 -0
- package/dist/tools/text-based-cut.test.js +32 -0
- package/dist/tools/text-based-cut.test.js.map +1 -0
- package/dist/tools/transcribe.d.ts +1 -1
- package/dist/tools/transition-videos.d.ts +1 -1
- package/dist/tools/transition-videos.d.ts.map +1 -1
- package/dist/tools/transition-videos.js +2 -1
- package/dist/tools/transition-videos.js.map +1 -1
- package/dist/tools/trim-dead-air.d.ts +59 -0
- package/dist/tools/trim-dead-air.d.ts.map +1 -0
- package/dist/tools/trim-dead-air.js +215 -0
- package/dist/tools/trim-dead-air.js.map +1 -0
- package/dist/tools/trim-dead-air.test.d.ts +2 -0
- package/dist/tools/trim-dead-air.test.d.ts.map +1 -0
- package/dist/tools/trim-dead-air.test.js +75 -0
- package/dist/tools/trim-dead-air.test.js.map +1 -0
- package/dist/tools/verify-thumbnail-promise.d.ts +33 -0
- package/dist/tools/verify-thumbnail-promise.d.ts.map +1 -0
- package/dist/tools/verify-thumbnail-promise.js +112 -0
- package/dist/tools/verify-thumbnail-promise.js.map +1 -0
- package/dist/tools/verify-thumbnail-promise.test.d.ts +2 -0
- package/dist/tools/verify-thumbnail-promise.test.d.ts.map +1 -0
- package/dist/tools/verify-thumbnail-promise.test.js +38 -0
- package/dist/tools/verify-thumbnail-promise.test.js.map +1 -0
- package/dist/tools/write-keyword-captions.d.ts +7 -0
- package/dist/tools/write-keyword-captions.d.ts.map +1 -1
- package/dist/tools/write-keyword-captions.js +35 -4
- package/dist/tools/write-keyword-captions.js.map +1 -1
- package/dist/ui/App.d.ts.map +1 -1
- package/dist/ui/App.js +75 -11
- package/dist/ui/App.js.map +1 -1
- package/dist/ui/tool-formatters.d.ts +30 -0
- package/dist/ui/tool-formatters.d.ts.map +1 -0
- package/dist/ui/tool-formatters.js +461 -0
- package/dist/ui/tool-formatters.js.map +1 -0
- package/dist/ui/tool-formatters.test.d.ts +2 -0
- package/dist/ui/tool-formatters.test.d.ts.map +1 -0
- package/dist/ui/tool-formatters.test.js +143 -0
- package/dist/ui/tool-formatters.test.js.map +1 -0
- package/package.json +10 -9
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { buildTrimConcatFilter, computeKeeps } from "./trim-dead-air.js";
|
|
3
|
+
describe("computeKeeps", () => {
|
|
4
|
+
it("head-tail trims leading and trailing silence", () => {
|
|
5
|
+
const sil = [
|
|
6
|
+
{ startSec: 0, endSec: 1.5 },
|
|
7
|
+
{ startSec: 28, endSec: 30 },
|
|
8
|
+
];
|
|
9
|
+
const keeps = computeKeeps(sil, 30, "head-tail", 0);
|
|
10
|
+
expect(keeps).toEqual([{ startSec: 1.5, endSec: 28 }]);
|
|
11
|
+
});
|
|
12
|
+
it("head-tail keeps mid-recording silence intact", () => {
|
|
13
|
+
const sil = [
|
|
14
|
+
{ startSec: 0, endSec: 1 },
|
|
15
|
+
{ startSec: 10, endSec: 12 },
|
|
16
|
+
{ startSec: 29, endSec: 30 },
|
|
17
|
+
];
|
|
18
|
+
const keeps = computeKeeps(sil, 30, "head-tail", 0);
|
|
19
|
+
expect(keeps).toEqual([{ startSec: 1, endSec: 29 }]);
|
|
20
|
+
});
|
|
21
|
+
it("head-tail returns full duration when no silences detected", () => {
|
|
22
|
+
const keeps = computeKeeps([], 30, "head-tail", 0);
|
|
23
|
+
expect(keeps).toEqual([{ startSec: 0, endSec: 30 }]);
|
|
24
|
+
});
|
|
25
|
+
it("all mode emits keeps between every silence", () => {
|
|
26
|
+
const sil = [
|
|
27
|
+
{ startSec: 5, endSec: 6 },
|
|
28
|
+
{ startSec: 12, endSec: 13 },
|
|
29
|
+
];
|
|
30
|
+
const keeps = computeKeeps(sil, 20, "all", 0);
|
|
31
|
+
expect(keeps).toEqual([
|
|
32
|
+
{ startSec: 0, endSec: 5 },
|
|
33
|
+
{ startSec: 6, endSec: 12 },
|
|
34
|
+
{ startSec: 13, endSec: 20 },
|
|
35
|
+
]);
|
|
36
|
+
});
|
|
37
|
+
it("padding extends keeps and merges overlaps", () => {
|
|
38
|
+
const sil = [
|
|
39
|
+
{ startSec: 5, endSec: 5.1 },
|
|
40
|
+
{ startSec: 5.3, endSec: 5.4 },
|
|
41
|
+
];
|
|
42
|
+
// Padding of 0.2 makes the two surrounding keeps overlap, merging to one.
|
|
43
|
+
const keeps = computeKeeps(sil, 10, "all", 0.2);
|
|
44
|
+
expect(keeps.length).toBe(1);
|
|
45
|
+
expect(keeps[0].startSec).toBeCloseTo(0, 5);
|
|
46
|
+
expect(keeps[0].endSec).toBeCloseTo(10, 5);
|
|
47
|
+
});
|
|
48
|
+
it("returns empty when totalSec is 0", () => {
|
|
49
|
+
expect(computeKeeps([], 0, "head-tail", 0)).toEqual([]);
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
describe("buildTrimConcatFilter", () => {
|
|
53
|
+
it("single keep emits one trim + atrim labelled [v][a]", () => {
|
|
54
|
+
const f = buildTrimConcatFilter([{ startSec: 1, endSec: 5 }]);
|
|
55
|
+
expect(f).toContain("trim=start=1:end=5");
|
|
56
|
+
expect(f).toContain("atrim=start=1:end=5");
|
|
57
|
+
expect(f).toContain("[v]");
|
|
58
|
+
expect(f).toContain("[a]");
|
|
59
|
+
});
|
|
60
|
+
it("multiple keeps emit per-segment trims and a concat", () => {
|
|
61
|
+
const f = buildTrimConcatFilter([
|
|
62
|
+
{ startSec: 0, endSec: 2 },
|
|
63
|
+
{ startSec: 5, endSec: 8 },
|
|
64
|
+
]);
|
|
65
|
+
expect(f).toContain("[v0]");
|
|
66
|
+
expect(f).toContain("[v1]");
|
|
67
|
+
expect(f).toContain("[a0]");
|
|
68
|
+
expect(f).toContain("[a1]");
|
|
69
|
+
expect(f).toContain("concat=n=2:v=1:a=1[v][a]");
|
|
70
|
+
});
|
|
71
|
+
it("throws on empty keep list", () => {
|
|
72
|
+
expect(() => buildTrimConcatFilter([])).toThrow();
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
//# sourceMappingURL=trim-dead-air.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trim-dead-air.test.js","sourceRoot":"","sources":["../../src/tools/trim-dead-air.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { AgentTool } from "@kenkaiiii/gg-agent";
|
|
3
|
+
declare const VerifyThumbnailPromiseParams: z.ZodObject<{
|
|
4
|
+
thumbnail: z.ZodString;
|
|
5
|
+
video: z.ZodString;
|
|
6
|
+
windowSec: z.ZodOptional<z.ZodNumber>;
|
|
7
|
+
sampleCount: z.ZodOptional<z.ZodNumber>;
|
|
8
|
+
detail: z.ZodOptional<z.ZodEnum<{
|
|
9
|
+
low: "low";
|
|
10
|
+
high: "high";
|
|
11
|
+
}>>;
|
|
12
|
+
model: z.ZodOptional<z.ZodString>;
|
|
13
|
+
}, z.core.$strip>;
|
|
14
|
+
/**
|
|
15
|
+
* verify_thumbnail_promise — does the opening deliver on the thumbnail?
|
|
16
|
+
*
|
|
17
|
+
* Per MrBeast's manual: "match the clickbait expectations and
|
|
18
|
+
* front-load." Thumbnails that promise X but show X at minute 8 tank
|
|
19
|
+
* retention. ONE vision LLM call against thumbnail + N sampled frames.
|
|
20
|
+
*/
|
|
21
|
+
export declare function createVerifyThumbnailPromiseTool(cwd: string): AgentTool<typeof VerifyThumbnailPromiseParams>;
|
|
22
|
+
/**
|
|
23
|
+
* Compute N sample timestamps evenly distributed across [0, windowSec].
|
|
24
|
+
* - 1 sample → [0]
|
|
25
|
+
* - 2 samples → [0, windowSec]
|
|
26
|
+
* - 3 samples → [0, windowSec/2, windowSec]
|
|
27
|
+
* - 4+ → endpoints + interior at equal stride
|
|
28
|
+
*
|
|
29
|
+
* Pure — exported for testing.
|
|
30
|
+
*/
|
|
31
|
+
export declare function sampleTimes(windowSec: number, n: number): number[];
|
|
32
|
+
export {};
|
|
33
|
+
//# sourceMappingURL=verify-thumbnail-promise.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify-thumbnail-promise.d.ts","sourceRoot":"","sources":["../../src/tools/verify-thumbnail-promise.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAMrD,QAAA,MAAM,4BAA4B;;;;;;;;;;iBAqBhC,CAAC;AAEH;;;;;;GAMG;AACH,wBAAgB,gCAAgC,CAC9C,GAAG,EAAE,MAAM,GACV,SAAS,CAAC,OAAO,4BAA4B,CAAC,CAiEhD;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAMlE"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { resolve as resolvePath } from "node:path";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { compact, err } from "../core/format.js";
|
|
4
|
+
import { extractAtTimes } from "../core/frames.js";
|
|
5
|
+
import { checkFfmpeg, probeMedia } from "../core/media/ffmpeg.js";
|
|
6
|
+
import { runThumbnailPromise } from "../core/thumbnail-promise.js";
|
|
7
|
+
const VerifyThumbnailPromiseParams = z.object({
|
|
8
|
+
thumbnail: z.string().describe("Path to the thumbnail .jpg/.png (relative resolves to cwd)."),
|
|
9
|
+
video: z.string().describe("Path to the source video the thumbnail accompanies."),
|
|
10
|
+
windowSec: z
|
|
11
|
+
.number()
|
|
12
|
+
.positive()
|
|
13
|
+
.max(120)
|
|
14
|
+
.optional()
|
|
15
|
+
.describe("How much of the opening to sample. Default 60s — short-form delivery's danger zone is " +
|
|
16
|
+
"the first minute."),
|
|
17
|
+
sampleCount: z
|
|
18
|
+
.number()
|
|
19
|
+
.int()
|
|
20
|
+
.min(1)
|
|
21
|
+
.max(8)
|
|
22
|
+
.optional()
|
|
23
|
+
.describe("Frames sampled within the window. Default 3 (taken at 0%, 50%, 100% of windowSec)."),
|
|
24
|
+
detail: z.enum(["low", "high"]).optional().describe("Vision detail. Default low."),
|
|
25
|
+
model: z.string().optional().describe("OpenAI model. Default gpt-4o-mini."),
|
|
26
|
+
});
|
|
27
|
+
/**
|
|
28
|
+
* verify_thumbnail_promise — does the opening deliver on the thumbnail?
|
|
29
|
+
*
|
|
30
|
+
* Per MrBeast's manual: "match the clickbait expectations and
|
|
31
|
+
* front-load." Thumbnails that promise X but show X at minute 8 tank
|
|
32
|
+
* retention. ONE vision LLM call against thumbnail + N sampled frames.
|
|
33
|
+
*/
|
|
34
|
+
export function createVerifyThumbnailPromiseTool(cwd) {
|
|
35
|
+
return {
|
|
36
|
+
name: "verify_thumbnail_promise",
|
|
37
|
+
description: "Verify a thumbnail's visual promise is delivered in the first N seconds of the video " +
|
|
38
|
+
"(default 60s). Per MrBeast's manual: 'match clickbait expectations, front-load' — " +
|
|
39
|
+
"thumbnails that promise X but show X at minute 8 tank retention. ONE vision LLM " +
|
|
40
|
+
"call. Returns matches (0-1), what the thumbnail promises, what the opening actually " +
|
|
41
|
+
"shows, missing elements, and a one-line suggestion. ALWAYS run before declaring done " +
|
|
42
|
+
"on any short-form delivery. Pair with `audit_first_frame` and `analyze_hook` as the " +
|
|
43
|
+
"three short-form pre-render checks.",
|
|
44
|
+
parameters: VerifyThumbnailPromiseParams,
|
|
45
|
+
async execute(args, ctx) {
|
|
46
|
+
if (!checkFfmpeg())
|
|
47
|
+
return err("ffmpeg not on PATH", "install ffmpeg");
|
|
48
|
+
if (!process.env.OPENAI_API_KEY) {
|
|
49
|
+
return err("OPENAI_API_KEY not set", "export OPENAI_API_KEY=...");
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
const thumbAbs = resolvePath(cwd, args.thumbnail);
|
|
53
|
+
const videoAbs = resolvePath(cwd, args.video);
|
|
54
|
+
const probe = probeMedia(videoAbs);
|
|
55
|
+
if (!probe) {
|
|
56
|
+
return err(`probe failed for ${videoAbs}`, "verify file exists and is media");
|
|
57
|
+
}
|
|
58
|
+
const windowSec = Math.min(args.windowSec ?? 60, probe.durationSec);
|
|
59
|
+
if (windowSec < 1) {
|
|
60
|
+
return err("video shorter than 1s — nothing to verify against");
|
|
61
|
+
}
|
|
62
|
+
const sampleCount = Math.min(8, Math.max(1, args.sampleCount ?? 3));
|
|
63
|
+
const times = sampleTimes(windowSec, sampleCount);
|
|
64
|
+
const frames = await extractAtTimes(videoAbs, times, {
|
|
65
|
+
maxWidth: 768,
|
|
66
|
+
signal: ctx.signal,
|
|
67
|
+
});
|
|
68
|
+
if (frames.length === 0) {
|
|
69
|
+
return err("could not extract opening frames");
|
|
70
|
+
}
|
|
71
|
+
const result = await runThumbnailPromise(thumbAbs, frames.map((f) => f.path), {
|
|
72
|
+
model: args.model,
|
|
73
|
+
detail: args.detail,
|
|
74
|
+
windowSec,
|
|
75
|
+
signal: ctx.signal,
|
|
76
|
+
});
|
|
77
|
+
return compact({
|
|
78
|
+
matches: +result.matches.toFixed(2),
|
|
79
|
+
thumbnailPromise: result.thumbnailPromise,
|
|
80
|
+
openingShows: result.openingShows,
|
|
81
|
+
missing: result.missing,
|
|
82
|
+
suggestion: result.suggestion,
|
|
83
|
+
windowSec: +windowSec.toFixed(2),
|
|
84
|
+
sampleCount: frames.length,
|
|
85
|
+
sampledAt: times.map((t) => +t.toFixed(2)),
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
catch (e) {
|
|
89
|
+
return err(e.message);
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Compute N sample timestamps evenly distributed across [0, windowSec].
|
|
96
|
+
* - 1 sample → [0]
|
|
97
|
+
* - 2 samples → [0, windowSec]
|
|
98
|
+
* - 3 samples → [0, windowSec/2, windowSec]
|
|
99
|
+
* - 4+ → endpoints + interior at equal stride
|
|
100
|
+
*
|
|
101
|
+
* Pure — exported for testing.
|
|
102
|
+
*/
|
|
103
|
+
export function sampleTimes(windowSec, n) {
|
|
104
|
+
if (n <= 1 || windowSec <= 0)
|
|
105
|
+
return [0];
|
|
106
|
+
const out = [];
|
|
107
|
+
const step = windowSec / (n - 1);
|
|
108
|
+
for (let i = 0; i < n; i++)
|
|
109
|
+
out.push(+(i * step).toFixed(3));
|
|
110
|
+
return out;
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=verify-thumbnail-promise.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify-thumbnail-promise.js","sourceRoot":"","sources":["../../src/tools/verify-thumbnail-promise.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify-thumbnail-promise.test.d.ts","sourceRoot":"","sources":["../../src/tools/verify-thumbnail-promise.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { createVerifyThumbnailPromiseTool, sampleTimes } from "./verify-thumbnail-promise.js";
|
|
3
|
+
const ctx = {
|
|
4
|
+
signal: new AbortController().signal,
|
|
5
|
+
toolCallId: "t1",
|
|
6
|
+
};
|
|
7
|
+
describe("sampleTimes", () => {
|
|
8
|
+
it("returns single sample at 0 when n=1", () => {
|
|
9
|
+
expect(sampleTimes(60, 1)).toEqual([0]);
|
|
10
|
+
});
|
|
11
|
+
it("returns endpoints when n=2", () => {
|
|
12
|
+
expect(sampleTimes(60, 2)).toEqual([0, 60]);
|
|
13
|
+
});
|
|
14
|
+
it("returns 0/mid/end when n=3", () => {
|
|
15
|
+
expect(sampleTimes(60, 3)).toEqual([0, 30, 60]);
|
|
16
|
+
});
|
|
17
|
+
it("evenly distributes for n=5", () => {
|
|
18
|
+
const t = sampleTimes(40, 5);
|
|
19
|
+
expect(t).toHaveLength(5);
|
|
20
|
+
expect(t[0]).toBe(0);
|
|
21
|
+
expect(t[t.length - 1]).toBe(40);
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
describe("verify_thumbnail_promise tool", () => {
|
|
25
|
+
it("description names front-load + matches + always-run + algorithm pairing", () => {
|
|
26
|
+
const tool = createVerifyThumbnailPromiseTool("/tmp");
|
|
27
|
+
expect(tool.description).toMatch(/front-load|MrBeast/);
|
|
28
|
+
expect(tool.description).toMatch(/ALWAYS|matches/);
|
|
29
|
+
expect(tool.description).toMatch(/audit_first_frame|analyze_hook/);
|
|
30
|
+
});
|
|
31
|
+
it("errors when OPENAI_API_KEY is missing", async () => {
|
|
32
|
+
delete process.env.OPENAI_API_KEY;
|
|
33
|
+
const tool = createVerifyThumbnailPromiseTool("/tmp");
|
|
34
|
+
const r = await tool.execute({ thumbnail: "t.jpg", video: "v.mp4" }, ctx);
|
|
35
|
+
expect(r).toMatch(/error/);
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
//# sourceMappingURL=verify-thumbnail-promise.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify-thumbnail-promise.test.js","sourceRoot":"","sources":["../../src/tools/verify-thumbnail-promise.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,gCAAgC,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAE9F,MAAM,GAAG,GAAG;IACV,MAAM,EAAE,IAAI,eAAe,EAAE,CAAC,MAAM;IACpC,UAAU,EAAE,IAAI;CAC2E,CAAC;AAE9F,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,CAAC,WAAW,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;QACpC,MAAM,CAAC,WAAW,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;QACpC,MAAM,CAAC,WAAW,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;QACpC,MAAM,CAAC,GAAG,WAAW,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QAC7B,MAAM,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC1B,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACrB,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,+BAA+B,EAAE,GAAG,EAAE;IAC7C,EAAE,CAAC,yEAAyE,EAAE,GAAG,EAAE;QACjF,MAAM,IAAI,GAAG,gCAAgC,CAAC,MAAM,CAAC,CAAC;QACtD,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;QACvD,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;QACnD,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,gCAAgC,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;QACrD,OAAO,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;QAClC,MAAM,IAAI,GAAG,gCAAgC,CAAC,MAAM,CAAC,CAAC;QACtD,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,GAAG,CAAC,CAAC;QAC1E,MAAM,CAAC,CAAW,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -18,6 +18,13 @@ declare const WriteKeywordCaptionsParams: z.ZodObject<{
|
|
|
18
18
|
marginV: z.ZodOptional<z.ZodNumber>;
|
|
19
19
|
playResX: z.ZodOptional<z.ZodNumber>;
|
|
20
20
|
playResY: z.ZodOptional<z.ZodNumber>;
|
|
21
|
+
autoEmoji: z.ZodOptional<z.ZodBoolean>;
|
|
22
|
+
emojiDensity: z.ZodOptional<z.ZodEnum<{
|
|
23
|
+
low: "low";
|
|
24
|
+
high: "high";
|
|
25
|
+
med: "med";
|
|
26
|
+
}>>;
|
|
27
|
+
emojiModel: z.ZodOptional<z.ZodString>;
|
|
21
28
|
}, z.core.$strip>;
|
|
22
29
|
/**
|
|
23
30
|
* write_keyword_captions — CapCut-style "active word" caption track.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"write-keyword-captions.d.ts","sourceRoot":"","sources":["../../src/tools/write-keyword-captions.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"write-keyword-captions.d.ts","sourceRoot":"","sources":["../../src/tools/write-keyword-captions.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AASrD,QAAA,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;iBAgF9B,CAAC;AAEH;;;;;;;;;;;GAWG;AACH,wBAAgB,8BAA8B,CAC5C,GAAG,EAAE,MAAM,GACV,SAAS,CAAC,OAAO,0BAA0B,CAAC,CAmH9C"}
|
|
@@ -2,9 +2,11 @@ import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
|
2
2
|
import { dirname, resolve as resolvePath } from "node:path";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { buildAss } from "../core/ass.js";
|
|
5
|
+
import { injectEmojis } from "../core/emoji-captions.js";
|
|
5
6
|
import { compact, err } from "../core/format.js";
|
|
6
7
|
import { buildKeywordCaptions } from "../core/keyword-captions.js";
|
|
7
8
|
import { safeOutputPath } from "../core/safe-paths.js";
|
|
9
|
+
import { parseTranscript } from "../core/whisper.js";
|
|
8
10
|
const WriteKeywordCaptionsParams = z.object({
|
|
9
11
|
transcript: z
|
|
10
12
|
.string()
|
|
@@ -69,6 +71,16 @@ const WriteKeywordCaptionsParams = z.object({
|
|
|
69
71
|
"puts captions in the lower-third sweet spot."),
|
|
70
72
|
playResX: z.number().int().positive().optional().describe("Canvas width. Default 1080."),
|
|
71
73
|
playResY: z.number().int().positive().optional().describe("Canvas height. Default 1920."),
|
|
74
|
+
autoEmoji: z
|
|
75
|
+
.boolean()
|
|
76
|
+
.optional()
|
|
77
|
+
.describe("If true, the tool calls the LLM ONCE over all cues to suggest a fitting emoji per cue " +
|
|
78
|
+
"(or empty string). Submagic / CapCut signature look. Default false."),
|
|
79
|
+
emojiDensity: z
|
|
80
|
+
.enum(["low", "med", "high"])
|
|
81
|
+
.optional()
|
|
82
|
+
.describe("low ≈ 1 in 4 cues, med ≈ 1 in 2, high = every cue. Default 'med'."),
|
|
83
|
+
emojiModel: z.string().optional().describe("LLM model. Default gpt-4o-mini."),
|
|
72
84
|
});
|
|
73
85
|
/**
|
|
74
86
|
* write_keyword_captions — CapCut-style "active word" caption track.
|
|
@@ -102,10 +114,10 @@ export function createWriteKeywordCaptionsTool(cwd) {
|
|
|
102
114
|
}
|
|
103
115
|
let t;
|
|
104
116
|
try {
|
|
105
|
-
t =
|
|
117
|
+
t = parseTranscript(raw);
|
|
106
118
|
}
|
|
107
119
|
catch (e) {
|
|
108
|
-
return err(
|
|
120
|
+
return err(e.message);
|
|
109
121
|
}
|
|
110
122
|
const lo = args.startSec ?? 0;
|
|
111
123
|
const hi = args.endSec ?? t.durationSec;
|
|
@@ -130,12 +142,14 @@ export function createWriteKeywordCaptionsTool(cwd) {
|
|
|
130
142
|
if (allWords.length === 0) {
|
|
131
143
|
return err("no word timings in window", "rerun transcribe(wordTimestamps=true) or widen startSec/endSec");
|
|
132
144
|
}
|
|
133
|
-
const
|
|
145
|
+
const built = buildKeywordCaptions(allWords, {
|
|
134
146
|
groupSize: args.groupSize,
|
|
135
147
|
gapSec: args.gapSec,
|
|
136
148
|
maxKeywordsPerCue: args.maxKeywordsPerCue,
|
|
137
149
|
minKeywordLen: args.minKeywordLen,
|
|
138
150
|
});
|
|
151
|
+
let cues = built.cues;
|
|
152
|
+
const styles = built.styles;
|
|
139
153
|
// Apply aesthetic overrides onto the returned styles.
|
|
140
154
|
for (const s of styles) {
|
|
141
155
|
if (s.name === "Default") {
|
|
@@ -163,6 +177,18 @@ export function createWriteKeywordCaptionsTool(cwd) {
|
|
|
163
177
|
s.marginV = args.marginV;
|
|
164
178
|
}
|
|
165
179
|
}
|
|
180
|
+
// Optional emoji-injection pass (Submagic / CapCut look).
|
|
181
|
+
let emojiInjected = 0;
|
|
182
|
+
let emojiError;
|
|
183
|
+
if (args.autoEmoji) {
|
|
184
|
+
const r = await injectEmojis(cues, {
|
|
185
|
+
density: args.emojiDensity,
|
|
186
|
+
model: args.emojiModel,
|
|
187
|
+
});
|
|
188
|
+
cues = r.cues;
|
|
189
|
+
emojiInjected = r.injected;
|
|
190
|
+
emojiError = r.error;
|
|
191
|
+
}
|
|
166
192
|
const ass = buildAss({
|
|
167
193
|
styles,
|
|
168
194
|
cues,
|
|
@@ -173,7 +199,12 @@ export function createWriteKeywordCaptionsTool(cwd) {
|
|
|
173
199
|
const outAbs = safeOutputPath(cwd, args.output);
|
|
174
200
|
mkdirSync(dirname(outAbs), { recursive: true });
|
|
175
201
|
writeFileSync(outAbs, ass, "utf8");
|
|
176
|
-
return compact({
|
|
202
|
+
return compact({
|
|
203
|
+
path: outAbs,
|
|
204
|
+
cues: cues.length,
|
|
205
|
+
...(args.autoEmoji ? { emojiInjected } : {}),
|
|
206
|
+
...(emojiError ? { emojiError } : {}),
|
|
207
|
+
});
|
|
177
208
|
}
|
|
178
209
|
catch (e) {
|
|
179
210
|
return err(e.message);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"write-keyword-captions.js","sourceRoot":"","sources":["../../src/tools/write-keyword-captions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACjE,OAAO,EAAE,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,WAAW,CAAC;AAC5D,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"write-keyword-captions.js","sourceRoot":"","sources":["../../src/tools/write-keyword-captions.ts"],"names":[],"mappings":"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"}
|
package/dist/ui/App.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/ui/App.tsx"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/ui/App.tsx"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAErD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAStD,MAAM,WAAW,QAAQ;IACvB;;;OAGG;IACH,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,CACnB,QAAQ,EAAE,QAAQ,EAClB,IAAI,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,OAAO,CAAA;KAAE,KAC9B,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACrD,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB;;;;;OAKG;IACH,gBAAgB,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,IAAI,EAAE,QAAQ,CAAC;IACf,gEAAgE;IAChE,aAAa,EAAE,OAAO,EAAE,CAAC;IAEzB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,sCAAsC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,iBAAiB,EAAE,QAAQ,EAAE,CAAC;IAE9B,yEAAyE;IACzE,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,UAAU,EAAE,MAAM,IAAI,CAAC;CACxB;AA+DD,wBAAgB,GAAG,CAAC,KAAK,EAAE,QAAQ,2CA4flC"}
|
package/dist/ui/App.js
CHANGED
|
@@ -6,17 +6,46 @@ import { useTerminalSize } from "@kenkaiiii/ggcoder/ui/hooks/terminal-size";
|
|
|
6
6
|
import { useAgentLoop } from "@kenkaiiii/ggcoder/ui/hooks/agent-loop";
|
|
7
7
|
import { useDoublePress } from "@kenkaiiii/ggcoder/ui/hooks/double-press";
|
|
8
8
|
import { useTheme } from "@kenkaiiii/ggcoder/ui/theme";
|
|
9
|
+
import { getMaxThinkingLevel } from "@kenkaiiii/ggcoder/models";
|
|
9
10
|
import { Banner } from "./components/Banner.js";
|
|
10
11
|
import { saveSession } from "../core/sessions.js";
|
|
11
12
|
import { buildEditorHostBlock, spliceHostBlock } from "../system-prompt.js";
|
|
13
|
+
import { EDITOR_PROMPT_COMMANDS, getEditorPromptCommand } from "../prompt-commands.js";
|
|
14
|
+
import { ggEditorFormatters } from "./tool-formatters.js";
|
|
12
15
|
// Editor brand pulse — amber → orange → rose. Distinct from ggcoder's blue/purple.
|
|
13
16
|
const THINKING_BORDER_COLORS = ["#fbbf24", "#f97316", "#ec4899", "#f97316", "#fbbf24"];
|
|
14
17
|
// Names are bare (no `/` prefix) — ggcoder's slash menu prepends `/` for
|
|
15
18
|
// display. Including a `/` here would render as `//`.
|
|
19
|
+
//
|
|
20
|
+
// Order is intentional, follows the typical creator session arc:
|
|
21
|
+
// 1. Setup — one-time per channel
|
|
22
|
+
// 2. Workflow — the main verb ("make me a YouTube video")
|
|
23
|
+
// 3. QA — audit before ship; diagnose after under-performance
|
|
24
|
+
// 4. Session UI — model swap, clear scrollback
|
|
25
|
+
// 5. Meta — help, then quit (always last)
|
|
26
|
+
//
|
|
27
|
+
// Prompt commands (group 1–3) come from `prompt-commands.ts` — looked up by
|
|
28
|
+
// name in the same handleSubmit dispatcher. Local UI commands (group 4–5)
|
|
29
|
+
// are handled inline because they manipulate React state directly.
|
|
30
|
+
function promptCmd(name) {
|
|
31
|
+
const c = EDITOR_PROMPT_COMMANDS.find((x) => x.name === name);
|
|
32
|
+
if (!c)
|
|
33
|
+
throw new Error(`gg-editor: missing prompt command '${name}' — check prompt-commands.ts`);
|
|
34
|
+
return { name: c.name, aliases: c.aliases, description: c.description };
|
|
35
|
+
}
|
|
16
36
|
const EDITOR_COMMANDS = [
|
|
37
|
+
// 1. Setup (one-time per channel)
|
|
38
|
+
promptCmd("setup-channel"),
|
|
39
|
+
// 2. Workflow (the main verb)
|
|
40
|
+
promptCmd("youtube"),
|
|
41
|
+
// 3. QA — pre-render audit, post-render diagnosis
|
|
42
|
+
promptCmd("audit"),
|
|
43
|
+
promptCmd("diagnose"),
|
|
44
|
+
// 4. Session UI
|
|
17
45
|
{ name: "model", aliases: ["m"], description: "switch model" },
|
|
18
|
-
{ name: "help", aliases: ["?"], description: "show available commands" },
|
|
19
46
|
{ name: "clear", aliases: [], description: "clear visible history (doesn't reset agent)" },
|
|
47
|
+
// 5. Meta — help next-to-last, quit always last
|
|
48
|
+
{ name: "help", aliases: ["?"], description: "show available commands" },
|
|
20
49
|
{ name: "quit", aliases: ["exit", "q"], description: "exit cleanly" },
|
|
21
50
|
];
|
|
22
51
|
export function App(props) {
|
|
@@ -170,7 +199,7 @@ export function App(props) {
|
|
|
170
199
|
maxTokens: 16384,
|
|
171
200
|
apiKey: props.apiKey,
|
|
172
201
|
accountId: props.accountId,
|
|
173
|
-
thinking: thinkingEnabled ?
|
|
202
|
+
thinking: thinkingEnabled ? getMaxThinkingLevel(currentModel) : undefined,
|
|
174
203
|
// Pull fresh creds before each turn so OAuth refresh + provider swaps
|
|
175
204
|
// via /model both flow through. Without this, an 8h Anthropic token
|
|
176
205
|
// that expires mid-session takes the whole CLI down.
|
|
@@ -194,14 +223,17 @@ export function App(props) {
|
|
|
194
223
|
},
|
|
195
224
|
// Running tool calls are rendered live from agentLoop.activeToolCalls
|
|
196
225
|
// OUTSIDE of <Static>; only the completed result enters scrollback here.
|
|
197
|
-
onToolEnd: (toolCallId, name, result, isError, _durationMs, details) => {
|
|
198
|
-
|
|
226
|
+
onToolEnd: (toolCallId, name, result, isError, _durationMs, details, args) => {
|
|
227
|
+
// Use the args passed through from onToolEnd directly. Looking them up
|
|
228
|
+
// via `agentLoop.activeToolCalls` here is racey — by the time onToolEnd
|
|
229
|
+
// fires the call has been pulled from the active list, so most tools
|
|
230
|
+
// would land on `{}` and lose every detail/inline summary.
|
|
199
231
|
queueFlush({
|
|
200
232
|
id: nextId(),
|
|
201
233
|
kind: "tool_done",
|
|
202
234
|
toolCallId,
|
|
203
235
|
name,
|
|
204
|
-
args:
|
|
236
|
+
args: args ?? {},
|
|
205
237
|
result,
|
|
206
238
|
isError,
|
|
207
239
|
details,
|
|
@@ -248,16 +280,26 @@ export function App(props) {
|
|
|
248
280
|
return;
|
|
249
281
|
}
|
|
250
282
|
if (value === "/help" || value === "/?") {
|
|
283
|
+
const fmt = (c) => `- \`/${c.name}\`${c.aliases.length ? " " + c.aliases.map((a) => `\`/${a}\``).join(" ") : ""} — ${c.description}`;
|
|
284
|
+
const setup = EDITOR_PROMPT_COMMANDS.filter((c) => c.name === "setup-channel").map(fmt);
|
|
285
|
+
const workflow = EDITOR_PROMPT_COMMANDS.filter((c) => c.name === "youtube").map(fmt);
|
|
286
|
+
const qa = EDITOR_PROMPT_COMMANDS.filter((c) => ["audit", "diagnose"].includes(c.name)).map(fmt);
|
|
251
287
|
setHistoryItems((items) => [
|
|
252
288
|
...items,
|
|
253
289
|
{
|
|
254
290
|
id: nextId(),
|
|
255
291
|
kind: "assistant",
|
|
256
|
-
text: "**
|
|
292
|
+
text: "**Setup** (one-time per channel)\n\n" +
|
|
293
|
+
setup.join("\n") +
|
|
294
|
+
"\n\n**Workflow**\n\n" +
|
|
295
|
+
workflow.join("\n") +
|
|
296
|
+
"\n\n**Quality checks**\n\n" +
|
|
297
|
+
qa.join("\n") +
|
|
298
|
+
"\n\n**Session**\n\n" +
|
|
257
299
|
"- `/model` `/m` — switch model\n" +
|
|
258
|
-
"- `/quit` `/exit` `/q` — exit\n" +
|
|
259
300
|
"- `/clear` — clear visible history (doesn't reset agent)\n" +
|
|
260
|
-
"- `/help` `/?` — this help\n
|
|
301
|
+
"- `/help` `/?` — this help\n" +
|
|
302
|
+
"- `/quit` `/exit` `/q` — exit\n\n" +
|
|
261
303
|
"**Keys**\n\n" +
|
|
262
304
|
"- `Shift-Tab` toggle thinking\n" +
|
|
263
305
|
"- `ESC` interrupt the agent\n" +
|
|
@@ -272,6 +314,28 @@ export function App(props) {
|
|
|
272
314
|
setOverlay("model");
|
|
273
315
|
return;
|
|
274
316
|
}
|
|
317
|
+
// Bundled prompt commands — dispatch to the agent loop with the
|
|
318
|
+
// command's prompt as the user message. Mirrors ggcoder's pattern.
|
|
319
|
+
// Args after the command name are appended as "## User Instructions".
|
|
320
|
+
if (value.startsWith("/")) {
|
|
321
|
+
const parts = value.slice(1).split(" ");
|
|
322
|
+
const cmdName = parts[0];
|
|
323
|
+
const cmdArgs = parts.slice(1).join(" ").trim();
|
|
324
|
+
const cmd = getEditorPromptCommand(cmdName);
|
|
325
|
+
if (cmd) {
|
|
326
|
+
const fullPrompt = cmdArgs
|
|
327
|
+
? `${cmd.prompt}\n\n## User Instructions\n\n${cmdArgs}`
|
|
328
|
+
: cmd.prompt;
|
|
329
|
+
// Show the user's literal /command invocation in scrollback so the
|
|
330
|
+
// history stays a faithful transcript; the expanded prompt itself
|
|
331
|
+
// goes to the agent loop only.
|
|
332
|
+
lastUserMessageRef.current = value;
|
|
333
|
+
setLastUserMessage(value);
|
|
334
|
+
setHistoryItems((items) => [...items, { id: nextId(), kind: "user", text: value }]);
|
|
335
|
+
void agentLoop.run(fullPrompt);
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
275
339
|
lastUserMessageRef.current = value;
|
|
276
340
|
setLastUserMessage(value);
|
|
277
341
|
setHistoryItems((items) => [...items, { id: nextId(), kind: "user", text: value }]);
|
|
@@ -355,9 +419,9 @@ export function App(props) {
|
|
|
355
419
|
// Banner is static — host connection state lives in the Footer (which
|
|
356
420
|
// polls every few seconds and updates live).
|
|
357
421
|
[historyItems, props.version, currentModel, currentProvider]);
|
|
358
|
-
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Static, { items: staticItems, children: (item) => _jsx(Box, { children: item.el }, item.id) }), _jsx(StreamingArea, { isRunning: agentLoop.isRunning, streamingText: agentLoop.streamingText, streamingThinking: agentLoop.streamingThinking, showThinking: true, thinkingMs: agentLoop.thinkingMs }), agentLoop.activeToolCalls.map((tc) => (_jsx(ToolExecution, { status: "running", name: tc.name, args: tc.args }, tc.toolCallId))), agentLoop.isRunning && agentLoop.activityPhase !== "idle" ? (_jsx(Box, { marginTop: 1, borderStyle: "round", borderColor: agentLoop.activityPhase === "thinking"
|
|
422
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Static, { items: staticItems, children: (item) => _jsx(Box, { children: item.el }, item.id) }), _jsx(StreamingArea, { isRunning: agentLoop.isRunning, streamingText: agentLoop.streamingText, streamingThinking: agentLoop.streamingThinking, showThinking: true, thinkingMs: agentLoop.thinkingMs }), agentLoop.activeToolCalls.map((tc) => (_jsx(ToolExecution, { status: "running", name: tc.name, args: tc.args, formatters: ggEditorFormatters }, tc.toolCallId))), agentLoop.isRunning && agentLoop.activityPhase !== "idle" ? (_jsx(Box, { marginTop: 1, borderStyle: "round", borderColor: agentLoop.activityPhase === "thinking"
|
|
359
423
|
? THINKING_BORDER_COLORS[thinkingBorderFrame]
|
|
360
|
-
: "transparent", paddingLeft: 1, paddingRight: 1, width: columns, children: _jsx(ActivityIndicator, { phase: agentLoop.activityPhase, elapsedMs: agentLoop.elapsedMs, runStartRef: agentLoop.runStartRef, thinkingMs: agentLoop.thinkingMs, isThinking: agentLoop.isThinking, tokenEstimate: agentLoop.streamedTokenEstimate, charCountRef: agentLoop.charCountRef, realTokensAccumRef: agentLoop.realTokensAccumRef, userMessage: lastUserMessage, activeToolNames: agentLoop.activeToolCalls.map((tc) => tc.name), retryInfo: agentLoop.retryInfo }) })) : agentLoop.stallError ? (_jsx(Box, { marginTop: 1, flexDirection: "column", children: _jsx(Text, { color: theme.warning, children: "⚠ Stream interrupted — retries exhausted. Your conversation is preserved." }) })) : null, _jsx(InputArea, { onSubmit: (value) => handleSubmit(value), onAbort: handleAbort, disabled: agentLoop.isRunning, isActive: overlay === null, onShiftTab: handleToggleThinking, cwd: props.cwd, commands: EDITOR_COMMANDS }), overlay === "model" ? (_jsx(ModelSelector, { onSelect: handleModelSelect, onCancel: () => setOverlay(null), loggedInProviders: props.loggedInProviders, currentModel: currentModel, currentProvider: currentProvider })) : (_jsx(Footer, { model: currentModel, tokensIn: agentLoop.contextUsed, cwd: props.cwd, thinkingEnabled:
|
|
424
|
+
: "transparent", paddingLeft: 1, paddingRight: 1, width: columns, children: _jsx(ActivityIndicator, { phase: agentLoop.activityPhase, elapsedMs: agentLoop.elapsedMs, runStartRef: agentLoop.runStartRef, thinkingMs: agentLoop.thinkingMs, isThinking: agentLoop.isThinking, tokenEstimate: agentLoop.streamedTokenEstimate, charCountRef: agentLoop.charCountRef, realTokensAccumRef: agentLoop.realTokensAccumRef, userMessage: lastUserMessage, activeToolNames: agentLoop.activeToolCalls.map((tc) => tc.name), retryInfo: agentLoop.retryInfo }) })) : agentLoop.stallError ? (_jsx(Box, { marginTop: 1, flexDirection: "column", children: _jsx(Text, { color: theme.warning, children: "⚠ Stream interrupted — retries exhausted. Your conversation is preserved." }) })) : null, _jsx(InputArea, { onSubmit: (value) => handleSubmit(value), onAbort: handleAbort, disabled: agentLoop.isRunning, isActive: overlay === null, onShiftTab: handleToggleThinking, cwd: props.cwd, commands: EDITOR_COMMANDS }), overlay === "model" ? (_jsx(ModelSelector, { onSelect: handleModelSelect, onCancel: () => setOverlay(null), loggedInProviders: props.loggedInProviders, currentModel: currentModel, currentProvider: currentProvider })) : (_jsx(Footer, { model: currentModel, tokensIn: agentLoop.contextUsed, cwd: props.cwd, thinkingLevel: thinkingEnabled ? getMaxThinkingLevel(currentModel) : undefined, hidePlan: true, hideCwd: true, hideGitBranch: true, exitPending: exitPending, statusLabel: composeStatusLabel(hostStatus, timelineGlance), statusColor: composeStatusColor(hostStatus, theme), statusBelow: true }))] }));
|
|
361
425
|
}
|
|
362
426
|
function composeStatusLabel(status, timeline) {
|
|
363
427
|
if (status.name === "none")
|
|
@@ -409,7 +473,7 @@ function renderItem(item) {
|
|
|
409
473
|
return (_jsx(AssistantMessage, { text: item.text, thinking: item.thinking, thinkingMs: item.thinkingMs, showThinking: true }, item.id));
|
|
410
474
|
}
|
|
411
475
|
// tool_done
|
|
412
|
-
return (_jsx(ToolExecution, { status: "done", name: item.name, args: item.args, result: item.result, isError: item.isError, details: item.details }, item.id));
|
|
476
|
+
return (_jsx(ToolExecution, { status: "done", name: item.name, args: item.args, result: item.result, isError: item.isError, details: item.details, formatters: ggEditorFormatters }, item.id));
|
|
413
477
|
}
|
|
414
478
|
/** Convert a persisted Message into HistoryItems for resume display. */
|
|
415
479
|
function messageToHistoryItems(msg, baseId) {
|