@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 @@
|
|
|
1
|
+
{"version":3,"file":"youtube-metadata.test.d.ts","sourceRoot":"","sources":["../../src/core/youtube-metadata.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { enforceMetadataConstraints, generateMetadata, parseMetadataResponse, } from "./youtube-metadata.js";
|
|
3
|
+
describe("parseMetadataResponse", () => {
|
|
4
|
+
it("parses a well-formed response", () => {
|
|
5
|
+
const r = parseMetadataResponse(JSON.stringify({
|
|
6
|
+
titles: ["A", "B", "C"],
|
|
7
|
+
description: "intro\n\n00:00 Intro",
|
|
8
|
+
tags: ["one", "two"],
|
|
9
|
+
chapters: [{ atSec: 0, title: "Intro" }],
|
|
10
|
+
hashtags: ["#tag1", "tag2"],
|
|
11
|
+
}));
|
|
12
|
+
expect(r.titles).toHaveLength(3);
|
|
13
|
+
expect(r.tags).toEqual(["one", "two"]);
|
|
14
|
+
expect(r.chapters[0].atSec).toBe(0);
|
|
15
|
+
// hashtag without # gets one prepended
|
|
16
|
+
expect(r.hashtags).toContain("#tag2");
|
|
17
|
+
});
|
|
18
|
+
it("strips leading # from tags", () => {
|
|
19
|
+
const r = parseMetadataResponse(JSON.stringify({ tags: ["#foo", "bar"] }));
|
|
20
|
+
expect(r.tags).toEqual(["foo", "bar"]);
|
|
21
|
+
});
|
|
22
|
+
it("drops chapter entries with bad atSec or empty title", () => {
|
|
23
|
+
const r = parseMetadataResponse(JSON.stringify({
|
|
24
|
+
chapters: [
|
|
25
|
+
{ atSec: 0, title: "ok" },
|
|
26
|
+
{ atSec: -5, title: "neg" },
|
|
27
|
+
{ atSec: "x", title: "bad" },
|
|
28
|
+
{ atSec: 30, title: "" },
|
|
29
|
+
],
|
|
30
|
+
}));
|
|
31
|
+
expect(r.chapters).toHaveLength(1);
|
|
32
|
+
});
|
|
33
|
+
it("throws on absent JSON", () => {
|
|
34
|
+
expect(() => parseMetadataResponse("just prose")).toThrow(/no JSON/);
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
describe("enforceMetadataConstraints", () => {
|
|
38
|
+
const base = {
|
|
39
|
+
titles: ["t1", "t2", "t3"],
|
|
40
|
+
description: "desc",
|
|
41
|
+
tags: Array.from({ length: 20 }, (_, i) => `tag${i}`),
|
|
42
|
+
chapters: [
|
|
43
|
+
{ atSec: 0, title: "Intro" },
|
|
44
|
+
{ atSec: 60, title: "Topic A" },
|
|
45
|
+
{ atSec: 120, title: "Topic B" },
|
|
46
|
+
{ atSec: 200, title: "Topic C" },
|
|
47
|
+
{ atSec: 280, title: "Topic D" },
|
|
48
|
+
],
|
|
49
|
+
hashtags: ["#a", "#b", "#c", "#d", "#e", "#f"],
|
|
50
|
+
};
|
|
51
|
+
it("drops chapters when duration < 5 minutes", () => {
|
|
52
|
+
const r = enforceMetadataConstraints(base, 200);
|
|
53
|
+
expect(r.chapters).toEqual([]);
|
|
54
|
+
});
|
|
55
|
+
it("preserves chapters when duration >= 5 minutes and there are 5-15", () => {
|
|
56
|
+
const r = enforceMetadataConstraints(base, 600);
|
|
57
|
+
expect(r.chapters.length).toBeGreaterThanOrEqual(5);
|
|
58
|
+
expect(r.chapters[0].atSec).toBe(0);
|
|
59
|
+
});
|
|
60
|
+
it("forces first chapter to atSec=0 even if LLM returned a different time", () => {
|
|
61
|
+
const r = enforceMetadataConstraints({ ...base, chapters: [{ atSec: 5, title: "Late Intro" }, ...base.chapters.slice(1)] }, 600);
|
|
62
|
+
expect(r.chapters[0].atSec).toBe(0);
|
|
63
|
+
});
|
|
64
|
+
it("drops chapters with <30s gap", () => {
|
|
65
|
+
const r = enforceMetadataConstraints({
|
|
66
|
+
...base,
|
|
67
|
+
chapters: [
|
|
68
|
+
{ atSec: 0, title: "A" },
|
|
69
|
+
{ atSec: 10, title: "B" }, // too close
|
|
70
|
+
{ atSec: 60, title: "C" },
|
|
71
|
+
{ atSec: 120, title: "D" },
|
|
72
|
+
{ atSec: 180, title: "E" },
|
|
73
|
+
],
|
|
74
|
+
}, 600);
|
|
75
|
+
// Must have ≥ 5 entries to keep — if pruning kills it below 5 we get [].
|
|
76
|
+
// After pruning B: A, C, D, E = 4 → []
|
|
77
|
+
expect(r.chapters).toEqual([]);
|
|
78
|
+
});
|
|
79
|
+
it("caps tags at 15 and dedupes", () => {
|
|
80
|
+
const r = enforceMetadataConstraints({ ...base, tags: ["a", "A", "b", ...base.tags] }, 200);
|
|
81
|
+
expect(r.tags.length).toBeLessThanOrEqual(15);
|
|
82
|
+
// case-insensitive dedupe
|
|
83
|
+
expect(r.tags.filter((t) => t.toLowerCase() === "a")).toHaveLength(1);
|
|
84
|
+
});
|
|
85
|
+
it("caps hashtags at 5", () => {
|
|
86
|
+
const r = enforceMetadataConstraints(base, 200);
|
|
87
|
+
expect(r.hashtags.length).toBeLessThanOrEqual(5);
|
|
88
|
+
});
|
|
89
|
+
it("truncates each title to 70 chars", () => {
|
|
90
|
+
const long = "x".repeat(100);
|
|
91
|
+
const r = enforceMetadataConstraints({ ...base, titles: [long, long, long] }, 200);
|
|
92
|
+
for (const t of r.titles)
|
|
93
|
+
expect(t.length).toBeLessThanOrEqual(70);
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
describe("generateMetadata", () => {
|
|
97
|
+
afterEach(() => {
|
|
98
|
+
vi.unstubAllGlobals();
|
|
99
|
+
delete process.env.OPENAI_API_KEY;
|
|
100
|
+
});
|
|
101
|
+
it("throws without API key", async () => {
|
|
102
|
+
delete process.env.OPENAI_API_KEY;
|
|
103
|
+
await expect(generateMetadata({ language: "en", durationSec: 60, segments: [] })).rejects.toThrow(/OPENAI_API_KEY/);
|
|
104
|
+
});
|
|
105
|
+
it("returns enforced metadata on success", async () => {
|
|
106
|
+
process.env.OPENAI_API_KEY = "k";
|
|
107
|
+
const json = {
|
|
108
|
+
titles: ["A title", "B title", "C title"],
|
|
109
|
+
description: "Some description",
|
|
110
|
+
tags: ["tech", "ai", "shorts"],
|
|
111
|
+
chapters: [{ atSec: 0, title: "Intro" }],
|
|
112
|
+
hashtags: ["#ai", "#tech"],
|
|
113
|
+
};
|
|
114
|
+
vi.stubGlobal("fetch", vi.fn(async () => ({
|
|
115
|
+
ok: true,
|
|
116
|
+
status: 200,
|
|
117
|
+
json: async () => ({
|
|
118
|
+
choices: [{ message: { content: JSON.stringify(json) } }],
|
|
119
|
+
}),
|
|
120
|
+
text: async () => "",
|
|
121
|
+
})));
|
|
122
|
+
const r = await generateMetadata({
|
|
123
|
+
language: "en",
|
|
124
|
+
durationSec: 200,
|
|
125
|
+
segments: [{ start: 0, end: 200, text: "intro" }],
|
|
126
|
+
});
|
|
127
|
+
expect(r.titles).toHaveLength(3);
|
|
128
|
+
// <5 min → chapters dropped
|
|
129
|
+
expect(r.chapters).toEqual([]);
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
//# sourceMappingURL=youtube-metadata.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"youtube-metadata.test.js","sourceRoot":"","sources":["../../src/core/youtube-metadata.test.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ export { runDoctorInteractive } from "./core/doctor-runner.js";
|
|
|
13
13
|
export type { DoctorRunOptions } from "./core/doctor-runner.js";
|
|
14
14
|
export { buildEditorSystemPrompt, buildEditorStaticBody, buildEditorHostBlock, spliceHostBlock, } from "./system-prompt.js";
|
|
15
15
|
export type { StaticPromptOptions } from "./system-prompt.js";
|
|
16
|
-
export { AuthStorage,
|
|
16
|
+
export { AuthStorage, NotLoggedInError, loginAnthropic, loginOpenAI, refreshAnthropicToken, refreshOpenAIToken, runLogin, runLogout, runStatus, } from "./core/auth/index.js";
|
|
17
17
|
export type { OAuthCredentials, OAuthLoginCallbacks, SupportedAuthProvider, } from "./core/auth/index.js";
|
|
18
18
|
export type { ClipInfo, EditorConfig, Frame, FrameRange, HostCapabilities, HostName, MarkerInfo, TimelineState, } from "./types.js";
|
|
19
19
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,YAAY,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAGjE,OAAO,EACL,UAAU,EACV,UAAU,EACV,oBAAoB,EACpB,oBAAoB,EACpB,WAAW,EACX,eAAe,EACf,cAAc,GACf,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,YAAY,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAGtE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAC1F,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGvE,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC/E,YAAY,EACV,aAAa,EACb,WAAW,EACX,WAAW,EACX,YAAY,EACZ,eAAe,GAChB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,YAAY,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAGhE,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,oBAAoB,EACpB,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,YAAY,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAGjE,OAAO,EACL,UAAU,EACV,UAAU,EACV,oBAAoB,EACpB,oBAAoB,EACpB,WAAW,EACX,eAAe,EACf,cAAc,GACf,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,YAAY,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAGtE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAC1F,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGvE,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC/E,YAAY,EACV,aAAa,EACb,WAAW,EACX,WAAW,EACX,YAAY,EACZ,eAAe,GAChB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,YAAY,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAGhE,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,oBAAoB,EACpB,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAI9D,OAAO,EACL,WAAW,EACX,gBAAgB,EAChB,cAAc,EACd,WAAW,EACX,qBAAqB,EACrB,kBAAkB,EAClB,QAAQ,EACR,SAAS,EACT,SAAS,GACV,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACV,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,sBAAsB,CAAC;AAG9B,YAAY,EACV,QAAQ,EACR,YAAY,EACZ,KAAK,EACL,UAAU,EACV,gBAAgB,EAChB,QAAQ,EACR,UAAU,EACV,aAAa,GACd,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -11,6 +11,7 @@ export { renderDoctorReport } from "./core/doctor-render.js";
|
|
|
11
11
|
export { runDoctorInteractive } from "./core/doctor-runner.js";
|
|
12
12
|
// System prompt
|
|
13
13
|
export { buildEditorSystemPrompt, buildEditorStaticBody, buildEditorHostBlock, spliceHostBlock, } from "./system-prompt.js";
|
|
14
|
-
// Auth (shared with ggcoder via ~/.gg/auth.json
|
|
15
|
-
|
|
14
|
+
// Auth (shared with ggcoder via ~/.gg/auth.json — implementations live in
|
|
15
|
+
// @kenkaiiii/ggcoder/auth and are re-exported through ./core/auth/index.js)
|
|
16
|
+
export { AuthStorage, NotLoggedInError, loginAnthropic, loginOpenAI, refreshAnthropicToken, refreshOpenAIToken, runLogin, runLogout, runStatus, } from "./core/auth/index.js";
|
|
16
17
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,QAAQ;AACR,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAGrD,QAAQ;AACR,OAAO,EACL,UAAU,EACV,UAAU,EACV,oBAAoB,EACpB,oBAAoB,EACpB,WAAW,EACX,eAAe,EACf,cAAc,GACf,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGtD,QAAQ;AACR,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAG1F,gCAAgC;AAChC,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAQ/E,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAG/D,gBAAgB;AAChB,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,oBAAoB,EACpB,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAG5B,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,QAAQ;AACR,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAGrD,QAAQ;AACR,OAAO,EACL,UAAU,EACV,UAAU,EACV,oBAAoB,EACpB,oBAAoB,EACpB,WAAW,EACX,eAAe,EACf,cAAc,GACf,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGtD,QAAQ;AACR,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAG1F,gCAAgC;AAChC,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAQ/E,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAG/D,gBAAgB;AAChB,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,oBAAoB,EACpB,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAG5B,0EAA0E;AAC1E,4EAA4E;AAC5E,OAAO,EACL,WAAW,EACX,gBAAgB,EAChB,cAAc,EACd,WAAW,EACX,qBAAqB,EACrB,kBAAkB,EAClB,QAAQ,EACR,SAAS,EACT,SAAS,GACV,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bundled slash-command prompt templates for gg-editor.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors ggcoder's `core/prompt-commands.ts` pattern: each command name maps
|
|
5
|
+
* to a full prompt that the agent loop executes. When the user types `/X`,
|
|
6
|
+
* the App.tsx slash dispatcher looks up the command, optionally appends any
|
|
7
|
+
* args, and runs the prompt as if it were a normal user message.
|
|
8
|
+
*
|
|
9
|
+
* Why bundled (not custom): these are core gg-editor workflows tied to our
|
|
10
|
+
* tool surface (`brand_kit`, `audit_*`, `verify_thumbnail_promise`, etc.).
|
|
11
|
+
* Per-project custom commands could still live in `<cwd>/.gg/commands/*.md`
|
|
12
|
+
* if we wire that loader in later — bundled commands take priority either
|
|
13
|
+
* way.
|
|
14
|
+
*/
|
|
15
|
+
export interface PromptCommand {
|
|
16
|
+
name: string;
|
|
17
|
+
aliases: string[];
|
|
18
|
+
description: string;
|
|
19
|
+
prompt: string;
|
|
20
|
+
}
|
|
21
|
+
export declare const EDITOR_PROMPT_COMMANDS: PromptCommand[];
|
|
22
|
+
/** Look up a prompt command by name or alias. Returns undefined when not found. */
|
|
23
|
+
export declare function getEditorPromptCommand(name: string): PromptCommand | undefined;
|
|
24
|
+
//# sourceMappingURL=prompt-commands.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-commands.d.ts","sourceRoot":"","sources":["../src/prompt-commands.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,sBAAsB,EAAE,aAAa,EA+NjD,CAAC;AAEF,mFAAmF;AACnF,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAE9E"}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bundled slash-command prompt templates for gg-editor.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors ggcoder's `core/prompt-commands.ts` pattern: each command name maps
|
|
5
|
+
* to a full prompt that the agent loop executes. When the user types `/X`,
|
|
6
|
+
* the App.tsx slash dispatcher looks up the command, optionally appends any
|
|
7
|
+
* args, and runs the prompt as if it were a normal user message.
|
|
8
|
+
*
|
|
9
|
+
* Why bundled (not custom): these are core gg-editor workflows tied to our
|
|
10
|
+
* tool surface (`brand_kit`, `audit_*`, `verify_thumbnail_promise`, etc.).
|
|
11
|
+
* Per-project custom commands could still live in `<cwd>/.gg/commands/*.md`
|
|
12
|
+
* if we wire that loader in later — bundled commands take priority either
|
|
13
|
+
* way.
|
|
14
|
+
*/
|
|
15
|
+
export const EDITOR_PROMPT_COMMANDS = [
|
|
16
|
+
{
|
|
17
|
+
name: "setup-channel",
|
|
18
|
+
aliases: ["brand-kit"],
|
|
19
|
+
description: "Walk through brand-kit setup, write .gg/brand.json",
|
|
20
|
+
prompt: `# Brand kit setup
|
|
21
|
+
|
|
22
|
+
Walk the user through configuring their channel's brand kit. The output is a single JSON file at \`<cwd>/.gg/brand.json\` that every render-time tool inherits from.
|
|
23
|
+
|
|
24
|
+
## Why this matters
|
|
25
|
+
|
|
26
|
+
Once the brand kit is set up, the user never has to re-specify channel name, logo, fonts, colours, intro/outro, or CTA on any future video. Tools like \`generate_outro\`, \`compose_thumbnail_variants\`, \`compose_thumbnail\`, and \`generate_youtube_metadata\` automatically inherit the kit's defaults.
|
|
27
|
+
|
|
28
|
+
## How to run this
|
|
29
|
+
|
|
30
|
+
ASK the user the questions below ONE AT A TIME (or in small grouped batches). DO NOT ask them all at once — that's overwhelming. Skip optional fields cleanly when the user says "skip" or "n/a". Show your work as you go.
|
|
31
|
+
|
|
32
|
+
After each answer, validate quickly:
|
|
33
|
+
- Path fields → confirm the file exists at the given path (use \`probe_media\` for video files, just check existence for fonts/images via your read tool's error behaviour).
|
|
34
|
+
- Hex colours → must be 6 hex chars, no leading \`#\`. If the user provides \`#FF6B35\`, strip the \`#\` automatically.
|
|
35
|
+
- URLs → no validation needed, just record.
|
|
36
|
+
|
|
37
|
+
If validation fails, tell the user clearly and ask once more.
|
|
38
|
+
|
|
39
|
+
## The questions, in order
|
|
40
|
+
|
|
41
|
+
### Required
|
|
42
|
+
1. **Channel name** — display name surfaced in outros / lower-thirds / metadata. Free text.
|
|
43
|
+
2. **Channel niche / topic** — one-sentence description. Used to give \`generate_youtube_metadata\` topical context for descriptions.
|
|
44
|
+
|
|
45
|
+
### Visual identity (recommended, but skippable)
|
|
46
|
+
3. **Logo** — relative path to a PNG with alpha (used by \`overlay_watermark\` and \`generate_outro\`). Skip if none.
|
|
47
|
+
4. **Watermark** — separate path if they have a positioned/sized variant (otherwise the agent uses logo). Optional.
|
|
48
|
+
5. **Intro video** — pre-rendered intro mp4 to splice via \`concat_videos\`. Optional.
|
|
49
|
+
6. **Outro video** — pre-rendered outro mp4. Optional. (\`generate_outro\` can produce one on-the-fly if they don't have one.)
|
|
50
|
+
|
|
51
|
+
### Typography (one-time pain, lifelong save)
|
|
52
|
+
7. **Heading font** — path to a .ttf/.otf used for thumbnail text + outro headline. Bebas Neue, Inter Black, Anton, Impact are common choices. If they don't have one, suggest downloading Bebas Neue (free, https://fonts.google.com/specimen/Bebas+Neue) and recommend a path like \`assets/Bebas-Bold.ttf\`.
|
|
53
|
+
8. **Body font** — for lower-thirds / captions. Optional; skip is fine.
|
|
54
|
+
|
|
55
|
+
### Colours (6-char hex, no #)
|
|
56
|
+
9. **Primary colour** — used for thumbnail text outline, accent. e.g. \`FF6B35\`.
|
|
57
|
+
10. **Secondary colour** — optional accent.
|
|
58
|
+
11. **Accent colour** — optional third.
|
|
59
|
+
|
|
60
|
+
### Voice
|
|
61
|
+
12. **CTA text** — what the outro card says. Default suggestion: "Subscribe for more". Free text.
|
|
62
|
+
13. **Subscribe URL** — full URL of their channel (e.g. \`youtube.com/@kenkaidoesai\`). Optional but useful for description templates.
|
|
63
|
+
|
|
64
|
+
## Writing the file
|
|
65
|
+
|
|
66
|
+
Use the file-write tool path you have access to (the agent's general write tool — not a video tool). The file must be valid JSON with at minimum the fields the user provided. Skip fields they declined; do NOT write empty strings or null values.
|
|
67
|
+
|
|
68
|
+
Schema (only include keys the user actually answered):
|
|
69
|
+
|
|
70
|
+
\`\`\`json
|
|
71
|
+
{
|
|
72
|
+
"channelName": "string",
|
|
73
|
+
"logo": "string (relative path)",
|
|
74
|
+
"watermark": "string",
|
|
75
|
+
"intro": "string",
|
|
76
|
+
"outro": "string",
|
|
77
|
+
"fonts": { "heading": "string", "body": "string" },
|
|
78
|
+
"colors": { "primary": "RRGGBB", "secondary": "RRGGBB", "accent": "RRGGBB" },
|
|
79
|
+
"ctaText": "string",
|
|
80
|
+
"subscribeUrl": "string"
|
|
81
|
+
}
|
|
82
|
+
\`\`\`
|
|
83
|
+
|
|
84
|
+
\`channelStyle\` (the niche from question 2) is NOT a brand-kit field — it goes into a separate \`<cwd>/.gg/editor-styles/channel.md\` if the user wants the LLM to consistently match their voice. Offer this as a follow-up after the kit is saved.
|
|
85
|
+
|
|
86
|
+
After writing \`<cwd>/.gg/brand.json\`:
|
|
87
|
+
1. Show the user the final saved JSON (pretty-printed) so they can sanity-check.
|
|
88
|
+
2. Tell them what's next:
|
|
89
|
+
|
|
90
|
+
> Brand kit saved to \`.gg/brand.json\`. From now on, every render automatically uses these defaults. Drop your footage in this directory and try:
|
|
91
|
+
>
|
|
92
|
+
> \`Make me a YouTube video from <filename>\`
|
|
93
|
+
>
|
|
94
|
+
> The agent will pick up the brand kit silently and produce a long-form cut + Shorts + thumbnails + metadata in one prompt.
|
|
95
|
+
|
|
96
|
+
3. If they skipped colours / fonts, gently note what they're missing — the kit still works without them, but thumbnail consistency takes a hit.
|
|
97
|
+
|
|
98
|
+
## Idempotency
|
|
99
|
+
|
|
100
|
+
If \`<cwd>/.gg/brand.json\` ALREADY exists, read it first. Tell the user what's currently set and ask whether they want to (a) update specific fields, (b) start over, or (c) cancel. Default to update-specific-fields and only ask the relevant questions.
|
|
101
|
+
|
|
102
|
+
## Constraints
|
|
103
|
+
|
|
104
|
+
- Don't fabricate paths. If the user says "I have a logo at \`assets/logo.png\`" — verify the file actually exists before writing it into the JSON. If it doesn't, say so and ask if they want to fix the path or skip the field.
|
|
105
|
+
- Don't over-engineer. The brand kit is small. Don't ask about lower-third templates, end-screen positioning, or other advanced stuff in this command.
|
|
106
|
+
- Keep tone friendly and quick. This should take the user under 3 minutes.
|
|
107
|
+
`,
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
name: "audit",
|
|
111
|
+
aliases: ["pre-render"],
|
|
112
|
+
description: "Run the canonical pre-render audit chain on a video",
|
|
113
|
+
prompt: `# Pre-render audit
|
|
114
|
+
|
|
115
|
+
Run the canonical audit chain before declaring a video ready to ship. The user will provide the video path (or thumbnail + video) as args; if not provided, ASK them which file to audit and whether it's a Short or long-form.
|
|
116
|
+
|
|
117
|
+
## For Shorts (short-form)
|
|
118
|
+
|
|
119
|
+
\`\`\`
|
|
120
|
+
audit_first_frame(input) # is t=0 thumbnail-quality?
|
|
121
|
+
analyze_hook(input) # does the spoken line earn the watch in the first 3s?
|
|
122
|
+
verify_thumbnail_promise(thumbnail, input, windowSec=15)
|
|
123
|
+
\`\`\`
|
|
124
|
+
|
|
125
|
+
If any score is below the gate (\`audit_first_frame.score < 60\`, \`analyze_hook.score < 60\`, \`verify_thumbnail_promise.matches < 0.6\`), surface the failing check + the tool's suggestion. **Don't say it passes when it doesn't.**
|
|
126
|
+
|
|
127
|
+
If the hook fails specifically, run \`rewrite_hook(currentHook=..., pattern="auto")\` to produce 3 candidate rewrites and surface them to the user. Be explicit: the agent can't re-record the line — the user has to either pick an alternative opener from existing source or re-shoot.
|
|
128
|
+
|
|
129
|
+
## For long-form
|
|
130
|
+
|
|
131
|
+
\`\`\`
|
|
132
|
+
analyze_hook(input) # first 3s
|
|
133
|
+
audit_retention_structure(transcript, checkpoints=...) # 3min, 6min, 9min
|
|
134
|
+
verify_thumbnail_promise(thumbnail, input, windowSec=60) # MrBeast: match clickbait promise in first minute
|
|
135
|
+
pre_render_check(timelineEmpty=false, expectCaptions=true,
|
|
136
|
+
loudnessSource=..., loudnessTarget="youtube")
|
|
137
|
+
\`\`\`
|
|
138
|
+
|
|
139
|
+
For each weak retention checkpoint, propose ONE concrete fix (\`cut_filler_words\`, \`text_based_cut\`, \`punch_in\`, or \`add_sfx_at_cuts\`) on the surrounding window. Don't dump the whole menu.
|
|
140
|
+
|
|
141
|
+
## Reporting
|
|
142
|
+
|
|
143
|
+
End with a structured pass/fail summary:
|
|
144
|
+
|
|
145
|
+
\`\`\`
|
|
146
|
+
✅ first_frame: 82 — strong subject, clear contrast
|
|
147
|
+
⚠️ hook: 54 — silent open, no on-screen text
|
|
148
|
+
✅ thumbnail_promise: 0.78
|
|
149
|
+
❌ retention[3min]: 0.42 — flat 2:30–3:30; suggested: punch_in + add_sfx_at_cuts
|
|
150
|
+
✅ retention[6min]: 0.71
|
|
151
|
+
✅ pre_render: pass
|
|
152
|
+
\`\`\`
|
|
153
|
+
|
|
154
|
+
The user reads the table and decides what to fix. Don't auto-fix without asking.
|
|
155
|
+
`,
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
name: "diagnose",
|
|
159
|
+
aliases: ["why-no-views"],
|
|
160
|
+
description: "Diagnose an underperforming video from Studio metrics",
|
|
161
|
+
prompt: `# Diagnose underperformance
|
|
162
|
+
|
|
163
|
+
The user's video isn't getting views and they want to know why. The agent does NOT have access to YouTube Studio. Don't fabricate diagnoses.
|
|
164
|
+
|
|
165
|
+
## Step 1 — Get the numbers
|
|
166
|
+
|
|
167
|
+
ASK the user to paste from YouTube Studio:
|
|
168
|
+
|
|
169
|
+
- **Impressions** (total)
|
|
170
|
+
- **Click-through rate (CTR)** as a %
|
|
171
|
+
- **Average view duration (AVD)** as M:SS
|
|
172
|
+
- **Average percentage viewed (AVP%)** as a %
|
|
173
|
+
- **Total video length** in seconds or M:SS
|
|
174
|
+
|
|
175
|
+
If they have the retention CSV exported, accept that too — it gives much more diagnostic power. Otherwise the four numbers above are enough.
|
|
176
|
+
|
|
177
|
+
## Step 2 — Diagnose in order, surface the FIRST failing metric
|
|
178
|
+
|
|
179
|
+
Use the order from the \`youtube-algorithm-primer\` skill (read it via \`read_skill\` if you haven't this session):
|
|
180
|
+
|
|
181
|
+
1. **CTR < 4% vs the channel's typical baseline?**
|
|
182
|
+
→ The package (thumbnail + title) isn't earning the click.
|
|
183
|
+
→ Recommend running \`compose_thumbnail_variants(input=..., strategy="expression", count=3)\` plus \`generate_youtube_metadata\` for 3 fresh title candidates.
|
|
184
|
+
→ Tell the user to upload the resulting variants to YouTube Studio's **Test & Compare** (which the agent CANNOT trigger directly — it lives only in Studio). YouTube picks the winner by Watch Time Share over 1–14 days.
|
|
185
|
+
|
|
186
|
+
2. **CTR ok but AVP% < 30%?**
|
|
187
|
+
→ Hook problem.
|
|
188
|
+
→ Run \`analyze_hook\` on the video. If Shorts, also \`audit_first_frame\`.
|
|
189
|
+
→ If hook scores low, run \`rewrite_hook(pattern="auto")\` and surface 3 candidates.
|
|
190
|
+
→ Be explicit: the agent CAN'T re-record. Options: pick a different opener from existing source via \`text_based_cut\`, or re-shoot.
|
|
191
|
+
|
|
192
|
+
3. **AVP% ok but AVD low (in absolute time)?**
|
|
193
|
+
→ Pacing.
|
|
194
|
+
→ Run \`audit_retention_structure(transcript)\` to find the flat stretches.
|
|
195
|
+
→ For each weak checkpoint propose ONE fix (\`cut_filler_words\` / \`text_based_cut\` / \`punch_in\` / \`add_sfx_at_cuts\`).
|
|
196
|
+
|
|
197
|
+
4. **AVD ok but no growth past initial views?** (Session contribution.)
|
|
198
|
+
→ Outro / next-video pointer missing. Use \`generate_outro\` with the brand kit's outro chain.
|
|
199
|
+
|
|
200
|
+
5. **Engagement velocity zero in first 24h?**
|
|
201
|
+
→ Either no question in description (run \`generate_youtube_metadata\` to add one) OR small-channel reality (no algorithmic fix; tell the user honestly).
|
|
202
|
+
|
|
203
|
+
## Step 3 — Surface ONE concrete fix
|
|
204
|
+
|
|
205
|
+
Don't dump the menu. Pick the FIRST failing metric and propose one tool call. After the user runs that fix and re-uploads / re-tests, they can come back and \`/diagnose\` again on the new numbers.
|
|
206
|
+
|
|
207
|
+
## Constraints
|
|
208
|
+
|
|
209
|
+
- If the user gives one number and asks for a full diagnosis, ask for the others first. CTR alone isn't enough; CTR plus AVP% is.
|
|
210
|
+
- If the channel is genuinely small (< 1k subs) and CTR is fine but views are low, tell them: this is community-size, not an algorithmic problem. No tool fix.
|
|
211
|
+
- Cite the source from the \`youtube-algorithm-primer\` skill when the user asks "why does that metric matter?" — don't paraphrase from memory.
|
|
212
|
+
`,
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
name: "youtube",
|
|
216
|
+
aliases: ["yt"],
|
|
217
|
+
description: "Make a YouTube video (long-form + Shorts) from footage",
|
|
218
|
+
prompt: `# Canonical YouTube delivery
|
|
219
|
+
|
|
220
|
+
Run the \`youtube-end-to-end\` skill on the footage the user provides. If they didn't specify a file, ASK once for the path; otherwise just go.
|
|
221
|
+
|
|
222
|
+
## Steps (the skill is authoritative — read it if you haven't this session)
|
|
223
|
+
|
|
224
|
+
1. \`read_skill(name="youtube-end-to-end")\` if not already in your context.
|
|
225
|
+
2. \`probe_media(input)\` — duration determines whether to produce long-form, Shorts, or both. Default per the skill: > 5min source → both.
|
|
226
|
+
3. Read \`<cwd>/.gg/brand.json\` if it exists. Mention which fields you'll inherit. If it DOESN'T exist, mention that running \`/setup-channel\` first would mean every future video uses the channel's defaults automatically — but don't block on it.
|
|
227
|
+
4. Run the canonical pipeline.
|
|
228
|
+
5. Run the pre-render audit chain (\`audit_first_frame\` on Shorts, \`analyze_hook\`, \`verify_thumbnail_promise\`, \`audit_retention_structure\` for long-form).
|
|
229
|
+
6. End with the structured deliverable summary the skill prescribes (long-form path, Shorts paths, 3 candidate titles, 3 thumbnail variants, description, dropped candidates with reasons).
|
|
230
|
+
|
|
231
|
+
## Reminders
|
|
232
|
+
|
|
233
|
+
- Don't paraphrase the skill's pipeline — call it out and follow it.
|
|
234
|
+
- The agent CANNOT generate footage. If a hook fails after \`rewrite_hook\`, surface the candidates and let the user choose between recutting and re-shooting.
|
|
235
|
+
- The agent CANNOT trigger Test & Compare. Tell the user to upload the 3 thumbnails to Studio manually.
|
|
236
|
+
`,
|
|
237
|
+
},
|
|
238
|
+
];
|
|
239
|
+
/** Look up a prompt command by name or alias. Returns undefined when not found. */
|
|
240
|
+
export function getEditorPromptCommand(name) {
|
|
241
|
+
return EDITOR_PROMPT_COMMANDS.find((cmd) => cmd.name === name || cmd.aliases.includes(name));
|
|
242
|
+
}
|
|
243
|
+
//# sourceMappingURL=prompt-commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-commands.js","sourceRoot":"","sources":["../src/prompt-commands.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AASH,MAAM,CAAC,MAAM,sBAAsB,GAAoB;IACrD;QACE,IAAI,EAAE,eAAe;QACrB,OAAO,EAAE,CAAC,WAAW,CAAC;QACtB,WAAW,EAAE,oDAAoD;QACjE,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuFX;KACE;IACD;QACE,IAAI,EAAE,OAAO;QACb,OAAO,EAAE,CAAC,YAAY,CAAC;QACvB,WAAW,EAAE,qDAAqD;QAClE,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0CX;KACE;IACD;QACE,IAAI,EAAE,UAAU;QAChB,OAAO,EAAE,CAAC,cAAc,CAAC;QACzB,WAAW,EAAE,uDAAuD;QACpE,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmDX;KACE;IACD;QACE,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,CAAC,IAAI,CAAC;QACf,WAAW,EAAE,wDAAwD;QACrE,MAAM,EAAE;;;;;;;;;;;;;;;;;;CAkBX;KACE;CACF,CAAC;AAEF,mFAAmF;AACnF,MAAM,UAAU,sBAAsB,CAAC,IAAY;IACjD,OAAO,sBAAsB,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,IAAI,IAAI,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;AAC/F,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-commands.test.d.ts","sourceRoot":"","sources":["../src/prompt-commands.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { EDITOR_PROMPT_COMMANDS, getEditorPromptCommand } from "./prompt-commands.js";
|
|
3
|
+
describe("EDITOR_PROMPT_COMMANDS", () => {
|
|
4
|
+
it("registers the four bundled commands", () => {
|
|
5
|
+
expect(EDITOR_PROMPT_COMMANDS.map((c) => c.name).sort()).toEqual([
|
|
6
|
+
"audit",
|
|
7
|
+
"diagnose",
|
|
8
|
+
"setup-channel",
|
|
9
|
+
"youtube",
|
|
10
|
+
]);
|
|
11
|
+
});
|
|
12
|
+
it("every command has a non-empty prompt and description", () => {
|
|
13
|
+
for (const cmd of EDITOR_PROMPT_COMMANDS) {
|
|
14
|
+
expect(cmd.prompt.length).toBeGreaterThan(50);
|
|
15
|
+
expect(cmd.description.length).toBeGreaterThan(0);
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
it("aliases are unique across commands", () => {
|
|
19
|
+
const seen = new Set();
|
|
20
|
+
for (const cmd of EDITOR_PROMPT_COMMANDS) {
|
|
21
|
+
expect(seen.has(cmd.name)).toBe(false);
|
|
22
|
+
seen.add(cmd.name);
|
|
23
|
+
for (const a of cmd.aliases) {
|
|
24
|
+
expect(seen.has(a)).toBe(false);
|
|
25
|
+
seen.add(a);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
describe("getEditorPromptCommand", () => {
|
|
31
|
+
it("resolves by primary name", () => {
|
|
32
|
+
expect(getEditorPromptCommand("setup-channel")?.name).toBe("setup-channel");
|
|
33
|
+
expect(getEditorPromptCommand("youtube")?.name).toBe("youtube");
|
|
34
|
+
});
|
|
35
|
+
it("resolves by alias", () => {
|
|
36
|
+
expect(getEditorPromptCommand("brand-kit")?.name).toBe("setup-channel");
|
|
37
|
+
expect(getEditorPromptCommand("yt")?.name).toBe("youtube");
|
|
38
|
+
expect(getEditorPromptCommand("pre-render")?.name).toBe("audit");
|
|
39
|
+
expect(getEditorPromptCommand("why-no-views")?.name).toBe("diagnose");
|
|
40
|
+
});
|
|
41
|
+
it("returns undefined for unknown names", () => {
|
|
42
|
+
expect(getEditorPromptCommand("nope")).toBeUndefined();
|
|
43
|
+
expect(getEditorPromptCommand("")).toBeUndefined();
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
//# sourceMappingURL=prompt-commands.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-commands.test.js","sourceRoot":"","sources":["../src/prompt-commands.test.ts"],"names":[],"mappings":"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"}
|
package/dist/skills.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Bundled skill markdowns.
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
2
|
+
* Bundled skill markdowns. Auto-generated from src/skills/*.md by
|
|
3
|
+
* scripts/build-skills.mjs — DO NOT EDIT BY HAND. Add a new skill by
|
|
4
|
+
* dropping a .md file in src/skills/ (with optional YAML frontmatter)
|
|
5
|
+
* and re-running `node scripts/build-skills.mjs`.
|
|
6
6
|
*
|
|
7
|
-
* Skills are exposed through the read_skill tool; their descriptions live
|
|
8
|
-
* the system prompt. Pattern follows the Anthropic
|
|
7
|
+
* Skills are exposed through the read_skill tool; their descriptions live
|
|
8
|
+
* in the system prompt. Pattern follows the Anthropic skill convention:
|
|
9
9
|
* description in the prompt, full content on demand.
|
|
10
10
|
*/
|
|
11
11
|
export interface BundledSkill {
|
package/dist/skills.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../src/skills.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;
|
|
1
|
+
{"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../src/skills.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAgsDD,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAmD/C,CAAC;AAEF,eAAO,MAAM,WAAW,UAAsB,CAAC"}
|