@mevdragon/vidfarm-devcli 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +11 -4
- package/PLATFORM_SPEC.md +142 -2
- package/README.md +165 -16
- package/SKILL.developer.md +577 -0
- package/dist/infra/cdk/bin/vidfarm-prod.js +59 -0
- package/dist/infra/cdk/lib/vidfarm-prod-stack.js +212 -0
- package/dist/src/account-pages.js +578 -0
- package/dist/src/app.js +887 -66
- package/dist/src/cli.js +284 -5
- package/dist/src/config.js +24 -4
- package/dist/src/db.js +427 -18
- package/dist/src/dev-app.js +59 -12
- package/dist/src/homepage.js +441 -0
- package/dist/src/index.js +12 -7
- package/dist/src/lib/crypto.js +14 -0
- package/dist/src/lib/template-dna.js +542 -0
- package/dist/src/lib/template-style-options.js +49 -0
- package/dist/src/registry.js +54 -7
- package/dist/src/runtime.js +3 -1
- package/dist/src/services/auth.js +69 -5
- package/dist/src/services/jobs.js +23 -4
- package/dist/src/services/providers.js +74 -12
- package/dist/src/services/storage.js +52 -18
- package/dist/src/services/template-certification.js +160 -0
- package/dist/src/services/template-loader.js +37 -0
- package/dist/src/services/template-sources.js +135 -0
- package/dist/src/worker.js +19 -7
- package/dist/templates/template_0000/src/lib/images.js +242 -0
- package/dist/templates/template_0000/src/remotion/Root.js +33 -0
- package/dist/templates/template_0000/src/sdk.js +3 -0
- package/dist/templates/template_0000/src/style-options.js +51 -0
- package/dist/templates/template_0000/src/template-dna.js +9 -0
- package/dist/templates/template_0000/src/template.js +1217 -0
- package/package.json +9 -1
- package/templates/template_0000/README.md +121 -0
- package/templates/template_0000/SKILL.md +193 -0
- package/templates/template_0000/assets/Abel-Regular.ttf +0 -0
- package/templates/template_0000/assets/DMSerifDisplay-Regular.ttf +0 -0
- package/templates/template_0000/assets/Montserrat[wght].ttf +0 -0
- package/templates/template_0000/assets/SourceCodePro[wght].ttf +0 -0
- package/templates/template_0000/assets/TikTokSans-SemiBold.ttf +0 -0
- package/templates/template_0000/assets/Yesteryear-Regular.ttf +0 -0
- package/templates/template_0000/composition.json +11 -0
- package/templates/template_0000/package-lock.json +5137 -0
- package/templates/template_0000/package.json +30 -0
- package/templates/template_0000/research/preview/.gitkeep +1 -0
- package/templates/template_0000/research/source_notes.md +7 -0
- package/templates/template_0000/scripts/create-site.mjs +27 -0
- package/templates/template_0000/scripts/render-cloud.mjs +72 -0
- package/templates/template_0000/src/lib/images.ts +284 -0
- package/templates/template_0000/src/remotion/Root.js +33 -0
- package/templates/template_0000/src/remotion/Root.tsx +75 -0
- package/templates/template_0000/src/remotion/index.tsx +4 -0
- package/templates/template_0000/src/sdk.ts +122 -0
- package/templates/template_0000/src/style-options.js +51 -0
- package/templates/template_0000/src/style-options.ts +60 -0
- package/templates/template_0000/src/template-dna.ts +15 -0
- package/templates/template_0000/src/template.ts +1747 -0
- package/templates/template_0000/template.config.json +26 -0
- package/templates/template_0000/tsconfig.json +19 -0
- package/dist/templates/template_0000/demo-template.js +0 -196
- package/dist/templates/template_0000/remotion/Root.js +0 -66
- /package/dist/templates/template_0000/{remotion → src/remotion}/index.js +0 -0
|
@@ -0,0 +1,577 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: vidfarm-developer
|
|
3
|
+
description: Build and extend Vidfarm video-production templates and platform features in this repository. Use this whenever the user wants to create a new Vidfarm template, add a pipeline stage or operation, wire billing or provider calls, integrate Remotion, extend the developer console, or modify the async jobs/auth/storage/webhook flow for Vidfarm.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Vidfarm Developer
|
|
7
|
+
|
|
8
|
+
This skill is for working inside the Vidfarm platform in this repository.
|
|
9
|
+
|
|
10
|
+
## Distribution Notes
|
|
11
|
+
|
|
12
|
+
Current published/distribution targets:
|
|
13
|
+
|
|
14
|
+
- npm package: `@mevdragon/vidfarm-devcli` as a private package
|
|
15
|
+
- GitHub repo: `OfficeXApp/vidfarm-devcli` as a private repo
|
|
16
|
+
|
|
17
|
+
Keep that split in mind when changing package metadata or release instructions. The npm package is intentionally user-scoped right now because private publish succeeded there, while the GitHub repo lives under the OfficeX org.
|
|
18
|
+
|
|
19
|
+
Use it when the task is any of:
|
|
20
|
+
|
|
21
|
+
- add a new internal video template
|
|
22
|
+
- extend an existing template with new operations or workflows
|
|
23
|
+
- wire AI generation through customer-owned provider keys
|
|
24
|
+
- add billing, artifacts, workspace, or webhook behavior
|
|
25
|
+
- integrate Remotion render steps
|
|
26
|
+
- modify the developer console at `/dev`
|
|
27
|
+
- change the Docker/AWS-hosted platform runtime
|
|
28
|
+
|
|
29
|
+
The current runtime is a single Node.js service with:
|
|
30
|
+
|
|
31
|
+
- Hono API
|
|
32
|
+
- SQLite job and lease state
|
|
33
|
+
- in-process worker loop
|
|
34
|
+
- local or S3-backed artifact storage
|
|
35
|
+
- async-first job model
|
|
36
|
+
|
|
37
|
+
The current release model also supports:
|
|
38
|
+
|
|
39
|
+
- GitHub-backed template source records
|
|
40
|
+
- admin-only import from the `production` branch
|
|
41
|
+
- admin-only Remotion site publish to shared AWS
|
|
42
|
+
- admin-only production Docker promotion
|
|
43
|
+
- pinned commit-SHA releases
|
|
44
|
+
- mandatory certification before activation
|
|
45
|
+
|
|
46
|
+
Start from the current implementation, not just the original spec.
|
|
47
|
+
|
|
48
|
+
## First Read
|
|
49
|
+
|
|
50
|
+
Read these files first before changing behavior:
|
|
51
|
+
|
|
52
|
+
1. [PLATFORM_SPEC.md](/Users/localghost/Projects/OfficeX/OfficeX/ZoomGTM/vidfarm/PLATFORM_SPEC.md)
|
|
53
|
+
2. [video-pipeline-architecture-draft.md](/Users/localghost/Projects/OfficeX/OfficeX/ZoomGTM/vidfarm/video-pipeline-architecture-draft.md)
|
|
54
|
+
3. [AWS_REMOTION_HANDOFF.md](/Users/localghost/Projects/OfficeX/OfficeX/ZoomGTM/vidfarm/AWS_REMOTION_HANDOFF.md) if the task touches Remotion or cloud render setup
|
|
55
|
+
4. [src/app.ts](/Users/localghost/Projects/OfficeX/OfficeX/ZoomGTM/vidfarm/src/app.ts)
|
|
56
|
+
5. [src/db.ts](/Users/localghost/Projects/OfficeX/OfficeX/ZoomGTM/vidfarm/src/db.ts)
|
|
57
|
+
6. [src/worker.ts](/Users/localghost/Projects/OfficeX/OfficeX/ZoomGTM/vidfarm/src/worker.ts)
|
|
58
|
+
7. [src/template-sdk.ts](/Users/localghost/Projects/OfficeX/OfficeX/ZoomGTM/vidfarm/src/template-sdk.ts)
|
|
59
|
+
8. [templates/template_0000/src/template.ts](/Users/localghost/Projects/OfficeX/OfficeX/ZoomGTM/vidfarm/templates/template_0000/src/template.ts)
|
|
60
|
+
9. [src/dev-app.ts](/Users/localghost/Projects/OfficeX/OfficeX/ZoomGTM/vidfarm/src/dev-app.ts)
|
|
61
|
+
10. [src/cli.ts](/Users/localghost/Projects/OfficeX/OfficeX/ZoomGTM/vidfarm/src/cli.ts) if the task touches local template developer workflow
|
|
62
|
+
|
|
63
|
+
If the task is narrow, only read the relevant slice after this initial pass.
|
|
64
|
+
|
|
65
|
+
## Platform Shape
|
|
66
|
+
|
|
67
|
+
Treat Vidfarm as one shared control-plane service.
|
|
68
|
+
|
|
69
|
+
- API routes live in `src/app.ts`
|
|
70
|
+
- database schema and persistence helpers live in `src/db.ts`
|
|
71
|
+
- background execution lives in `src/worker.ts`
|
|
72
|
+
- template execution context is built in `src/context.ts`
|
|
73
|
+
- provider leasing and outbound AI routing live in `src/services/providers.ts`
|
|
74
|
+
- storage lives in `src/services/storage.ts`
|
|
75
|
+
- jobs live in `src/services/jobs.ts`
|
|
76
|
+
- webhooks live in `src/services/webhooks.ts`
|
|
77
|
+
- Remotion integration seam lives in `src/services/remotion.ts`
|
|
78
|
+
- templates are registered in `src/registry.ts`
|
|
79
|
+
- template implementation code lives in `templates/*`, not `src/*`
|
|
80
|
+
|
|
81
|
+
Do not split a new template into its own HTTP service unless the user explicitly wants that. The default Vidfarm pattern is internal code modules loaded by the shared platform.
|
|
82
|
+
|
|
83
|
+
## Core Mental Model
|
|
84
|
+
|
|
85
|
+
Every public template action is async and returns a `job_id`.
|
|
86
|
+
|
|
87
|
+
The normal request flow is:
|
|
88
|
+
|
|
89
|
+
1. client calls `POST /templates/:templateId/operations/:operationName`
|
|
90
|
+
2. platform authenticates with `vidfarm-user-id` and `vidfarm-api-key`
|
|
91
|
+
3. platform validates payload against the template operation schema
|
|
92
|
+
4. platform creates a queued job in SQLite
|
|
93
|
+
5. worker picks up the job
|
|
94
|
+
6. workflow emits logs, artifacts, billing events, and optional webhook deliveries
|
|
95
|
+
7. client polls `GET /templates/:templateId/jobs/:jobId`
|
|
96
|
+
|
|
97
|
+
Do not implement new synchronous flows unless the user explicitly asks for it. Prefer consistency with the async job model.
|
|
98
|
+
|
|
99
|
+
## When Adding A New Template
|
|
100
|
+
|
|
101
|
+
Follow this checklist.
|
|
102
|
+
|
|
103
|
+
1. Create a new folder under `templates/template_<nnnn>/`
|
|
104
|
+
2. Put the template definition in that folder, not under `src/*`
|
|
105
|
+
3. Export `defineTemplate({...})`
|
|
106
|
+
4. Define:
|
|
107
|
+
- `id`
|
|
108
|
+
- `version`
|
|
109
|
+
- `about.description`
|
|
110
|
+
- `about.viral_dna`
|
|
111
|
+
- `about.visual_dna`
|
|
112
|
+
- `about.preview_media`
|
|
113
|
+
- `about.link_to_original`
|
|
114
|
+
- `skillPath`
|
|
115
|
+
- `configSchema`
|
|
116
|
+
- `operations`
|
|
117
|
+
- `jobs`
|
|
118
|
+
5. Add a template-local `SKILL.md`
|
|
119
|
+
6. Put original-format notes in `research/source_notes.md` and source screenshots/video in `research/preview/`
|
|
120
|
+
7. Run `vidfarm analyze-viral-dna --template-dir <template-dir>` and `vidfarm analyze-visual-dna --template-dir <template-dir>`
|
|
121
|
+
8. Add `smokeTestPayload` for every operation
|
|
122
|
+
9. Register the template in `src/registry.ts`
|
|
123
|
+
10. If useful, add default payload/config examples to `src/dev-app.ts`
|
|
124
|
+
11. Verify end to end with the local developer console and/or curl
|
|
125
|
+
|
|
126
|
+
Use the existing `template_0000` starter template as the baseline example.
|
|
127
|
+
|
|
128
|
+
The starter scaffold now standardizes template DNA authoring:
|
|
129
|
+
|
|
130
|
+
- `research/source_notes.md` is the source-format note file
|
|
131
|
+
- `research/preview/` holds the screenshots or video the analyzers inspect
|
|
132
|
+
- `src/template-dna.ts` is the checked-in generated module that feeds `about.viral_dna`, `about.visual_dna`, and `about.link_to_original`
|
|
133
|
+
- `vidfarm generate-template` stages those files automatically, and if preview media is already present it will run both DNA analyzers during scaffold creation
|
|
134
|
+
|
|
135
|
+
`template_0000` is intentionally opinionated and should be treated as the default starter pattern:
|
|
136
|
+
|
|
137
|
+
- operation 1: `create_slideshow`
|
|
138
|
+
- operation 2: `render_video`
|
|
139
|
+
- stage 1 outputs finished 9:16 slide images with the text already composited
|
|
140
|
+
- stage 2 only sequences those finished slide images into video
|
|
141
|
+
- reserve TikTok UI safe zones at the top, right edge, and bottom
|
|
142
|
+
- avoid subject cut-off during portrait normalization
|
|
143
|
+
- use checked-in TikTok Sans for starter caption typography
|
|
144
|
+
- prefer readable text with shadow/fade over caption boxes
|
|
145
|
+
- if a new template does not need video, it can stop after stage 1
|
|
146
|
+
|
|
147
|
+
Not every template uses Remotion. That is fine. Certification only expects Remotion behavior if the template actually calls `ctx.remotion`.
|
|
148
|
+
|
|
149
|
+
## Template Contract
|
|
150
|
+
|
|
151
|
+
Each template should expose operations, not ad hoc endpoints.
|
|
152
|
+
|
|
153
|
+
Use this shape:
|
|
154
|
+
|
|
155
|
+
```ts
|
|
156
|
+
export const myTemplate = defineTemplate({
|
|
157
|
+
id: "123e4567-e89b-42d3-a456-426614174000",
|
|
158
|
+
slugId: "ugc_hooks_v1",
|
|
159
|
+
version: "1.0.0",
|
|
160
|
+
about: {
|
|
161
|
+
title: "UGC Hooks V1",
|
|
162
|
+
description: "Generate hooks, previews, and final render inputs.",
|
|
163
|
+
viral_dna: "Fast creator-style hooks with simple repeatable structure.",
|
|
164
|
+
visual_dna: "Presentation-led mobile layouts with recognizable creator-native framing.",
|
|
165
|
+
preview_media: ["https://cdn.example.com/templates/ugc_hooks_v1/about/preview-01.jpg"],
|
|
166
|
+
link_to_original: "https://www.tiktok.com/@example/video/1234567890"
|
|
167
|
+
},
|
|
168
|
+
configSchema: z.object({
|
|
169
|
+
defaultProvider: z.enum(["openai", "openrouter", "gemini", "perplexity"]).default("openai")
|
|
170
|
+
}),
|
|
171
|
+
operations: {
|
|
172
|
+
scaffold: {
|
|
173
|
+
description: "Generate a script scaffold.",
|
|
174
|
+
inputSchema: z.object({
|
|
175
|
+
topic: z.string()
|
|
176
|
+
}),
|
|
177
|
+
workflow: "scaffoldWorkflow",
|
|
178
|
+
providerHint: "openai",
|
|
179
|
+
webhookSupport: true,
|
|
180
|
+
smokeTestPayload: {
|
|
181
|
+
topic: "creator hooks"
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
jobs: {
|
|
186
|
+
async scaffoldWorkflow(ctx, input) {
|
|
187
|
+
return {
|
|
188
|
+
progress: 1,
|
|
189
|
+
output: {}
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Keep the separation clear:
|
|
197
|
+
|
|
198
|
+
- `id` is the self-issued UUIDv4 `template_id`
|
|
199
|
+
- `slugId` is the human-readable stable `slug_id`
|
|
200
|
+
- `operations` define the public API surface
|
|
201
|
+
- `jobs` define internal execution workflows
|
|
202
|
+
- `smokeTestPayload` defines the minimum certification input
|
|
203
|
+
|
|
204
|
+
## GitHub Source Flow
|
|
205
|
+
|
|
206
|
+
For GitHub-backed template distribution, treat the platform as importing approved source code, not live-tracking a repo.
|
|
207
|
+
|
|
208
|
+
Rules:
|
|
209
|
+
|
|
210
|
+
- default source branch is `production`
|
|
211
|
+
- admin manually reviews the repo and decides when to import
|
|
212
|
+
- template authors do not publish directly to shared Remotion AWS
|
|
213
|
+
- template authors do not directly promote templates into production Docker
|
|
214
|
+
- import resolves to a pinned commit SHA
|
|
215
|
+
- certification runs before activation
|
|
216
|
+
- activation flips one certified release live
|
|
217
|
+
- Remotion site publish is part of admin release promotion, not template authoring
|
|
218
|
+
- production Docker rebuild/redeploy happens only after admin approval
|
|
219
|
+
|
|
220
|
+
Do not implement floating branch-head production state. Live template state must always be tied to a specific commit.
|
|
221
|
+
|
|
222
|
+
For the current demo standalone template repo, use:
|
|
223
|
+
|
|
224
|
+
- project/package name: `vidfarm_template_0000`
|
|
225
|
+
- GitHub repo target: `mevdragon/vidfarm_template_0000`
|
|
226
|
+
- checked-in production config file: `template.config.json`
|
|
227
|
+
- `slug_id`: `template_0000`
|
|
228
|
+
- sample `template_id`: `4c7a7e1a-7f35-4f30-9f86-9c8a63c7f2db`
|
|
229
|
+
|
|
230
|
+
When registering a template source with the platform:
|
|
231
|
+
|
|
232
|
+
- `template_id` must be a self-issued UUIDv4
|
|
233
|
+
- `slug_id` must be the human-readable stable identifier
|
|
234
|
+
- registration must fail if another source already uses the same `template_id`
|
|
235
|
+
- the conflict error should tell the developer to generate a different UUIDv4
|
|
236
|
+
|
|
237
|
+
Template repos should prefer checked-in config for production topology over scattered env vars. In particular:
|
|
238
|
+
|
|
239
|
+
- Remotion region/function/bucket/site/composition settings should live in `template.config.json`
|
|
240
|
+
- release control metadata should also live in `template.config.json`
|
|
241
|
+
- AI agents should read `template.config.json` as the source of truth
|
|
242
|
+
- only secrets and credentials should come from the execution environment
|
|
243
|
+
|
|
244
|
+
## Workflow Rules
|
|
245
|
+
|
|
246
|
+
Inside a template workflow:
|
|
247
|
+
|
|
248
|
+
- log meaningful progress
|
|
249
|
+
- store large outputs as artifacts
|
|
250
|
+
- record billing when you consume external or compute-heavy resources
|
|
251
|
+
- route provider calls through `ctx.providers`
|
|
252
|
+
- use `ctx.remotion` for render submission
|
|
253
|
+
- use `ctx.jobs.enqueueChild(...)` only when a child-job boundary is truly useful
|
|
254
|
+
|
|
255
|
+
Do not bypass framework-owned services with raw provider calls unless the user explicitly wants to break out of the shared routing and billing model.
|
|
256
|
+
|
|
257
|
+
## Provider Usage
|
|
258
|
+
|
|
259
|
+
For customer-billed AI calls, always go through:
|
|
260
|
+
|
|
261
|
+
```ts
|
|
262
|
+
await ctx.providers.generateText({
|
|
263
|
+
provider: "openai",
|
|
264
|
+
model: "gpt-4.1-mini",
|
|
265
|
+
prompt: "...",
|
|
266
|
+
temperature: 0.7
|
|
267
|
+
});
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
Why:
|
|
271
|
+
|
|
272
|
+
- it leases a compatible customer key
|
|
273
|
+
- it respects cooldown and invalidation behavior
|
|
274
|
+
- it records usage events
|
|
275
|
+
- it fits the retry model in the worker
|
|
276
|
+
|
|
277
|
+
Relevant files:
|
|
278
|
+
|
|
279
|
+
- [src/services/providers.ts](/Users/localghost/Projects/OfficeX/OfficeX/ZoomGTM/vidfarm/src/services/providers.ts)
|
|
280
|
+
- [src/db.ts](/Users/localghost/Projects/OfficeX/OfficeX/ZoomGTM/vidfarm/src/db.ts)
|
|
281
|
+
|
|
282
|
+
## Billing Rules
|
|
283
|
+
|
|
284
|
+
Templates should emit billable events through the framework context, not invent a separate ledger.
|
|
285
|
+
|
|
286
|
+
Use:
|
|
287
|
+
|
|
288
|
+
```ts
|
|
289
|
+
await ctx.billing.record({
|
|
290
|
+
type: "ai_generation",
|
|
291
|
+
costUsd: 0.02,
|
|
292
|
+
metadata: { provider: "openai" }
|
|
293
|
+
});
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
Current default behavior charges roughly `costUsd * 2` if `chargeUsd` is omitted.
|
|
297
|
+
|
|
298
|
+
If you add a new billable resource type, update both:
|
|
299
|
+
|
|
300
|
+
1. the domain types in `src/domain.ts`
|
|
301
|
+
2. any services or reporting code that assumes the existing event kinds
|
|
302
|
+
|
|
303
|
+
## Storage And Artifacts
|
|
304
|
+
|
|
305
|
+
Use `ctx.storage.putJson(...)` for structured intermediate outputs.
|
|
306
|
+
|
|
307
|
+
The current storage adapter supports:
|
|
308
|
+
|
|
309
|
+
- local disk for development
|
|
310
|
+
- S3-compatible object storage for hosted environments
|
|
311
|
+
|
|
312
|
+
Store large stage outputs as artifacts rather than only embedding them inside `job.result`.
|
|
313
|
+
Template-generated artifacts should be written under the logical prefix:
|
|
314
|
+
|
|
315
|
+
```txt
|
|
316
|
+
templates/:templateId/users/:userId/jobs/:jobId/...
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
Relevant files:
|
|
320
|
+
|
|
321
|
+
- [src/services/storage.ts](/Users/localghost/Projects/OfficeX/OfficeX/ZoomGTM/vidfarm/src/services/storage.ts)
|
|
322
|
+
- [src/context.ts](/Users/localghost/Projects/OfficeX/OfficeX/ZoomGTM/vidfarm/src/context.ts)
|
|
323
|
+
|
|
324
|
+
## Remotion Pattern
|
|
325
|
+
|
|
326
|
+
Remotion is treated as a downstream adapter, not the platform center.
|
|
327
|
+
|
|
328
|
+
Use:
|
|
329
|
+
|
|
330
|
+
```ts
|
|
331
|
+
const render = await ctx.remotion.render({
|
|
332
|
+
compositionId: "storyboard-main",
|
|
333
|
+
inputProps: {...}
|
|
334
|
+
});
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
If the user asks for real Lambda wiring, keep the template contract stable and upgrade `src/services/remotion.ts` rather than hardcoding provider-specific render logic directly into template files.
|
|
338
|
+
|
|
339
|
+
For real AWS-backed Remotion work in this repo:
|
|
340
|
+
|
|
341
|
+
- use [AWS_REMOTION_HANDOFF.md](/Users/localghost/Projects/OfficeX/OfficeX/ZoomGTM/vidfarm/AWS_REMOTION_HANDOFF.md) as source of truth
|
|
342
|
+
- target the shared `us-east-1` Remotion infra described there
|
|
343
|
+
- pin Remotion packages to `4.0.355` unless the task is explicitly shared-infra upgrade work
|
|
344
|
+
- publish a repo-specific site bundle instead of deploying a new render Lambda by default
|
|
345
|
+
- treat shared AWS site publish and cloud render validation as release-admin work, not normal developer authoring work
|
|
346
|
+
|
|
347
|
+
Important credential note:
|
|
348
|
+
|
|
349
|
+
- this repo has separate Remotion AWS credentials available in local production env config as `REMOTION_AWS_ACCESS_KEY_ID` and `REMOTION_AWS_SECRET_ACCESS_KEY`
|
|
350
|
+
- use those for Remotion site publish/render operations
|
|
351
|
+
- do not assume generic `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` are the correct identity for Remotion work
|
|
352
|
+
|
|
353
|
+
Preferred env/config values for real Remotion integration:
|
|
354
|
+
|
|
355
|
+
```env
|
|
356
|
+
REMOTION_REGION=us-east-1
|
|
357
|
+
REMOTION_FUNCTION_NAME=remotion-render-4-0-355-mem2048mb-disk2048mb-180sec
|
|
358
|
+
REMOTION_BUCKET_NAME=remotionlambda-useast1-ujg7c0h43q
|
|
359
|
+
REMOTION_SITE_NAME=your-site-name
|
|
360
|
+
REMOTION_SERVE_URL=https://remotionlambda-useast1-ujg7c0h43q.s3.us-east-1.amazonaws.com/sites/your-site-name/index.html
|
|
361
|
+
REMOTION_COMPOSITION_ID=YourComposition
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
If implementing real rendering, prefer one of these patterns:
|
|
365
|
+
|
|
366
|
+
1. publish a site bundle with the shared bucket and site-name pattern from the handoff
|
|
367
|
+
2. render against the shared function name and the repo-specific `REMOTION_SERVE_URL`
|
|
368
|
+
|
|
369
|
+
Do not deploy a new Lambda function for every template unless the task explicitly requires shared infra changes.
|
|
370
|
+
|
|
371
|
+
Release sequence for Remotion-backed templates:
|
|
372
|
+
|
|
373
|
+
1. developer merges approved code into the template repo `production` branch
|
|
374
|
+
2. release admin reviews and pins a commit SHA
|
|
375
|
+
3. release admin publishes the site bundle to shared AWS
|
|
376
|
+
4. release admin verifies a cloud render against that site
|
|
377
|
+
5. release admin activates the pinned template release in the platform
|
|
378
|
+
6. release admin rebuilds and redeploys the production Docker image
|
|
379
|
+
|
|
380
|
+
## API Rules
|
|
381
|
+
|
|
382
|
+
If you need new API surface area, prefer these patterns:
|
|
383
|
+
|
|
384
|
+
- customer-facing template actions under `/templates/:templateId/*`
|
|
385
|
+
- developer or customer profile actions under `/me/*`
|
|
386
|
+
- auth under `/auth/*`
|
|
387
|
+
- documentation or debug surfaces only when justified
|
|
388
|
+
|
|
389
|
+
Do not create a separate route per stage if an operation-based route can cover it cleanly. The platform already normalizes work through:
|
|
390
|
+
|
|
391
|
+
`POST /templates/:templateId/operations/:operationName`
|
|
392
|
+
|
|
393
|
+
## Database Rules
|
|
394
|
+
|
|
395
|
+
When changing persistence:
|
|
396
|
+
|
|
397
|
+
- update schema in `src/db.ts`
|
|
398
|
+
- add mapping helpers there too
|
|
399
|
+
- keep writes idempotent where possible
|
|
400
|
+
- preserve the worker’s retry safety
|
|
401
|
+
- avoid introducing a second state store unless the user explicitly wants it
|
|
402
|
+
|
|
403
|
+
For provider-key coordination, preserve the SQLite lease model unless the task is explicitly about moving to Postgres, Redis, or SQS.
|
|
404
|
+
|
|
405
|
+
## Developer Console
|
|
406
|
+
|
|
407
|
+
The browser console lives at `/dev`.
|
|
408
|
+
|
|
409
|
+
If you add a new template or operation, consider whether `src/dev-app.ts` should also gain:
|
|
410
|
+
|
|
411
|
+
- default config JSON
|
|
412
|
+
- default payload JSON
|
|
413
|
+
- extra developer affordances for that workflow
|
|
414
|
+
|
|
415
|
+
Keep the console practical. It is for internal developers to test the platform quickly, not for polished end-user UX.
|
|
416
|
+
|
|
417
|
+
## Local Runbook
|
|
418
|
+
|
|
419
|
+
Typical local run:
|
|
420
|
+
|
|
421
|
+
```bash
|
|
422
|
+
npm install
|
|
423
|
+
PORT=3100 ENCRYPTION_SECRET=test-secret API_KEY_SALT=test-salt MOCK_PROVIDER_RESPONSES=true npm run dev
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
Open:
|
|
427
|
+
|
|
428
|
+
```txt
|
|
429
|
+
http://127.0.0.1:3100/dev
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
Use mocked provider responses by default during local development unless the task specifically requires real provider traffic.
|
|
433
|
+
|
|
434
|
+
Preferred local template developer workflow:
|
|
435
|
+
|
|
436
|
+
```bash
|
|
437
|
+
npx @mevdragon/vidfarm-devcli dev --port 3310 --reset
|
|
438
|
+
npx @mevdragon/vidfarm-devcli session
|
|
439
|
+
npx @mevdragon/vidfarm-devcli validate-template --template-id template_0000
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
That CLI should be the default path for local template testing because it:
|
|
443
|
+
|
|
444
|
+
- boots the real REST API and worker
|
|
445
|
+
- provisions local SQLite automatically
|
|
446
|
+
- seeds a dev auth session
|
|
447
|
+
- seeds provider keys from local env vars when present
|
|
448
|
+
- falls back to mock provider keys plus mocked AI responses when needed
|
|
449
|
+
- renders Remotion locally
|
|
450
|
+
|
|
451
|
+
Reset local state when you need a clean test pass:
|
|
452
|
+
|
|
453
|
+
```bash
|
|
454
|
+
rm -rf .vidfarm/local
|
|
455
|
+
npx @mevdragon/vidfarm-devcli dev --port 3310 --reset
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
For slideshow-style templates, remember the artifact distinction:
|
|
459
|
+
|
|
460
|
+
- `slides/*.png` are background images only
|
|
461
|
+
- text overlay appears in `renders/final.mp4`
|
|
462
|
+
- if text seems missing, inspect the final MP4 before assuming generation failed
|
|
463
|
+
|
|
464
|
+
If the task requires real Remotion cloud rendering, confirm these before coding:
|
|
465
|
+
|
|
466
|
+
1. the repo is using the shared function and bucket from `AWS_REMOTION_HANDOFF.md`
|
|
467
|
+
2. the Remotion package version matches `4.0.355`
|
|
468
|
+
3. the runner is using `REMOTION_AWS_ACCESS_KEY_ID` and `REMOTION_AWS_SECRET_ACCESS_KEY`
|
|
469
|
+
4. the site name is repo-specific and not reusing another repo’s published bundle unintentionally
|
|
470
|
+
|
|
471
|
+
## Validation Checklist
|
|
472
|
+
|
|
473
|
+
After changes, validate with as many of these as apply:
|
|
474
|
+
|
|
475
|
+
1. `npm run check`
|
|
476
|
+
2. `npm run build`
|
|
477
|
+
3. `npx @mevdragon/vidfarm-devcli validate-template --template-id <templateIdOrSlug>`
|
|
478
|
+
4. hit `/health`
|
|
479
|
+
5. use `/dev`
|
|
480
|
+
6. request OTP and verify login
|
|
481
|
+
7. add a provider key
|
|
482
|
+
8. save template config
|
|
483
|
+
9. launch a job
|
|
484
|
+
10. poll job status and logs
|
|
485
|
+
11. inspect produced artifacts
|
|
486
|
+
|
|
487
|
+
If the task touches GitHub-backed template releases, also validate:
|
|
488
|
+
|
|
489
|
+
1. source branch is `production`
|
|
490
|
+
2. module path points to the built template export
|
|
491
|
+
3. `SKILL.md` path is correct
|
|
492
|
+
4. import creates a release pinned to a commit SHA
|
|
493
|
+
5. only certified releases are activatable
|
|
494
|
+
|
|
495
|
+
For new template scaffolds, use the CLI instead of copy-pasting the starter repo by hand:
|
|
496
|
+
|
|
497
|
+
```bash
|
|
498
|
+
npx @mevdragon/vidfarm-devcli generate-template --slug-id hooks_v1 --template-dir templates/template_0007
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
That command copies `templates/template_0000`, strips `.git` and `node_modules`, rewrites the starter placeholders for the new template, and generates a UUIDv4 `template_id` if you do not pass one explicitly.
|
|
502
|
+
|
|
503
|
+
The generated template repo is still authoring-only. It can contain admin release scripts and config, but only the release admin should run those scripts against shared AWS or production infrastructure.
|
|
504
|
+
|
|
505
|
+
If you changed worker behavior, do not stop at compile success. Run a real job.
|
|
506
|
+
|
|
507
|
+
If you changed Remotion integration, also validate:
|
|
508
|
+
|
|
509
|
+
1. site publish config
|
|
510
|
+
2. serve URL shape
|
|
511
|
+
3. function name
|
|
512
|
+
4. composition ID
|
|
513
|
+
5. render submission path
|
|
514
|
+
|
|
515
|
+
If you changed slideshow or text-overlay behavior, also validate:
|
|
516
|
+
|
|
517
|
+
1. the generated background slide images do not contain baked-in text unless explicitly intended
|
|
518
|
+
2. the final MP4 shows the overlay text in the expected zone
|
|
519
|
+
3. long captions wrap correctly and do not clip
|
|
520
|
+
4. the stored slide assets are the expected aspect ratio, especially for strict 9:16 templates
|
|
521
|
+
|
|
522
|
+
## Common Tasks
|
|
523
|
+
|
|
524
|
+
### Add a new operation to an existing template
|
|
525
|
+
|
|
526
|
+
1. update `operations` in the template file
|
|
527
|
+
2. add the workflow implementation under `jobs`
|
|
528
|
+
3. add sample payload defaults in `src/dev-app.ts` if useful
|
|
529
|
+
4. verify through `/dev`
|
|
530
|
+
|
|
531
|
+
### Add a new template-wide config field
|
|
532
|
+
|
|
533
|
+
1. extend `configSchema`
|
|
534
|
+
2. read it from `ctx.templateConfig`
|
|
535
|
+
3. test save/load through `/templates/:templateId/config`
|
|
536
|
+
|
|
537
|
+
### Add a new provider-aware generation step
|
|
538
|
+
|
|
539
|
+
1. call `ctx.providers.generateText(...)`
|
|
540
|
+
2. record billing
|
|
541
|
+
3. log progress and persist the artifact
|
|
542
|
+
|
|
543
|
+
### Add webhook behavior
|
|
544
|
+
|
|
545
|
+
1. prefer queueing delivery through the existing webhook service
|
|
546
|
+
2. do not send ad hoc `fetch()` calls directly from template code
|
|
547
|
+
|
|
548
|
+
### Register a GitHub-backed template source
|
|
549
|
+
|
|
550
|
+
1. create or update the template source record
|
|
551
|
+
2. use branch `production`
|
|
552
|
+
3. point `template_module_path` at the built module the platform should import
|
|
553
|
+
4. point `skill_path` at the template-local `SKILL.md`
|
|
554
|
+
5. import the source to create a pinned release
|
|
555
|
+
6. activate only after certification passes
|
|
556
|
+
|
|
557
|
+
## What To Avoid
|
|
558
|
+
|
|
559
|
+
- bypassing auth and job creation by adding custom one-off endpoints
|
|
560
|
+
- storing plaintext customer provider secrets
|
|
561
|
+
- making raw AI calls outside the provider lease system for customer workloads
|
|
562
|
+
- writing template-specific persistence logic outside `src/db.ts` without reason
|
|
563
|
+
- activating a template from a floating branch head instead of a pinned commit
|
|
564
|
+
- omitting `SKILL.md` or `smokeTestPayload`
|
|
565
|
+
- coupling the platform too tightly to one render engine
|
|
566
|
+
- returning giant generated outputs only inline when they should be artifacts
|
|
567
|
+
|
|
568
|
+
## Output Style For Vidfarm Work
|
|
569
|
+
|
|
570
|
+
When reporting back after Vidfarm changes:
|
|
571
|
+
|
|
572
|
+
- name the main platform area changed
|
|
573
|
+
- mention the template or route affected
|
|
574
|
+
- state how you verified it
|
|
575
|
+
- call out any remaining gap such as `Remotion path still mocked` or `real provider calls not exercised`
|
|
576
|
+
|
|
577
|
+
That keeps Vidfarm work easy to review and safe to iterate on.
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { App } from "aws-cdk-lib";
|
|
3
|
+
import { VidfarmProdStack } from "../lib/vidfarm-prod-stack.js";
|
|
4
|
+
function required(name) {
|
|
5
|
+
const value = process.env[name]?.trim();
|
|
6
|
+
if (!value) {
|
|
7
|
+
throw new Error(`Missing required environment variable: ${name}`);
|
|
8
|
+
}
|
|
9
|
+
return value;
|
|
10
|
+
}
|
|
11
|
+
function optional(name) {
|
|
12
|
+
const value = process.env[name]?.trim();
|
|
13
|
+
return value ? value : undefined;
|
|
14
|
+
}
|
|
15
|
+
const account = optional("CDK_DEFAULT_ACCOUNT") ?? optional("AWS_ACCOUNT_ID");
|
|
16
|
+
const region = optional("CDK_DEFAULT_REGION") ?? optional("AWS_REGION") ?? "us-east-1";
|
|
17
|
+
if (!account) {
|
|
18
|
+
throw new Error("Set CDK_DEFAULT_ACCOUNT or AWS_ACCOUNT_ID before running CDK.");
|
|
19
|
+
}
|
|
20
|
+
const env = { account, region };
|
|
21
|
+
const app = new App();
|
|
22
|
+
new VidfarmProdStack(app, "VidfarmProdStack", {
|
|
23
|
+
env,
|
|
24
|
+
zoneName: optional("VIDFARM_ZONE_NAME") ?? "cloud.zoomgtm.com",
|
|
25
|
+
zoneId: required("VIDFARM_ZONE_ID"),
|
|
26
|
+
recordName: optional("VIDFARM_RECORD_NAME") ?? "vidfarm",
|
|
27
|
+
publicBaseUrl: optional("VIDFARM_PUBLIC_BASE_URL") ?? "https://vidfarm.cloud.zoomgtm.com",
|
|
28
|
+
adminEmails: required("VIDFARM_ADMIN_EMAILS"),
|
|
29
|
+
developerEmails: optional("VIDFARM_DEVELOPER_EMAILS") ?? "",
|
|
30
|
+
encryptionSecret: required("VIDFARM_ENCRYPTION_SECRET"),
|
|
31
|
+
apiKeySalt: required("VIDFARM_API_KEY_SALT"),
|
|
32
|
+
webhookSecret: required("VIDFARM_WEBHOOK_SECRET"),
|
|
33
|
+
resendApiKey: optional("VIDFARM_RESEND_API_KEY"),
|
|
34
|
+
resendFromEmail: optional("VIDFARM_RESEND_FROM_EMAIL") ?? "noreply@zoomgtm.com",
|
|
35
|
+
superagencyKey: optional("SUPERAGENCY_KEY"),
|
|
36
|
+
openAiApiKey: optional("VIDFARM_OPENAI_API_KEY"),
|
|
37
|
+
openRouterApiKey: optional("VIDFARM_OPENROUTER_API_KEY"),
|
|
38
|
+
geminiApiKey: optional("VIDFARM_GEMINI_API_KEY"),
|
|
39
|
+
perplexityApiKey: optional("VIDFARM_PERPLEXITY_API_KEY"),
|
|
40
|
+
remotionMode: optional("VIDFARM_REMOTION_MODE") ?? "auto",
|
|
41
|
+
remotionRegion: optional("VIDFARM_REMOTION_REGION") ?? "us-east-1",
|
|
42
|
+
remotionBucketName: optional("VIDFARM_REMOTION_BUCKET_NAME"),
|
|
43
|
+
remotionSiteName: optional("VIDFARM_REMOTION_SITE_NAME"),
|
|
44
|
+
remotionFunctionName: optional("VIDFARM_REMOTION_FUNCTION_NAME"),
|
|
45
|
+
remotionServeUrl: optional("VIDFARM_REMOTION_SERVE_URL"),
|
|
46
|
+
remotionCompositionId: optional("VIDFARM_REMOTION_COMPOSITION_ID") ?? "template-0000",
|
|
47
|
+
remotionAwsAccessKeyId: optional("VIDFARM_REMOTION_AWS_ACCESS_KEY_ID"),
|
|
48
|
+
remotionAwsSecretAccessKey: optional("VIDFARM_REMOTION_AWS_SECRET_ACCESS_KEY"),
|
|
49
|
+
mockProviderResponses: optional("VIDFARM_MOCK_PROVIDER_RESPONSES") ?? "false",
|
|
50
|
+
workerPollMs: Number(optional("VIDFARM_WORKER_POLL_MS") ?? "1500"),
|
|
51
|
+
workerBatchSize: Number(optional("VIDFARM_WORKER_BATCH_SIZE") ?? "2"),
|
|
52
|
+
workerMaxConcurrentJobs: Number(optional("VIDFARM_WORKER_MAX_CONCURRENT_JOBS") ?? "1"),
|
|
53
|
+
defaultJobDelaySeconds: Number(optional("VIDFARM_DEFAULT_JOB_DELAY_SECONDS") ?? "20"),
|
|
54
|
+
maxPendingJobsGlobal: Number(optional("VIDFARM_MAX_PENDING_JOBS_GLOBAL") ?? "0"),
|
|
55
|
+
maxPendingJobsPerCustomer: Number(optional("VIDFARM_MAX_PENDING_JOBS_PER_CUSTOMER") ?? "0"),
|
|
56
|
+
instanceType: optional("VIDFARM_INSTANCE_TYPE") ?? "t3.small",
|
|
57
|
+
dataVolumeSizeGiB: Number(optional("VIDFARM_DATA_VOLUME_SIZE_GIB") ?? "80")
|
|
58
|
+
});
|
|
59
|
+
app.synth();
|