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.
- package/.claude/settings.local.json +1 -1
- package/.env.example +3 -0
- package/.github/workflows/ci.yml +23 -0
- package/.husky/README.md +102 -0
- package/.husky/commit-msg +6 -0
- package/.husky/pre-commit +9 -0
- package/.husky/pre-push +6 -0
- package/.size-limit.json +8 -0
- package/.test-hooks.ts +5 -0
- package/CLAUDE.md +10 -3
- package/CONTRIBUTING.md +150 -0
- package/LICENSE.md +53 -0
- package/README.md +56 -209
- package/SKILLS.md +26 -10
- package/biome.json +7 -1
- package/bun.lock +1286 -0
- package/commitlint.config.js +22 -0
- package/docs/index.html +1130 -0
- package/docs/prompting.md +326 -0
- package/docs/react.md +834 -0
- package/docs/sdk.md +812 -0
- package/ffmpeg/CLAUDE.md +68 -0
- package/package.json +43 -10
- package/pipeline/cookbooks/scripts/animate-frames-parallel.ts +84 -0
- package/pipeline/cookbooks/scripts/combine-scenes.sh +53 -0
- package/pipeline/cookbooks/scripts/generate-frames-parallel.ts +99 -0
- package/pipeline/cookbooks/scripts/still-to-video.sh +37 -0
- package/pipeline/cookbooks/text-to-tiktok.md +669 -0
- package/pipeline/cookbooks/trendwatching.md +156 -0
- package/plan.md +281 -0
- package/scripts/.gitkeep +0 -0
- package/src/ai-sdk/cache.ts +142 -0
- package/src/ai-sdk/examples/cached-generation.ts +53 -0
- package/src/ai-sdk/examples/duet-scene-4.ts +53 -0
- package/src/ai-sdk/examples/duet-scene-5-audio.ts +32 -0
- package/src/ai-sdk/examples/duet-video.ts +56 -0
- package/src/ai-sdk/examples/editly-composition.ts +63 -0
- package/src/ai-sdk/examples/editly-test.ts +57 -0
- package/src/ai-sdk/examples/editly-video-test.ts +52 -0
- package/src/ai-sdk/examples/fal-lipsync.ts +43 -0
- package/src/ai-sdk/examples/higgsfield-image.ts +61 -0
- package/src/ai-sdk/examples/music-generation.ts +19 -0
- package/src/ai-sdk/examples/openai-sora.ts +34 -0
- package/src/ai-sdk/examples/replicate-bg-removal.ts +52 -0
- package/src/ai-sdk/examples/simpsons-scene.ts +61 -0
- package/src/ai-sdk/examples/talking-lion.ts +55 -0
- package/src/ai-sdk/examples/video-generation.ts +39 -0
- package/src/ai-sdk/examples/workflow-animated-girl.ts +104 -0
- package/src/ai-sdk/examples/workflow-before-after.ts +114 -0
- package/src/ai-sdk/examples/workflow-character-grid.ts +112 -0
- package/src/ai-sdk/examples/workflow-slideshow.ts +161 -0
- package/src/ai-sdk/file-cache.ts +112 -0
- package/src/ai-sdk/file.ts +238 -0
- package/src/ai-sdk/generate-element.ts +92 -0
- package/src/ai-sdk/generate-music.ts +46 -0
- package/src/ai-sdk/generate-video.ts +165 -0
- package/src/ai-sdk/index.ts +72 -0
- package/src/ai-sdk/music-model.ts +110 -0
- package/src/ai-sdk/providers/editly/editly.test.ts +1108 -0
- package/src/ai-sdk/providers/editly/ffmpeg.ts +60 -0
- package/src/ai-sdk/providers/editly/index.ts +817 -0
- package/src/ai-sdk/providers/editly/layers.ts +776 -0
- package/src/ai-sdk/providers/editly/plan.md +144 -0
- package/src/ai-sdk/providers/editly/types.ts +328 -0
- package/src/ai-sdk/providers/elevenlabs-provider.ts +255 -0
- package/src/ai-sdk/providers/fal-provider.ts +512 -0
- package/src/ai-sdk/providers/higgsfield.ts +379 -0
- package/src/ai-sdk/providers/openai.ts +251 -0
- package/src/ai-sdk/providers/replicate.ts +16 -0
- package/src/ai-sdk/video-model.ts +185 -0
- package/src/cli/commands/find.tsx +137 -0
- package/src/cli/commands/help.tsx +85 -0
- package/src/cli/commands/index.ts +6 -0
- package/src/cli/commands/list.tsx +238 -0
- package/src/cli/commands/render.tsx +71 -0
- package/src/cli/commands/run.tsx +511 -0
- package/src/cli/commands/which.tsx +253 -0
- package/src/cli/index.ts +114 -0
- package/src/cli/quiet.ts +44 -0
- package/src/cli/types.ts +32 -0
- package/src/cli/ui/components/Badge.tsx +29 -0
- package/src/cli/ui/components/DataTable.tsx +51 -0
- package/src/cli/ui/components/Header.tsx +23 -0
- package/src/cli/ui/components/HelpBlock.tsx +44 -0
- package/src/cli/ui/components/KeyValue.tsx +33 -0
- package/src/cli/ui/components/OptionRow.tsx +81 -0
- package/src/cli/ui/components/Separator.tsx +23 -0
- package/src/cli/ui/components/StatusBox.tsx +108 -0
- package/src/cli/ui/components/VargBox.tsx +51 -0
- package/src/cli/ui/components/VargProgress.tsx +36 -0
- package/src/cli/ui/components/VargSpinner.tsx +34 -0
- package/src/cli/ui/components/VargText.tsx +56 -0
- package/src/cli/ui/components/index.ts +19 -0
- package/src/cli/ui/index.ts +12 -0
- package/src/cli/ui/render.ts +35 -0
- package/src/cli/ui/theme.ts +63 -0
- package/src/cli/utils.ts +78 -0
- package/src/core/executor/executor.ts +201 -0
- package/src/core/executor/index.ts +13 -0
- package/src/core/executor/job.ts +214 -0
- package/src/core/executor/pipeline.ts +222 -0
- package/src/core/index.ts +11 -0
- package/src/core/registry/index.ts +9 -0
- package/src/core/registry/loader.ts +149 -0
- package/src/core/registry/registry.ts +221 -0
- package/src/core/registry/resolver.ts +206 -0
- package/src/core/schema/helpers.ts +134 -0
- package/src/core/schema/index.ts +8 -0
- package/src/core/schema/shared.ts +102 -0
- package/src/core/schema/types.ts +279 -0
- package/src/core/schema/validator.ts +92 -0
- package/src/definitions/actions/captions.ts +261 -0
- package/src/definitions/actions/edit.ts +298 -0
- package/src/definitions/actions/image.ts +125 -0
- package/src/definitions/actions/index.ts +114 -0
- package/src/definitions/actions/music.ts +205 -0
- package/src/definitions/actions/sync.ts +128 -0
- package/{action/transcribe/index.ts → src/definitions/actions/transcribe.ts} +58 -68
- package/src/definitions/actions/upload.ts +111 -0
- package/src/definitions/actions/video.ts +163 -0
- package/src/definitions/actions/voice.ts +119 -0
- package/src/definitions/index.ts +23 -0
- package/src/definitions/models/elevenlabs.ts +50 -0
- package/src/definitions/models/flux.ts +56 -0
- package/src/definitions/models/index.ts +36 -0
- package/src/definitions/models/kling.ts +56 -0
- package/src/definitions/models/llama.ts +54 -0
- package/src/definitions/models/nano-banana-pro.ts +102 -0
- package/src/definitions/models/sonauto.ts +68 -0
- package/src/definitions/models/soul.ts +65 -0
- package/src/definitions/models/wan.ts +54 -0
- package/src/definitions/models/whisper.ts +44 -0
- package/src/definitions/skills/index.ts +12 -0
- package/src/definitions/skills/talking-character.ts +87 -0
- package/src/definitions/skills/text-to-tiktok.ts +97 -0
- package/src/index.ts +118 -0
- package/src/providers/apify.ts +269 -0
- package/src/providers/base.ts +264 -0
- package/src/providers/elevenlabs.ts +217 -0
- package/src/providers/fal.ts +392 -0
- package/src/providers/ffmpeg.ts +544 -0
- package/src/providers/fireworks.ts +193 -0
- package/src/providers/groq.ts +149 -0
- package/src/providers/higgsfield.ts +145 -0
- package/src/providers/index.ts +143 -0
- package/src/providers/replicate.ts +147 -0
- package/src/providers/storage.ts +206 -0
- package/src/react/cli.ts +52 -0
- package/src/react/elements.ts +146 -0
- package/src/react/examples/branching.tsx +66 -0
- package/src/react/examples/captions-demo.tsx +37 -0
- package/src/react/examples/character-video.tsx +84 -0
- package/src/react/examples/grid.tsx +53 -0
- package/src/react/examples/layouts-demo.tsx +57 -0
- package/src/react/examples/madi.tsx +60 -0
- package/src/react/examples/music-test.tsx +35 -0
- package/src/react/examples/onlyfans-1m/workflow.tsx +88 -0
- package/src/react/examples/orange-portrait.tsx +41 -0
- package/src/react/examples/split-element-demo.tsx +60 -0
- package/src/react/examples/split-layout-demo.tsx +60 -0
- package/src/react/examples/split.tsx +41 -0
- package/src/react/examples/video-grid.tsx +46 -0
- package/src/react/index.ts +43 -0
- package/src/react/layouts/grid.tsx +28 -0
- package/src/react/layouts/index.ts +2 -0
- package/src/react/layouts/split.tsx +20 -0
- package/src/react/react.test.ts +309 -0
- package/src/react/render.ts +21 -0
- package/src/react/renderers/animate.ts +59 -0
- package/src/react/renderers/captions.ts +297 -0
- package/src/react/renderers/clip.ts +248 -0
- package/src/react/renderers/context.ts +17 -0
- package/src/react/renderers/image.ts +109 -0
- package/src/react/renderers/index.ts +22 -0
- package/src/react/renderers/music.ts +60 -0
- package/src/react/renderers/packshot.ts +84 -0
- package/src/react/renderers/progress.ts +173 -0
- package/src/react/renderers/render.ts +243 -0
- package/src/react/renderers/slider.ts +69 -0
- package/src/react/renderers/speech.ts +53 -0
- package/src/react/renderers/split.ts +91 -0
- package/src/react/renderers/subtitle.ts +16 -0
- package/src/react/renderers/swipe.ts +75 -0
- package/src/react/renderers/title.ts +17 -0
- package/src/react/renderers/utils.ts +124 -0
- package/src/react/renderers/video.ts +127 -0
- package/src/react/runtime/jsx-dev-runtime.ts +43 -0
- package/src/react/runtime/jsx-runtime.ts +35 -0
- package/src/react/types.ts +232 -0
- package/src/studio/index.ts +26 -0
- package/src/studio/scanner.ts +102 -0
- package/src/studio/server.ts +554 -0
- package/src/studio/stages.ts +251 -0
- package/src/studio/step-renderer.ts +279 -0
- package/src/studio/types.ts +60 -0
- package/src/studio/ui/cache.html +303 -0
- package/src/studio/ui/index.html +1820 -0
- package/src/tests/all.test.ts +509 -0
- package/src/tests/index.ts +33 -0
- package/src/tests/unit.test.ts +403 -0
- package/tsconfig.cli.json +8 -0
- package/tsconfig.json +21 -3
- package/TEST_RESULTS.md +0 -122
- package/action/captions/SKILL.md +0 -170
- package/action/captions/index.ts +0 -169
- package/action/edit/SKILL.md +0 -235
- package/action/edit/index.ts +0 -437
- package/action/image/SKILL.md +0 -140
- package/action/image/index.ts +0 -105
- package/action/sync/SKILL.md +0 -136
- package/action/sync/index.ts +0 -145
- package/action/transcribe/SKILL.md +0 -179
- package/action/video/SKILL.md +0 -116
- package/action/video/index.ts +0 -125
- package/action/voice/SKILL.md +0 -125
- package/action/voice/index.ts +0 -136
- package/cli/commands/find.ts +0 -58
- package/cli/commands/help.ts +0 -70
- package/cli/commands/list.ts +0 -49
- package/cli/commands/run.ts +0 -237
- package/cli/commands/which.ts +0 -66
- package/cli/discover.ts +0 -66
- package/cli/index.ts +0 -33
- package/cli/runner.ts +0 -65
- package/cli/types.ts +0 -49
- package/cli/ui.ts +0 -185
- package/index.ts +0 -75
- package/lib/README.md +0 -144
- package/lib/ai-sdk/fal.ts +0 -106
- package/lib/ai-sdk/replicate.ts +0 -107
- package/lib/elevenlabs.ts +0 -382
- package/lib/fal.ts +0 -467
- package/lib/ffmpeg.ts +0 -467
- package/lib/fireworks.ts +0 -235
- package/lib/groq.ts +0 -246
- package/lib/higgsfield.ts +0 -176
- package/lib/remotion/SKILL.md +0 -823
- package/lib/remotion/cli.ts +0 -115
- package/lib/remotion/functions.ts +0 -283
- package/lib/remotion/index.ts +0 -19
- package/lib/remotion/templates.ts +0 -73
- package/lib/replicate.ts +0 -304
- package/output.txt +0 -1
- package/test-import.ts +0 -7
- package/test-services.ts +0 -97
- package/utilities/s3.ts +0 -147
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* varg which command
|
|
3
|
+
* Ink-based inspection view
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { defineCommand } from "citty";
|
|
7
|
+
import { Box, Text } from "ink";
|
|
8
|
+
import { resolve } from "../../core/registry/resolver.ts";
|
|
9
|
+
import { getCliSchemaInfo, toJsonSchema } from "../../core/schema/helpers.ts";
|
|
10
|
+
import type {
|
|
11
|
+
ActionDefinition,
|
|
12
|
+
Definition,
|
|
13
|
+
ModelDefinition,
|
|
14
|
+
SkillDefinition,
|
|
15
|
+
} from "../../core/schema/types.ts";
|
|
16
|
+
import {
|
|
17
|
+
Badge,
|
|
18
|
+
Header,
|
|
19
|
+
OptionRow,
|
|
20
|
+
Separator,
|
|
21
|
+
VargBox,
|
|
22
|
+
VargText,
|
|
23
|
+
} from "../ui/index.ts";
|
|
24
|
+
import { renderStatic } from "../ui/render.ts";
|
|
25
|
+
import { theme } from "../ui/theme.ts";
|
|
26
|
+
|
|
27
|
+
interface WhichViewProps {
|
|
28
|
+
item: Definition;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function InputSchemaView({ schema }: { schema: unknown }) {
|
|
32
|
+
// biome-ignore lint/suspicious/noExplicitAny: Zod v4 type compatibility
|
|
33
|
+
const { properties, required } = getCliSchemaInfo(schema as any);
|
|
34
|
+
return (
|
|
35
|
+
<>
|
|
36
|
+
<Header>INPUT SCHEMA</Header>
|
|
37
|
+
<Box flexDirection="column" paddingLeft={2} marginBottom={1}>
|
|
38
|
+
{Object.entries(properties).map(([key, prop]) => (
|
|
39
|
+
<OptionRow
|
|
40
|
+
key={key}
|
|
41
|
+
name={key}
|
|
42
|
+
description={prop.description}
|
|
43
|
+
required={required.includes(key)}
|
|
44
|
+
defaultValue={prop.default}
|
|
45
|
+
enumValues={prop.enum}
|
|
46
|
+
type={prop.type}
|
|
47
|
+
/>
|
|
48
|
+
))}
|
|
49
|
+
</Box>
|
|
50
|
+
</>
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function OutputSchemaView({ schema }: { schema: unknown }) {
|
|
55
|
+
// biome-ignore lint/suspicious/noExplicitAny: Zod v4 type compatibility
|
|
56
|
+
const jsonSchema = toJsonSchema(schema as any);
|
|
57
|
+
return (
|
|
58
|
+
<>
|
|
59
|
+
<Header>OUTPUT</Header>
|
|
60
|
+
<Box paddingLeft={2} marginBottom={1}>
|
|
61
|
+
<Text>{jsonSchema.description || "Output result"}</Text>
|
|
62
|
+
</Box>
|
|
63
|
+
</>
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function WhichView({ item }: WhichViewProps) {
|
|
68
|
+
return (
|
|
69
|
+
<VargBox title={item.name}>
|
|
70
|
+
<Box marginBottom={1}>
|
|
71
|
+
<Text>{item.description}</Text>
|
|
72
|
+
</Box>
|
|
73
|
+
|
|
74
|
+
<Header>TYPE</Header>
|
|
75
|
+
<Box paddingLeft={2} marginBottom={1}>
|
|
76
|
+
<Badge type={item.type} />
|
|
77
|
+
</Box>
|
|
78
|
+
|
|
79
|
+
{/* Providers for models */}
|
|
80
|
+
{item.type === "model" && (
|
|
81
|
+
<>
|
|
82
|
+
<Header>PROVIDERS</Header>
|
|
83
|
+
<Box flexDirection="column" paddingLeft={2} marginBottom={1}>
|
|
84
|
+
<Text>{(item as ModelDefinition).providers.join(", ")}</Text>
|
|
85
|
+
<Text dimColor>
|
|
86
|
+
default: {(item as ModelDefinition).defaultProvider}
|
|
87
|
+
</Text>
|
|
88
|
+
</Box>
|
|
89
|
+
</>
|
|
90
|
+
)}
|
|
91
|
+
|
|
92
|
+
{/* Routes for actions */}
|
|
93
|
+
{item.type === "action" &&
|
|
94
|
+
(item as ActionDefinition).routes.length > 0 && (
|
|
95
|
+
<>
|
|
96
|
+
<Header>ROUTES</Header>
|
|
97
|
+
<Box flexDirection="column" paddingLeft={2} marginBottom={1}>
|
|
98
|
+
{(item as ActionDefinition).routes.map((route) => (
|
|
99
|
+
<Box key={route.target}>
|
|
100
|
+
<Text>
|
|
101
|
+
{"\u2192"} {route.target}
|
|
102
|
+
</Text>
|
|
103
|
+
{route.when && (
|
|
104
|
+
<Text dimColor> when {JSON.stringify(route.when)}</Text>
|
|
105
|
+
)}
|
|
106
|
+
</Box>
|
|
107
|
+
))}
|
|
108
|
+
</Box>
|
|
109
|
+
</>
|
|
110
|
+
)}
|
|
111
|
+
|
|
112
|
+
{/* Steps for skills */}
|
|
113
|
+
{item.type === "skill" && (
|
|
114
|
+
<>
|
|
115
|
+
<Header>STEPS</Header>
|
|
116
|
+
<Box flexDirection="column" paddingLeft={2} marginBottom={1}>
|
|
117
|
+
{(item as SkillDefinition).steps.map((step, index) => (
|
|
118
|
+
<Box key={step.name}>
|
|
119
|
+
<Text>
|
|
120
|
+
{index + 1}. {step.name} {"\u2192"} {step.run}
|
|
121
|
+
</Text>
|
|
122
|
+
</Box>
|
|
123
|
+
))}
|
|
124
|
+
</Box>
|
|
125
|
+
</>
|
|
126
|
+
)}
|
|
127
|
+
|
|
128
|
+
{/* Input schema */}
|
|
129
|
+
<InputSchemaView schema={item.schema.input} />
|
|
130
|
+
|
|
131
|
+
{/* Output */}
|
|
132
|
+
<OutputSchemaView schema={item.schema.output} />
|
|
133
|
+
|
|
134
|
+
<Separator />
|
|
135
|
+
<Box marginTop={1}>
|
|
136
|
+
<Text dimColor>run with </Text>
|
|
137
|
+
<Text color={theme.colors.accent}>varg run {item.name} [options]</Text>
|
|
138
|
+
</Box>
|
|
139
|
+
</VargBox>
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function NotFoundView({
|
|
144
|
+
name,
|
|
145
|
+
suggestions,
|
|
146
|
+
}: {
|
|
147
|
+
name: string;
|
|
148
|
+
suggestions?: string[];
|
|
149
|
+
}) {
|
|
150
|
+
return (
|
|
151
|
+
<Box flexDirection="column" padding={1}>
|
|
152
|
+
<VargText variant="error">not found: '{name}'</VargText>
|
|
153
|
+
{suggestions && suggestions.length > 0 && (
|
|
154
|
+
<Box marginTop={1}>
|
|
155
|
+
<Text>did you mean: {suggestions.slice(0, 3).join(", ")}?</Text>
|
|
156
|
+
</Box>
|
|
157
|
+
)}
|
|
158
|
+
</Box>
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/** Help view for which command */
|
|
163
|
+
function WhichHelpView() {
|
|
164
|
+
return (
|
|
165
|
+
<VargBox title="varg which">
|
|
166
|
+
<Box marginBottom={1}>
|
|
167
|
+
<Text>inspect a model, action, or skill</Text>
|
|
168
|
+
</Box>
|
|
169
|
+
|
|
170
|
+
<Header>USAGE</Header>
|
|
171
|
+
<Box paddingLeft={2} marginBottom={1}>
|
|
172
|
+
<VargText variant="accent">varg which {"<name>"} [--json]</VargText>
|
|
173
|
+
</Box>
|
|
174
|
+
|
|
175
|
+
<Header>ARGUMENTS</Header>
|
|
176
|
+
<Box flexDirection="column" paddingLeft={2} marginBottom={1}>
|
|
177
|
+
<Text>name name of item to inspect</Text>
|
|
178
|
+
</Box>
|
|
179
|
+
|
|
180
|
+
<Header>OPTIONS</Header>
|
|
181
|
+
<Box flexDirection="column" paddingLeft={2} marginBottom={1}>
|
|
182
|
+
<Text>--json output as json</Text>
|
|
183
|
+
</Box>
|
|
184
|
+
|
|
185
|
+
<Header>EXAMPLES</Header>
|
|
186
|
+
<Box flexDirection="column" paddingLeft={2}>
|
|
187
|
+
<Box flexDirection="column" marginBottom={1}>
|
|
188
|
+
<Text dimColor># inspect video action</Text>
|
|
189
|
+
<VargText variant="accent">varg which video</VargText>
|
|
190
|
+
</Box>
|
|
191
|
+
<Box flexDirection="column">
|
|
192
|
+
<Text dimColor># get json schema</Text>
|
|
193
|
+
<VargText variant="accent">varg which flux --json</VargText>
|
|
194
|
+
</Box>
|
|
195
|
+
</Box>
|
|
196
|
+
</VargBox>
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/** Show which command help */
|
|
201
|
+
export function showWhichHelp() {
|
|
202
|
+
renderStatic(<WhichHelpView />);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export const whichCmd = defineCommand({
|
|
206
|
+
meta: {
|
|
207
|
+
name: "which",
|
|
208
|
+
description: "inspect a model, action, or skill",
|
|
209
|
+
},
|
|
210
|
+
args: {
|
|
211
|
+
name: {
|
|
212
|
+
type: "positional",
|
|
213
|
+
description: "name to inspect",
|
|
214
|
+
required: false,
|
|
215
|
+
},
|
|
216
|
+
json: {
|
|
217
|
+
type: "boolean",
|
|
218
|
+
description: "output as json",
|
|
219
|
+
},
|
|
220
|
+
},
|
|
221
|
+
async run({ args, rawArgs }) {
|
|
222
|
+
// Handle --help
|
|
223
|
+
if (rawArgs.includes("--help") || rawArgs.includes("-h")) {
|
|
224
|
+
showWhichHelp();
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const name = args.name as string;
|
|
229
|
+
|
|
230
|
+
if (!name) {
|
|
231
|
+
showWhichHelp();
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
const result = resolve(name, { fuzzy: true });
|
|
236
|
+
|
|
237
|
+
if (!result.definition) {
|
|
238
|
+
renderStatic(
|
|
239
|
+
<NotFoundView name={name} suggestions={result.suggestions} />,
|
|
240
|
+
);
|
|
241
|
+
process.exit(1);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
const item = result.definition;
|
|
245
|
+
|
|
246
|
+
if (args.json) {
|
|
247
|
+
console.log(JSON.stringify(item, null, 2));
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
renderStatic(<WhichView item={item} />);
|
|
252
|
+
},
|
|
253
|
+
});
|
package/src/cli/index.ts
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* varg cli
|
|
5
|
+
* ai video infrastructure from your terminal
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// Must be first import to suppress logs before other modules load
|
|
9
|
+
import "./quiet";
|
|
10
|
+
|
|
11
|
+
import { defineCommand, runMain } from "citty";
|
|
12
|
+
import { registry } from "../core/registry";
|
|
13
|
+
import { allDefinitions } from "../definitions";
|
|
14
|
+
import {
|
|
15
|
+
findCmd,
|
|
16
|
+
helpCmd,
|
|
17
|
+
listCmd,
|
|
18
|
+
renderCmd,
|
|
19
|
+
runCmd,
|
|
20
|
+
showFindHelp,
|
|
21
|
+
showHelp,
|
|
22
|
+
showListHelp,
|
|
23
|
+
showRunHelp,
|
|
24
|
+
showTargetHelp,
|
|
25
|
+
showWhichHelp,
|
|
26
|
+
whichCmd,
|
|
27
|
+
} from "./commands";
|
|
28
|
+
|
|
29
|
+
// Register all providers
|
|
30
|
+
import "../providers"; // Side effect: registers providers to base registry
|
|
31
|
+
import { providers } from "../providers/base";
|
|
32
|
+
|
|
33
|
+
// Register all definitions
|
|
34
|
+
for (const definition of allDefinitions) {
|
|
35
|
+
registry.register(definition);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Also register providers to core registry
|
|
39
|
+
for (const provider of providers.all()) {
|
|
40
|
+
registry.registerProvider(provider);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Intercept --help and -h to use our custom help views
|
|
44
|
+
const args = process.argv.slice(2);
|
|
45
|
+
const hasHelp = args.includes("--help") || args.includes("-h");
|
|
46
|
+
|
|
47
|
+
// Map subcommands to their help functions
|
|
48
|
+
const subcommandHelp: Record<string, () => void> = {
|
|
49
|
+
run: showRunHelp,
|
|
50
|
+
list: showListHelp,
|
|
51
|
+
ls: showListHelp,
|
|
52
|
+
find: showFindHelp,
|
|
53
|
+
search: showFindHelp,
|
|
54
|
+
which: showWhichHelp,
|
|
55
|
+
inspect: showWhichHelp,
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
// Handle help for root or subcommands
|
|
59
|
+
if (args.length === 0 || args[0] === "help") {
|
|
60
|
+
showHelp();
|
|
61
|
+
process.exit(0);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (hasHelp) {
|
|
65
|
+
const subcommand = args[0];
|
|
66
|
+
// Root --help
|
|
67
|
+
if (subcommand === "--help" || subcommand === "-h") {
|
|
68
|
+
showHelp();
|
|
69
|
+
process.exit(0);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Handle subcommand help
|
|
73
|
+
if (subcommand && subcommand in subcommandHelp) {
|
|
74
|
+
const nonHelpArgs = args.filter((a) => a !== "--help" && a !== "-h");
|
|
75
|
+
|
|
76
|
+
// "varg run --help" - show run help
|
|
77
|
+
if (nonHelpArgs.length === 1) {
|
|
78
|
+
const helpFn = subcommandHelp[subcommand];
|
|
79
|
+
if (helpFn) {
|
|
80
|
+
helpFn();
|
|
81
|
+
process.exit(0);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// "varg run <target> --help" - show target-specific help
|
|
86
|
+
if (subcommand === "run" && nonHelpArgs.length === 2) {
|
|
87
|
+
const target = nonHelpArgs[1];
|
|
88
|
+
if (target && showTargetHelp(target)) {
|
|
89
|
+
process.exit(0);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const main = defineCommand({
|
|
96
|
+
meta: {
|
|
97
|
+
name: "varg",
|
|
98
|
+
version: "0.3.0",
|
|
99
|
+
description: "ai video infrastructure from your terminal",
|
|
100
|
+
},
|
|
101
|
+
subCommands: {
|
|
102
|
+
run: runCmd,
|
|
103
|
+
render: renderCmd,
|
|
104
|
+
list: listCmd,
|
|
105
|
+
ls: listCmd,
|
|
106
|
+
find: findCmd,
|
|
107
|
+
search: findCmd,
|
|
108
|
+
which: whichCmd,
|
|
109
|
+
inspect: whichCmd,
|
|
110
|
+
help: helpCmd,
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
runMain(main);
|
package/src/cli/quiet.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quiet mode setup - must be imported first
|
|
3
|
+
* Suppresses console.log for --json and --quiet modes
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const args = process.argv.slice(2);
|
|
7
|
+
export const isQuietMode = args.includes("--json") || args.includes("--quiet");
|
|
8
|
+
|
|
9
|
+
// Store original write function
|
|
10
|
+
const _originalWrite = process.stdout.write.bind(process.stdout);
|
|
11
|
+
|
|
12
|
+
if (isQuietMode) {
|
|
13
|
+
// Override process.stdout.write to filter non-JSON output
|
|
14
|
+
process.stdout.write = ((
|
|
15
|
+
// biome-ignore lint/suspicious/noExplicitAny: complex overload signature
|
|
16
|
+
chunk: any,
|
|
17
|
+
// biome-ignore lint/suspicious/noExplicitAny: complex overload signature
|
|
18
|
+
encoding?: any,
|
|
19
|
+
// biome-ignore lint/suspicious/noExplicitAny: complex overload signature
|
|
20
|
+
callback?: any,
|
|
21
|
+
): boolean => {
|
|
22
|
+
const str = typeof chunk === "string" ? chunk : chunk.toString();
|
|
23
|
+
const trimmed = str.trim();
|
|
24
|
+
|
|
25
|
+
// Only allow JSON output (starts with { or [) or empty lines
|
|
26
|
+
if (trimmed === "" || trimmed.startsWith("{") || trimmed.startsWith("[")) {
|
|
27
|
+
return _originalWrite(chunk, encoding, callback);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Suppress non-JSON output, still call callback if provided
|
|
31
|
+
if (typeof encoding === "function") {
|
|
32
|
+
encoding();
|
|
33
|
+
} else if (callback) {
|
|
34
|
+
callback();
|
|
35
|
+
}
|
|
36
|
+
return true;
|
|
37
|
+
}) as typeof process.stdout.write;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Export for direct output when needed (bypasses quiet mode)
|
|
41
|
+
export function rawLog(...args: unknown[]): void {
|
|
42
|
+
const message = `${args.map(String).join(" ")}\n`;
|
|
43
|
+
_originalWrite(message);
|
|
44
|
+
}
|
package/src/cli/types.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI type definitions
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export interface NotFoundOptions {
|
|
6
|
+
/** Suggested alternatives */
|
|
7
|
+
suggestions?: string[];
|
|
8
|
+
/** Max number of suggestions to show */
|
|
9
|
+
maxSuggestions?: number;
|
|
10
|
+
/** Custom hint message */
|
|
11
|
+
hint?: string;
|
|
12
|
+
/** Color function for error text */
|
|
13
|
+
errorColorFn?: (s: string) => string;
|
|
14
|
+
/** Color function for hints */
|
|
15
|
+
hintColorFn?: (s: string) => string;
|
|
16
|
+
/** Whether to exit process (default: true) */
|
|
17
|
+
exit?: boolean;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface JsonSchemaProperty {
|
|
21
|
+
type?: string;
|
|
22
|
+
description?: string;
|
|
23
|
+
default?: unknown;
|
|
24
|
+
enum?: string[];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface JsonSchema {
|
|
28
|
+
type?: string;
|
|
29
|
+
properties?: Record<string, JsonSchemaProperty>;
|
|
30
|
+
required?: string[];
|
|
31
|
+
description?: string;
|
|
32
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Badge - Type indicator badge
|
|
3
|
+
* Shows [model] [action] [skill] with appropriate styling
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { Text } from "ink";
|
|
7
|
+
import { theme } from "../theme.ts";
|
|
8
|
+
|
|
9
|
+
type BadgeType = "model" | "action" | "skill";
|
|
10
|
+
|
|
11
|
+
interface BadgeProps {
|
|
12
|
+
type: BadgeType;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const badgeColors: Record<BadgeType, string> = {
|
|
16
|
+
model: theme.colors.accent,
|
|
17
|
+
action: theme.colors.success,
|
|
18
|
+
skill: theme.colors.warning,
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export function Badge({ type }: BadgeProps) {
|
|
22
|
+
return (
|
|
23
|
+
<Text color={badgeColors[type]} dimColor>
|
|
24
|
+
[{type}]
|
|
25
|
+
</Text>
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export default Badge;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DataTable - Table display component
|
|
3
|
+
* Clean text-based table for listing items
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { Box, Text } from "ink";
|
|
7
|
+
import { Badge } from "./Badge.tsx";
|
|
8
|
+
import { VargText } from "./VargText.tsx";
|
|
9
|
+
|
|
10
|
+
interface TableRow {
|
|
11
|
+
name: string;
|
|
12
|
+
description: string;
|
|
13
|
+
type?: "model" | "action" | "skill";
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface DataTableProps {
|
|
17
|
+
rows: TableRow[];
|
|
18
|
+
showType?: boolean;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function DataTable({ rows, showType = false }: DataTableProps) {
|
|
22
|
+
if (rows.length === 0) {
|
|
23
|
+
return (
|
|
24
|
+
<Box paddingLeft={2}>
|
|
25
|
+
<VargText variant="muted">no items</VargText>
|
|
26
|
+
</Box>
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Calculate max name width for alignment
|
|
31
|
+
const maxNameWidth = Math.max(...rows.map((r) => r.name.length), 12);
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<Box flexDirection="column">
|
|
35
|
+
{rows.map((row) => (
|
|
36
|
+
<Box key={row.name} paddingLeft={2}>
|
|
37
|
+
{showType && row.type && (
|
|
38
|
+
<>
|
|
39
|
+
<Badge type={row.type} />
|
|
40
|
+
<Text> </Text>
|
|
41
|
+
</>
|
|
42
|
+
)}
|
|
43
|
+
<Text bold>{row.name.padEnd(maxNameWidth)}</Text>
|
|
44
|
+
<VargText variant="muted"> {row.description}</VargText>
|
|
45
|
+
</Box>
|
|
46
|
+
))}
|
|
47
|
+
</Box>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export default DataTable;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Header - Section header component
|
|
3
|
+
* Bold dimmed text for section titles
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { Box, Text } from "ink";
|
|
7
|
+
import type { ReactNode } from "react";
|
|
8
|
+
|
|
9
|
+
interface HeaderProps {
|
|
10
|
+
children: ReactNode;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function Header({ children }: HeaderProps) {
|
|
14
|
+
return (
|
|
15
|
+
<Box>
|
|
16
|
+
<Text bold dimColor>
|
|
17
|
+
{children}
|
|
18
|
+
</Text>
|
|
19
|
+
</Box>
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export default Header;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HelpBlock - Command help and examples
|
|
3
|
+
* Displays usage patterns and command examples
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { Box, Text } from "ink";
|
|
7
|
+
import { VargText } from "./VargText.tsx";
|
|
8
|
+
|
|
9
|
+
interface HelpBlockProps {
|
|
10
|
+
usage?: string;
|
|
11
|
+
examples?: Array<{ command: string; description?: string }>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function HelpBlock({ usage, examples }: HelpBlockProps) {
|
|
15
|
+
return (
|
|
16
|
+
<Box flexDirection="column">
|
|
17
|
+
{usage && (
|
|
18
|
+
<Box marginBottom={1}>
|
|
19
|
+
<VargText variant="muted">usage: </VargText>
|
|
20
|
+
<VargText variant="accent">{usage}</VargText>
|
|
21
|
+
</Box>
|
|
22
|
+
)}
|
|
23
|
+
|
|
24
|
+
{examples && examples.length > 0 && (
|
|
25
|
+
<Box flexDirection="column">
|
|
26
|
+
{examples.map((ex) => (
|
|
27
|
+
<Box key={ex.command} flexDirection="column" marginBottom={1}>
|
|
28
|
+
{ex.description && (
|
|
29
|
+
<Box paddingLeft={2}>
|
|
30
|
+
<Text dimColor># {ex.description}</Text>
|
|
31
|
+
</Box>
|
|
32
|
+
)}
|
|
33
|
+
<Box paddingLeft={2}>
|
|
34
|
+
<VargText variant="accent">{ex.command}</VargText>
|
|
35
|
+
</Box>
|
|
36
|
+
</Box>
|
|
37
|
+
))}
|
|
38
|
+
</Box>
|
|
39
|
+
)}
|
|
40
|
+
</Box>
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export default HelpBlock;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KeyValue - Label-value pair display
|
|
3
|
+
* Aligned key-value pairs with optional required marker
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { Box, Text } from "ink";
|
|
7
|
+
import { theme } from "../theme.ts";
|
|
8
|
+
|
|
9
|
+
interface KeyValueProps {
|
|
10
|
+
label: string;
|
|
11
|
+
value: string;
|
|
12
|
+
labelWidth?: number;
|
|
13
|
+
required?: boolean;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function KeyValue({
|
|
17
|
+
label,
|
|
18
|
+
value,
|
|
19
|
+
labelWidth = theme.layout.optionNameWidth,
|
|
20
|
+
required = false,
|
|
21
|
+
}: KeyValueProps) {
|
|
22
|
+
const paddedLabel = label.padEnd(labelWidth);
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<Box>
|
|
26
|
+
<Text dimColor>{paddedLabel}</Text>
|
|
27
|
+
{required && <Text color={theme.colors.warning}>* </Text>}
|
|
28
|
+
<Text>{value}</Text>
|
|
29
|
+
</Box>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export default KeyValue;
|