varg.ai-sdk 0.1.1 → 0.4.0-alpha.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.
Files changed (246) hide show
  1. package/.claude/settings.local.json +1 -1
  2. package/.env.example +3 -0
  3. package/.github/workflows/ci.yml +23 -0
  4. package/.husky/README.md +102 -0
  5. package/.husky/commit-msg +6 -0
  6. package/.husky/pre-commit +9 -0
  7. package/.husky/pre-push +6 -0
  8. package/.size-limit.json +8 -0
  9. package/.test-hooks.ts +5 -0
  10. package/CLAUDE.md +10 -3
  11. package/CONTRIBUTING.md +150 -0
  12. package/LICENSE.md +53 -0
  13. package/README.md +56 -209
  14. package/SKILLS.md +26 -10
  15. package/biome.json +7 -1
  16. package/bun.lock +1286 -0
  17. package/commitlint.config.js +22 -0
  18. package/docs/index.html +1130 -0
  19. package/docs/prompting.md +326 -0
  20. package/docs/react.md +834 -0
  21. package/docs/sdk.md +812 -0
  22. package/ffmpeg/CLAUDE.md +68 -0
  23. package/package.json +43 -10
  24. package/pipeline/cookbooks/scripts/animate-frames-parallel.ts +84 -0
  25. package/pipeline/cookbooks/scripts/combine-scenes.sh +53 -0
  26. package/pipeline/cookbooks/scripts/generate-frames-parallel.ts +99 -0
  27. package/pipeline/cookbooks/scripts/still-to-video.sh +37 -0
  28. package/pipeline/cookbooks/text-to-tiktok.md +669 -0
  29. package/pipeline/cookbooks/trendwatching.md +156 -0
  30. package/plan.md +281 -0
  31. package/scripts/.gitkeep +0 -0
  32. package/src/ai-sdk/cache.ts +142 -0
  33. package/src/ai-sdk/examples/cached-generation.ts +53 -0
  34. package/src/ai-sdk/examples/duet-scene-4.ts +53 -0
  35. package/src/ai-sdk/examples/duet-scene-5-audio.ts +32 -0
  36. package/src/ai-sdk/examples/duet-video.ts +56 -0
  37. package/src/ai-sdk/examples/editly-composition.ts +63 -0
  38. package/src/ai-sdk/examples/editly-test.ts +57 -0
  39. package/src/ai-sdk/examples/editly-video-test.ts +52 -0
  40. package/src/ai-sdk/examples/fal-lipsync.ts +43 -0
  41. package/src/ai-sdk/examples/higgsfield-image.ts +61 -0
  42. package/src/ai-sdk/examples/music-generation.ts +19 -0
  43. package/src/ai-sdk/examples/openai-sora.ts +34 -0
  44. package/src/ai-sdk/examples/replicate-bg-removal.ts +52 -0
  45. package/src/ai-sdk/examples/simpsons-scene.ts +61 -0
  46. package/src/ai-sdk/examples/talking-lion.ts +55 -0
  47. package/src/ai-sdk/examples/video-generation.ts +39 -0
  48. package/src/ai-sdk/examples/workflow-animated-girl.ts +104 -0
  49. package/src/ai-sdk/examples/workflow-before-after.ts +114 -0
  50. package/src/ai-sdk/examples/workflow-character-grid.ts +112 -0
  51. package/src/ai-sdk/examples/workflow-slideshow.ts +161 -0
  52. package/src/ai-sdk/file-cache.ts +112 -0
  53. package/src/ai-sdk/file.ts +238 -0
  54. package/src/ai-sdk/generate-element.ts +92 -0
  55. package/src/ai-sdk/generate-music.ts +46 -0
  56. package/src/ai-sdk/generate-video.ts +165 -0
  57. package/src/ai-sdk/index.ts +72 -0
  58. package/src/ai-sdk/music-model.ts +110 -0
  59. package/src/ai-sdk/providers/editly/editly.test.ts +1108 -0
  60. package/src/ai-sdk/providers/editly/ffmpeg.ts +60 -0
  61. package/src/ai-sdk/providers/editly/index.ts +817 -0
  62. package/src/ai-sdk/providers/editly/layers.ts +776 -0
  63. package/src/ai-sdk/providers/editly/plan.md +144 -0
  64. package/src/ai-sdk/providers/editly/types.ts +328 -0
  65. package/src/ai-sdk/providers/elevenlabs-provider.ts +255 -0
  66. package/src/ai-sdk/providers/fal-provider.ts +512 -0
  67. package/src/ai-sdk/providers/higgsfield.ts +379 -0
  68. package/src/ai-sdk/providers/openai.ts +251 -0
  69. package/src/ai-sdk/providers/replicate.ts +16 -0
  70. package/src/ai-sdk/video-model.ts +185 -0
  71. package/src/cli/commands/find.tsx +137 -0
  72. package/src/cli/commands/help.tsx +85 -0
  73. package/src/cli/commands/index.ts +6 -0
  74. package/src/cli/commands/list.tsx +238 -0
  75. package/src/cli/commands/render.tsx +71 -0
  76. package/src/cli/commands/run.tsx +511 -0
  77. package/src/cli/commands/which.tsx +253 -0
  78. package/src/cli/index.ts +114 -0
  79. package/src/cli/quiet.ts +44 -0
  80. package/src/cli/types.ts +32 -0
  81. package/src/cli/ui/components/Badge.tsx +29 -0
  82. package/src/cli/ui/components/DataTable.tsx +51 -0
  83. package/src/cli/ui/components/Header.tsx +23 -0
  84. package/src/cli/ui/components/HelpBlock.tsx +44 -0
  85. package/src/cli/ui/components/KeyValue.tsx +33 -0
  86. package/src/cli/ui/components/OptionRow.tsx +81 -0
  87. package/src/cli/ui/components/Separator.tsx +23 -0
  88. package/src/cli/ui/components/StatusBox.tsx +108 -0
  89. package/src/cli/ui/components/VargBox.tsx +51 -0
  90. package/src/cli/ui/components/VargProgress.tsx +36 -0
  91. package/src/cli/ui/components/VargSpinner.tsx +34 -0
  92. package/src/cli/ui/components/VargText.tsx +56 -0
  93. package/src/cli/ui/components/index.ts +19 -0
  94. package/src/cli/ui/index.ts +12 -0
  95. package/src/cli/ui/render.ts +35 -0
  96. package/src/cli/ui/theme.ts +63 -0
  97. package/src/cli/utils.ts +78 -0
  98. package/src/core/executor/executor.ts +201 -0
  99. package/src/core/executor/index.ts +13 -0
  100. package/src/core/executor/job.ts +214 -0
  101. package/src/core/executor/pipeline.ts +222 -0
  102. package/src/core/index.ts +11 -0
  103. package/src/core/registry/index.ts +9 -0
  104. package/src/core/registry/loader.ts +149 -0
  105. package/src/core/registry/registry.ts +221 -0
  106. package/src/core/registry/resolver.ts +206 -0
  107. package/src/core/schema/helpers.ts +134 -0
  108. package/src/core/schema/index.ts +8 -0
  109. package/src/core/schema/shared.ts +102 -0
  110. package/src/core/schema/types.ts +279 -0
  111. package/src/core/schema/validator.ts +92 -0
  112. package/src/definitions/actions/captions.ts +261 -0
  113. package/src/definitions/actions/edit.ts +298 -0
  114. package/src/definitions/actions/image.ts +125 -0
  115. package/src/definitions/actions/index.ts +114 -0
  116. package/src/definitions/actions/music.ts +205 -0
  117. package/src/definitions/actions/sync.ts +128 -0
  118. package/{action/transcribe/index.ts → src/definitions/actions/transcribe.ts} +58 -68
  119. package/src/definitions/actions/upload.ts +111 -0
  120. package/src/definitions/actions/video.ts +163 -0
  121. package/src/definitions/actions/voice.ts +119 -0
  122. package/src/definitions/index.ts +23 -0
  123. package/src/definitions/models/elevenlabs.ts +50 -0
  124. package/src/definitions/models/flux.ts +56 -0
  125. package/src/definitions/models/index.ts +36 -0
  126. package/src/definitions/models/kling.ts +56 -0
  127. package/src/definitions/models/llama.ts +54 -0
  128. package/src/definitions/models/nano-banana-pro.ts +102 -0
  129. package/src/definitions/models/sonauto.ts +68 -0
  130. package/src/definitions/models/soul.ts +65 -0
  131. package/src/definitions/models/wan.ts +54 -0
  132. package/src/definitions/models/whisper.ts +44 -0
  133. package/src/definitions/skills/index.ts +12 -0
  134. package/src/definitions/skills/talking-character.ts +87 -0
  135. package/src/definitions/skills/text-to-tiktok.ts +97 -0
  136. package/src/index.ts +118 -0
  137. package/src/providers/apify.ts +269 -0
  138. package/src/providers/base.ts +264 -0
  139. package/src/providers/elevenlabs.ts +217 -0
  140. package/src/providers/fal.ts +392 -0
  141. package/src/providers/ffmpeg.ts +544 -0
  142. package/src/providers/fireworks.ts +193 -0
  143. package/src/providers/groq.ts +149 -0
  144. package/src/providers/higgsfield.ts +145 -0
  145. package/src/providers/index.ts +143 -0
  146. package/src/providers/replicate.ts +147 -0
  147. package/src/providers/storage.ts +206 -0
  148. package/src/react/cli.ts +52 -0
  149. package/src/react/elements.ts +146 -0
  150. package/src/react/examples/branching.tsx +66 -0
  151. package/src/react/examples/captions-demo.tsx +37 -0
  152. package/src/react/examples/character-video.tsx +84 -0
  153. package/src/react/examples/grid.tsx +53 -0
  154. package/src/react/examples/layouts-demo.tsx +57 -0
  155. package/src/react/examples/madi.tsx +60 -0
  156. package/src/react/examples/music-test.tsx +35 -0
  157. package/src/react/examples/onlyfans-1m/workflow.tsx +88 -0
  158. package/src/react/examples/orange-portrait.tsx +41 -0
  159. package/src/react/examples/split-element-demo.tsx +60 -0
  160. package/src/react/examples/split-layout-demo.tsx +60 -0
  161. package/src/react/examples/split.tsx +41 -0
  162. package/src/react/examples/video-grid.tsx +46 -0
  163. package/src/react/index.ts +43 -0
  164. package/src/react/layouts/grid.tsx +28 -0
  165. package/src/react/layouts/index.ts +2 -0
  166. package/src/react/layouts/split.tsx +20 -0
  167. package/src/react/react.test.ts +309 -0
  168. package/src/react/render.ts +21 -0
  169. package/src/react/renderers/animate.ts +59 -0
  170. package/src/react/renderers/captions.ts +297 -0
  171. package/src/react/renderers/clip.ts +248 -0
  172. package/src/react/renderers/context.ts +17 -0
  173. package/src/react/renderers/image.ts +109 -0
  174. package/src/react/renderers/index.ts +22 -0
  175. package/src/react/renderers/music.ts +60 -0
  176. package/src/react/renderers/packshot.ts +84 -0
  177. package/src/react/renderers/progress.ts +173 -0
  178. package/src/react/renderers/render.ts +243 -0
  179. package/src/react/renderers/slider.ts +69 -0
  180. package/src/react/renderers/speech.ts +53 -0
  181. package/src/react/renderers/split.ts +91 -0
  182. package/src/react/renderers/subtitle.ts +16 -0
  183. package/src/react/renderers/swipe.ts +75 -0
  184. package/src/react/renderers/title.ts +17 -0
  185. package/src/react/renderers/utils.ts +124 -0
  186. package/src/react/renderers/video.ts +127 -0
  187. package/src/react/runtime/jsx-dev-runtime.ts +43 -0
  188. package/src/react/runtime/jsx-runtime.ts +35 -0
  189. package/src/react/types.ts +232 -0
  190. package/src/studio/index.ts +26 -0
  191. package/src/studio/scanner.ts +102 -0
  192. package/src/studio/server.ts +554 -0
  193. package/src/studio/stages.ts +251 -0
  194. package/src/studio/step-renderer.ts +279 -0
  195. package/src/studio/types.ts +60 -0
  196. package/src/studio/ui/cache.html +303 -0
  197. package/src/studio/ui/index.html +1820 -0
  198. package/src/tests/all.test.ts +509 -0
  199. package/src/tests/index.ts +33 -0
  200. package/src/tests/unit.test.ts +403 -0
  201. package/tsconfig.cli.json +8 -0
  202. package/tsconfig.json +21 -3
  203. package/TEST_RESULTS.md +0 -122
  204. package/action/captions/SKILL.md +0 -170
  205. package/action/captions/index.ts +0 -169
  206. package/action/edit/SKILL.md +0 -235
  207. package/action/edit/index.ts +0 -437
  208. package/action/image/SKILL.md +0 -140
  209. package/action/image/index.ts +0 -105
  210. package/action/sync/SKILL.md +0 -136
  211. package/action/sync/index.ts +0 -145
  212. package/action/transcribe/SKILL.md +0 -179
  213. package/action/video/SKILL.md +0 -116
  214. package/action/video/index.ts +0 -125
  215. package/action/voice/SKILL.md +0 -125
  216. package/action/voice/index.ts +0 -136
  217. package/cli/commands/find.ts +0 -58
  218. package/cli/commands/help.ts +0 -70
  219. package/cli/commands/list.ts +0 -49
  220. package/cli/commands/run.ts +0 -237
  221. package/cli/commands/which.ts +0 -66
  222. package/cli/discover.ts +0 -66
  223. package/cli/index.ts +0 -33
  224. package/cli/runner.ts +0 -65
  225. package/cli/types.ts +0 -49
  226. package/cli/ui.ts +0 -185
  227. package/index.ts +0 -75
  228. package/lib/README.md +0 -144
  229. package/lib/ai-sdk/fal.ts +0 -106
  230. package/lib/ai-sdk/replicate.ts +0 -107
  231. package/lib/elevenlabs.ts +0 -382
  232. package/lib/fal.ts +0 -467
  233. package/lib/ffmpeg.ts +0 -467
  234. package/lib/fireworks.ts +0 -235
  235. package/lib/groq.ts +0 -246
  236. package/lib/higgsfield.ts +0 -176
  237. package/lib/remotion/SKILL.md +0 -823
  238. package/lib/remotion/cli.ts +0 -115
  239. package/lib/remotion/functions.ts +0 -283
  240. package/lib/remotion/index.ts +0 -19
  241. package/lib/remotion/templates.ts +0 -73
  242. package/lib/replicate.ts +0 -304
  243. package/output.txt +0 -1
  244. package/test-import.ts +0 -7
  245. package/test-services.ts +0 -97
  246. package/utilities/s3.ts +0 -147
@@ -1,125 +0,0 @@
1
- ---
2
- name: voice-synthesis
3
- description: generate realistic text-to-speech audio using elevenlabs with multiple voice options. use when user needs voiceovers, narration, character voices, or audio for lipsync videos.
4
- allowed-tools: Read, Bash
5
- ---
6
-
7
- # voice synthesis
8
-
9
- generate high-quality text-to-speech audio with elevenlabs.
10
-
11
- ## available voices
12
-
13
- - **rachel** - clear, professional female voice
14
- - **domi** - warm, friendly female voice
15
- - **bella** - energetic female voice
16
- - **antoni** - friendly male voice
17
- - **elli** - young, clear female voice
18
- - **josh** - deep, clear male voice
19
- - **arnold** - strong, authoritative male voice
20
- - **adam** - natural, conversational male voice
21
- - **sam** - raspy, character male voice
22
-
23
- ## usage
24
-
25
- ### generate voice
26
- ```bash
27
- bun run service/voice.ts generate <text> [voice] [provider] [upload]
28
- ```
29
-
30
- **parameters:**
31
- - `text` (required): text to convert to speech
32
- - `voice` (optional): voice name (default: rachel)
33
- - `provider` (optional): elevenlabs (default)
34
- - `upload` (optional): "true" to upload to s3
35
-
36
- **example:**
37
- ```bash
38
- bun run service/voice.ts generate "hello world, this is my voice" rachel elevenlabs true
39
- ```
40
-
41
- ### shorthand for elevenlabs
42
- ```bash
43
- bun run service/voice.ts elevenlabs <text> [voice] [upload]
44
- ```
45
-
46
- **example:**
47
- ```bash
48
- bun run service/voice.ts elevenlabs "welcome to our video" josh true
49
- ```
50
-
51
- ## as library
52
-
53
- ```typescript
54
- import { generateVoice } from "./service/voice"
55
-
56
- const result = await generateVoice({
57
- text: "hello world",
58
- voice: "rachel",
59
- provider: "elevenlabs",
60
- upload: true,
61
- outputPath: "media/voiceover.mp3"
62
- })
63
-
64
- console.log(result.provider)
65
- console.log(result.voiceId)
66
- console.log(result.uploadUrl)
67
- ```
68
-
69
- ## output
70
-
71
- returns `VoiceResult`:
72
- ```typescript
73
- {
74
- audio: Buffer, // raw audio buffer
75
- provider: string, // "elevenlabs"
76
- voiceId: string, // actual voice id used
77
- uploadUrl?: string // s3 url if upload requested
78
- }
79
- ```
80
-
81
- saves audio file to `media/voice-{timestamp}.mp3`
82
-
83
- ## when to use
84
-
85
- use this skill when:
86
- - creating voiceovers for videos
87
- - generating narration or character dialogue
88
- - preparing audio for lipsync videos
89
- - need text-to-speech for talking character pipeline
90
- - testing different voice options
91
-
92
- ## tips
93
-
94
- **voice selection:**
95
- - use **rachel** or **josh** for professional narration
96
- - use **bella** or **antoni** for friendly, casual content
97
- - use **arnold** for authoritative or dramatic content
98
- - use **sam** for character or stylized voices
99
-
100
- **text formatting:**
101
- - add punctuation for natural pauses
102
- - use shorter sentences for clearer speech
103
- - spell out numbers and abbreviations
104
-
105
- ## integration with other services
106
-
107
- perfect companion for:
108
- - **lipsync service** - sync generated voice with video
109
- - **video generation** - create talking character videos
110
- - **captions service** - auto-generate subtitles from voiceover
111
-
112
- ## environment variables
113
-
114
- required:
115
- - `ELEVENLABS_API_KEY` - for voice generation
116
-
117
- optional (for s3 upload):
118
- - `CLOUDFLARE_R2_API_URL`
119
- - `CLOUDFLARE_ACCESS_KEY_ID`
120
- - `CLOUDFLARE_ACCESS_SECRET`
121
- - `CLOUDFLARE_R2_BUCKET`
122
-
123
- ## generation time
124
-
125
- expect 5-15 seconds depending on text length
@@ -1,136 +0,0 @@
1
- #!/usr/bin/env bun
2
-
3
- /**
4
- * voice service - high-level voice generation combining multiple providers
5
- * supports elevenlabs and future providers
6
- */
7
-
8
- import type { ActionMeta } from "../../cli/types";
9
- import { textToSpeech, VOICES } from "../../lib/elevenlabs";
10
- import { uploadFile } from "../../utilities/s3";
11
-
12
- export const meta: ActionMeta = {
13
- name: "voice",
14
- type: "action",
15
- description: "text to speech generation",
16
- inputType: "text",
17
- outputType: "audio",
18
- schema: {
19
- input: {
20
- type: "object",
21
- required: ["text"],
22
- properties: {
23
- text: { type: "string", description: "text to convert to speech" },
24
- voice: {
25
- type: "string",
26
- enum: ["rachel", "domi", "bella", "antoni", "josh", "adam", "sam"],
27
- default: "rachel",
28
- description: "voice to use",
29
- },
30
- output: {
31
- type: "string",
32
- format: "file-path",
33
- description: "output file path",
34
- },
35
- },
36
- },
37
- output: { type: "string", format: "file-path", description: "audio path" },
38
- },
39
- async run(options) {
40
- const { text, voice, output } = options as {
41
- text: string;
42
- voice?: string;
43
- output?: string;
44
- };
45
- return generateVoice({ text, voice, outputPath: output });
46
- },
47
- };
48
-
49
- // types
50
- export interface GenerateVoiceOptions {
51
- text: string;
52
- voice?: string;
53
- provider?: "elevenlabs";
54
- upload?: boolean;
55
- outputPath?: string;
56
- }
57
-
58
- export interface VoiceResult {
59
- audio: Buffer;
60
- provider: string;
61
- voiceId: string;
62
- uploadUrl?: string;
63
- }
64
-
65
- // core functions
66
- export async function generateVoice(
67
- options: GenerateVoiceOptions,
68
- ): Promise<VoiceResult> {
69
- const {
70
- text,
71
- voice = "rachel",
72
- provider = "elevenlabs",
73
- upload = false,
74
- outputPath,
75
- } = options;
76
-
77
- if (!text) {
78
- throw new Error("text is required");
79
- }
80
-
81
- console.log(`[voice] generating with ${provider} (${voice})...`);
82
-
83
- let audio: Buffer;
84
- let voiceId: string;
85
-
86
- switch (provider) {
87
- case "elevenlabs": {
88
- // map friendly names to voice ids
89
- const voiceMap: Record<string, string> = {
90
- rachel: VOICES.RACHEL,
91
- domi: VOICES.DOMI,
92
- bella: VOICES.BELLA,
93
- antoni: VOICES.ANTONI,
94
- elli: VOICES.ELLI,
95
- josh: VOICES.JOSH,
96
- arnold: VOICES.ARNOLD,
97
- adam: VOICES.ADAM,
98
- sam: VOICES.SAM,
99
- };
100
-
101
- voiceId = voiceMap[voice.toLowerCase()] || voice;
102
-
103
- audio = await textToSpeech({
104
- text,
105
- voiceId,
106
- outputPath,
107
- });
108
- break;
109
- }
110
-
111
- default:
112
- throw new Error(`unsupported provider: ${provider}`);
113
- }
114
-
115
- const result: VoiceResult = {
116
- audio,
117
- provider,
118
- voiceId,
119
- };
120
-
121
- // upload to s3 if requested
122
- if (upload && outputPath) {
123
- const objectKey = `voice/${Date.now()}-${voice}.mp3`;
124
- const uploadUrl = await uploadFile(outputPath, objectKey);
125
- result.uploadUrl = uploadUrl;
126
- console.log(`[voice] uploaded to ${uploadUrl}`);
127
- }
128
-
129
- return result;
130
- }
131
-
132
- // cli
133
- if (import.meta.main) {
134
- const { runCli } = await import("../../cli/runner");
135
- runCli(meta);
136
- }
@@ -1,58 +0,0 @@
1
- /**
2
- * varg find command
3
- * fuzzy search by scanning filesystem
4
- */
5
-
6
- import { defineCommand } from "citty";
7
- import { search } from "../discover";
8
- import { box, c, header, separator } from "../ui";
9
-
10
- export const findCmd = defineCommand({
11
- meta: {
12
- name: "find",
13
- description: "fuzzy search for models/actions",
14
- },
15
- args: {
16
- query: {
17
- type: "positional",
18
- description: "search query",
19
- required: true,
20
- },
21
- },
22
- async run({ args }) {
23
- const query = args.query;
24
-
25
- if (!query) {
26
- console.error(`${c.red("error:")} search query required`);
27
- console.log(`\nusage: ${c.cyan("varg find <query>")}`);
28
- process.exit(1);
29
- }
30
-
31
- const results = await search(query);
32
-
33
- if (results.length === 0) {
34
- console.log(`\nno matches for "${query}"`);
35
- console.log(`\ntry ${c.cyan("varg list")} to see all available actions`);
36
- return;
37
- }
38
-
39
- const content: string[] = [];
40
- content.push("");
41
- content.push(header("MATCHES"));
42
- content.push("");
43
-
44
- for (const action of results) {
45
- content.push(
46
- ` ${c.cyan(action.name.padEnd(16))}${action.inputType} → ${action.outputType}`,
47
- );
48
- }
49
-
50
- content.push("");
51
- content.push(separator());
52
- content.push("");
53
- content.push(` run ${c.cyan("varg run <name> --help")} for usage`);
54
- content.push("");
55
-
56
- console.log(box(`search: "${query}"`, content));
57
- },
58
- });
@@ -1,70 +0,0 @@
1
- /**
2
- * varg help command
3
- */
4
-
5
- import { defineCommand } from "citty";
6
- import { box, c, header, separator } from "../ui";
7
-
8
- export const helpCmd = defineCommand({
9
- meta: {
10
- name: "help",
11
- description: "show help",
12
- },
13
- run() {
14
- const content: string[] = [];
15
- content.push("");
16
- content.push(" AI video infrastructure from your terminal.");
17
- content.push("");
18
- content.push(separator());
19
- content.push("");
20
- content.push(header("USAGE"));
21
- content.push("");
22
- content.push(` varg ${c.cyan("<command>")} [target] [options]`);
23
- content.push("");
24
- content.push(separator());
25
- content.push("");
26
- content.push(header("COMMANDS"));
27
- content.push("");
28
- content.push(` ${c.cyan("run".padEnd(12))}run a model or action`);
29
- content.push(` ${c.cyan("list".padEnd(12))}discover what's available`);
30
- content.push(
31
- ` ${c.cyan("find".padEnd(12))}fuzzy search for models/actions`,
32
- );
33
- content.push(
34
- ` ${c.cyan("which".padEnd(12))}inspect what's behind an action`,
35
- );
36
- content.push(` ${c.cyan("help".padEnd(12))}show this help`);
37
- content.push("");
38
- content.push(separator());
39
- content.push("");
40
- content.push(header("EXAMPLES"));
41
- content.push("");
42
- content.push(` ${c.dim("# generate video from text")}`);
43
- content.push(` varg run kling --prompt "a cat dancing"`);
44
- content.push("");
45
- content.push(` ${c.dim("# animate an image")}`);
46
- content.push(` varg run image-to-video --image ./cat.png`);
47
- content.push("");
48
- content.push(` ${c.dim("# transcribe audio")}`);
49
- content.push(` varg run transcribe ./video.mp4`);
50
- content.push("");
51
- content.push(` ${c.dim("# see what's available")}`);
52
- content.push(` varg list`);
53
- content.push("");
54
- content.push(separator());
55
- content.push("");
56
- content.push(header("ENVIRONMENT"));
57
- content.push("");
58
- content.push(` ${c.dim("FAL_KEY".padEnd(24))}fal.ai api key`);
59
- content.push(
60
- ` ${c.dim("REPLICATE_API_TOKEN".padEnd(24))}replicate api key`,
61
- );
62
- content.push(
63
- ` ${c.dim("ELEVENLABS_API_KEY".padEnd(24))}elevenlabs api key`,
64
- );
65
- content.push(` ${c.dim("GROQ_API_KEY".padEnd(24))}groq api key`);
66
- content.push("");
67
-
68
- console.log(box("varg", content));
69
- },
70
- });
@@ -1,49 +0,0 @@
1
- /**
2
- * varg list command
3
- * discover what's available by scanning filesystem
4
- */
5
-
6
- import { defineCommand } from "citty";
7
- import { discoverActions } from "../discover";
8
- import { box, c, header, separator, table } from "../ui";
9
-
10
- export const listCmd = defineCommand({
11
- meta: {
12
- name: "list",
13
- description: "discover what's available",
14
- },
15
- args: {
16
- filter: {
17
- type: "positional",
18
- description: "filter by type",
19
- required: false,
20
- },
21
- },
22
- async run() {
23
- const actions = await discoverActions();
24
-
25
- const content: string[] = [];
26
- content.push("");
27
-
28
- content.push(header("ACTIONS"));
29
- content.push("");
30
-
31
- const rows = actions.map((a) => ({
32
- name: a.name,
33
- description:
34
- `${a.inputType} → ${a.outputType}`.padEnd(20) + a.description,
35
- }));
36
-
37
- content.push(...table(rows));
38
- content.push("");
39
-
40
- content.push(separator());
41
- content.push("");
42
- content.push(
43
- ` ${actions.length} actions · run ${c.cyan("varg run <action> --info")} for details`,
44
- );
45
- content.push("");
46
-
47
- console.log(box("varg", content));
48
- },
49
- });
@@ -1,237 +0,0 @@
1
- /**
2
- * varg run command
3
- * execute actions by scanning filesystem
4
- */
5
-
6
- import { existsSync } from "node:fs";
7
- import { defineCommand } from "citty";
8
- import { resolve } from "../discover";
9
- import type { Meta } from "../types";
10
- import { box, c, runningBox } from "../ui";
11
-
12
- interface RunOptions {
13
- [key: string]: string | boolean | undefined;
14
- info?: boolean;
15
- schema?: boolean;
16
- json?: boolean;
17
- quiet?: boolean;
18
- }
19
-
20
- function parseArgs(args: string[]): { target: string; options: RunOptions } {
21
- const options: RunOptions = {};
22
- let target = "";
23
-
24
- for (let i = 0; i < args.length; i++) {
25
- const arg = args[i];
26
- if (!arg) continue;
27
-
28
- if (arg.startsWith("--")) {
29
- const key = arg.slice(2);
30
- if (
31
- key === "info" ||
32
- key === "schema" ||
33
- key === "json" ||
34
- key === "quiet"
35
- ) {
36
- options[key] = true;
37
- } else {
38
- const value = args[++i];
39
- if (value) options[key] = value;
40
- }
41
- } else if (!target) {
42
- target = arg;
43
- } else {
44
- // positional args - check if it looks like a file
45
- if (existsSync(arg) || arg.startsWith("./") || arg.startsWith("/")) {
46
- if (!options.image && !options.audio) {
47
- options.image = arg;
48
- }
49
- } else if (!options.prompt && !options.text) {
50
- options.prompt = arg;
51
- }
52
- }
53
- }
54
-
55
- return { target, options };
56
- }
57
-
58
- function showHelp(item: Meta) {
59
- const content: string[] = [];
60
- content.push("");
61
- content.push(` ${item.description}`);
62
- content.push("");
63
- content.push(c.bold(c.dim(" USAGE")));
64
- content.push("");
65
-
66
- const required = item.schema.input.required;
67
- const reqArgs = required.map((r) => `--${r} <${r}>`).join(" ");
68
- content.push(` varg run ${item.name} ${reqArgs} [options]`);
69
-
70
- content.push("");
71
- content.push(c.bold(c.dim(" OPTIONS")));
72
- content.push("");
73
-
74
- for (const [key, prop] of Object.entries(item.schema.input.properties)) {
75
- const req = item.schema.input.required.includes(key);
76
- const reqTag = req ? c.yellow(" (required)") : "";
77
- const defaultVal =
78
- prop.default !== undefined ? c.dim(` default: ${prop.default}`) : "";
79
- const enumVals = prop.enum ? c.dim(` [${prop.enum.join(", ")}]`) : "";
80
-
81
- content.push(
82
- ` --${key.padEnd(12)}${prop.description}${reqTag}${defaultVal}${enumVals}`,
83
- );
84
- }
85
-
86
- content.push("");
87
- content.push(` --json output result as json`);
88
- content.push(` --quiet minimal output`);
89
- content.push(` --info show this help`);
90
- content.push("");
91
-
92
- console.log(box(`action: ${item.name}`, content));
93
- }
94
-
95
- function showSchema(item: Meta) {
96
- const schema = {
97
- name: item.name,
98
- type: item.type,
99
- description: item.description,
100
- input: item.schema.input,
101
- output: item.schema.output,
102
- };
103
-
104
- console.log(JSON.stringify(schema, null, 2));
105
- }
106
-
107
- export const runCmd = defineCommand({
108
- meta: {
109
- name: "run",
110
- description: "run a model or action",
111
- },
112
- args: {
113
- target: {
114
- type: "positional",
115
- description: "action to run",
116
- required: false,
117
- },
118
- info: {
119
- type: "boolean",
120
- description: "show action info",
121
- },
122
- schema: {
123
- type: "boolean",
124
- description: "show action schema as json",
125
- },
126
- json: {
127
- type: "boolean",
128
- description: "output result as json",
129
- },
130
- quiet: {
131
- type: "boolean",
132
- description: "minimal output",
133
- },
134
- },
135
- async run({ rawArgs }) {
136
- // use rawArgs for dynamic action options
137
- const { target, options } = parseArgs(rawArgs);
138
-
139
- if (!target) {
140
- console.error(`${c.red("error:")} target required`);
141
- console.log(`\nusage: ${c.cyan("varg run <action> [options]")}`);
142
- console.log(`\nrun ${c.cyan("varg list")} to see available actions`);
143
- process.exit(1);
144
- }
145
-
146
- const item = await resolve(target);
147
-
148
- if (!item) {
149
- console.error(`${c.red("error:")} '${target}' not found`);
150
- console.log(`\nrun ${c.cyan("varg list")} to see available actions`);
151
- process.exit(1);
152
- }
153
-
154
- if (options.info) {
155
- showHelp(item);
156
- return;
157
- }
158
-
159
- if (options.schema) {
160
- showSchema(item);
161
- return;
162
- }
163
-
164
- // validate required args
165
- for (const req of item.schema.input.required) {
166
- if (!options[req]) {
167
- console.error(`${c.red("error:")} --${req} is required`);
168
- console.log(`\nrun ${c.cyan(`varg run ${target} --info`)} for usage`);
169
- process.exit(1);
170
- }
171
- }
172
-
173
- // build params for display
174
- const params: Record<string, string> = {};
175
- for (const key of Object.keys(item.schema.input.properties)) {
176
- if (options[key] && typeof options[key] === "string") {
177
- params[key] = options[key] as string;
178
- }
179
- }
180
-
181
- if (!options.quiet && !options.json) {
182
- console.log(runningBox(target, params, "running"));
183
- }
184
-
185
- const startTime = Date.now();
186
-
187
- try {
188
- const result = await item.run(options);
189
- const elapsed = Date.now() - startTime;
190
-
191
- if (options.json) {
192
- console.log(JSON.stringify({ success: true, result, time: elapsed }));
193
- } else if (options.quiet) {
194
- console.log(JSON.stringify(result));
195
- } else {
196
- // extract url from result if present
197
- const resultObj = result as Record<string, unknown> | null;
198
- const url =
199
- resultObj?.imageUrl || resultObj?.videoUrl || resultObj?.url || null;
200
-
201
- console.log("\x1b[2J\x1b[H");
202
- console.log(
203
- runningBox(target, params, "done", {
204
- output: url ? "saved" : "done",
205
- time: elapsed,
206
- }),
207
- );
208
-
209
- // print url outside box so it's clickable
210
- if (url) {
211
- console.log(`\n ${c.cyan("url")} ${url}\n`);
212
- }
213
- }
214
- } catch (err) {
215
- const elapsed = Date.now() - startTime;
216
- const errorMsg = err instanceof Error ? err.message : String(err);
217
-
218
- if (options.json) {
219
- console.log(
220
- JSON.stringify({ success: false, error: errorMsg, time: elapsed }),
221
- );
222
- } else if (options.quiet) {
223
- console.error(errorMsg);
224
- } else {
225
- console.log("\x1b[2J\x1b[H");
226
- console.log(
227
- runningBox(target, params, "error", {
228
- error: errorMsg,
229
- time: elapsed,
230
- }),
231
- );
232
- }
233
-
234
- process.exit(1);
235
- }
236
- },
237
- });