@mevdragon/vidfarm-devcli 0.2.8 → 0.2.10

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 (98) hide show
  1. package/.env.example +9 -0
  2. package/GETTING_STARTED.developers.md +1 -26
  3. package/README.md +3 -0
  4. package/SKILL.developer.md +419 -8
  5. package/auto-create-templates/AUTO_CREATE_TEMPLATES.md +475 -0
  6. package/auto-create-templates/extractor-system-prompt.md +113 -0
  7. package/auto-create-templates/production-graph.schema.json +276 -0
  8. package/auto-create-templates/runbook.md +140 -0
  9. package/auto-create-templates/template-plan.schema.json +230 -0
  10. package/auto-create-templates/template-planner-prompt.md +75 -0
  11. package/dist/src/account-pages-legacy.js +9064 -0
  12. package/dist/src/account-pages.js +41 -620
  13. package/dist/src/app.js +6627 -244
  14. package/dist/src/cli.js +386 -26
  15. package/dist/src/config.js +12 -2
  16. package/dist/src/context.js +35 -35
  17. package/dist/src/db.js +1016 -53
  18. package/dist/src/dev-app-legacy.js +693 -0
  19. package/dist/src/dev-app.js +4 -904
  20. package/dist/src/domain.js +1 -1
  21. package/dist/src/editor-chat-history.js +72 -0
  22. package/dist/src/editor-chat.js +202 -0
  23. package/dist/src/frontend/flockposter-cache-store.js +116 -0
  24. package/dist/src/frontend/homepage-client.js +114 -0
  25. package/dist/src/frontend/homepage-shared.js +3 -0
  26. package/dist/src/frontend/homepage-store.js +27 -0
  27. package/dist/src/frontend/homepage-view.js +147 -0
  28. package/dist/src/frontend/page-runtime-client.js +100 -0
  29. package/dist/src/frontend/page-runtime-store.js +8 -0
  30. package/dist/src/frontend/template-editor-chat.js +2261 -0
  31. package/dist/src/homepage.js +695 -371
  32. package/dist/src/lib/template-style-options.js +95 -15
  33. package/dist/src/page-runtime.js +1 -0
  34. package/dist/src/page-shell.js +941 -0
  35. package/dist/src/primitive-context.js +163 -0
  36. package/dist/src/primitive-registry.js +340 -0
  37. package/dist/src/primitive-sdk.js +3 -0
  38. package/dist/src/primitives/remotion/html-image.js +28 -0
  39. package/dist/src/react-page-shell.js +34 -0
  40. package/dist/src/ready-post-schedule-component.js +1514 -0
  41. package/dist/src/registry.js +36 -17
  42. package/dist/src/runtime.js +6 -1
  43. package/dist/src/services/api-call-history.js +245 -0
  44. package/dist/src/services/auth.js +25 -3
  45. package/dist/src/services/billing.js +248 -9
  46. package/dist/src/services/chat-threads.js +88 -0
  47. package/dist/src/services/job-logs.js +14 -7
  48. package/dist/src/services/jobs.js +13 -2
  49. package/dist/src/services/providers.js +552 -133
  50. package/dist/src/services/rate-limits.js +236 -0
  51. package/dist/src/services/remotion.js +143 -16
  52. package/dist/src/services/storage.js +10 -8
  53. package/dist/src/services/template-certification.js +11 -2
  54. package/dist/src/services/template-loader.js +3 -1
  55. package/dist/src/services/template-sources.js +68 -3
  56. package/dist/src/template-editor-pages.js +2309 -0
  57. package/dist/src/template-editor-shell.js +1507 -0
  58. package/dist/src/worker.js +120 -22
  59. package/package.json +27 -4
  60. package/public/assets/homepage-app.js +54 -0
  61. package/public/assets/homepage-client-app.js +54 -0
  62. package/public/assets/page-runtime-client-app.js +68 -0
  63. package/dist/templates/vidfarm_template_0000/src/lib/images.js +0 -202
  64. package/dist/templates/vidfarm_template_0000/src/remotion/Root.js +0 -34
  65. package/dist/templates/vidfarm_template_0000/src/remotion/index.js +0 -3
  66. package/dist/templates/vidfarm_template_0000/src/sdk.js +0 -3
  67. package/dist/templates/vidfarm_template_0000/src/style-options.js +0 -51
  68. package/dist/templates/vidfarm_template_0000/src/template-dna.js +0 -9
  69. package/dist/templates/vidfarm_template_0000/src/template.js +0 -1447
  70. package/templates/vidfarm_template_0000/README.md +0 -100
  71. package/templates/vidfarm_template_0000/SKILL.md +0 -225
  72. package/templates/vidfarm_template_0000/assets/Abel-Regular.ttf +0 -0
  73. package/templates/vidfarm_template_0000/assets/DMSerifDisplay-Regular.ttf +0 -0
  74. package/templates/vidfarm_template_0000/assets/Montserrat[wght].ttf +0 -0
  75. package/templates/vidfarm_template_0000/assets/SourceCodePro[wght].ttf +0 -0
  76. package/templates/vidfarm_template_0000/assets/TikTokSans-SemiBold.ttf +0 -0
  77. package/templates/vidfarm_template_0000/assets/Yesteryear-Regular.ttf +0 -0
  78. package/templates/vidfarm_template_0000/composition.json +0 -11
  79. package/templates/vidfarm_template_0000/package.json +0 -27
  80. package/templates/vidfarm_template_0000/research/preview/.gitkeep +0 -1
  81. package/templates/vidfarm_template_0000/research/source_notes.md +0 -7
  82. package/templates/vidfarm_template_0000/src/lib/images.js +0 -202
  83. package/templates/vidfarm_template_0000/src/lib/images.ts +0 -241
  84. package/templates/vidfarm_template_0000/src/remotion/Root.js +0 -33
  85. package/templates/vidfarm_template_0000/src/remotion/Root.tsx +0 -75
  86. package/templates/vidfarm_template_0000/src/remotion/index.js +0 -3
  87. package/templates/vidfarm_template_0000/src/remotion/index.tsx +0 -4
  88. package/templates/vidfarm_template_0000/src/sdk.js +0 -3
  89. package/templates/vidfarm_template_0000/src/sdk.ts +0 -140
  90. package/templates/vidfarm_template_0000/src/style-options.js +0 -51
  91. package/templates/vidfarm_template_0000/src/style-options.ts +0 -60
  92. package/templates/vidfarm_template_0000/src/template-dna.js +0 -9
  93. package/templates/vidfarm_template_0000/src/template-dna.ts +0 -15
  94. package/templates/vidfarm_template_0000/src/template.js +0 -1447
  95. package/templates/vidfarm_template_0000/src/template.ts +0 -2049
  96. package/templates/vidfarm_template_0000/template.config.json +0 -21
  97. package/templates/vidfarm_template_0000/tmp/solobacterium-moorei-slideshow.request.json +0 -31
  98. package/templates/vidfarm_template_0000/tsconfig.json +0 -19
@@ -26,10 +26,51 @@ Do not use this skill for:
26
26
  - production deploys, release admin, or shared cloud infrastructure
27
27
  - asking for AWS, S3, Remotion cloud, or other platform secrets
28
28
 
29
+ ## Hosted Remotion Cost Reporting
30
+
31
+ When a template runs a hosted Remotion Lambda render, template code should report the base render cost back to platform billing.
32
+
33
+ Use the template job context billing helper:
34
+
35
+ ```ts
36
+ await ctx.billing.record({
37
+ type: "render",
38
+ costUsd: 0.35,
39
+ costCenterSlug: "remotion_lambda",
40
+ idempotencyKey: `remotion_lambda:${render.renderId}`,
41
+ occurredAtMs: Date.now(),
42
+ metadata: {
43
+ render_id: render.renderId,
44
+ ...render.metadata
45
+ }
46
+ });
47
+ ```
48
+
49
+ Rules:
50
+
51
+ - only report the raw base Remotion cost in `costUsd`
52
+ - always use `costCenterSlug: "remotion_lambda"` for hosted Remotion Lambda usage
53
+ - always provide a stable `idempotencyKey`, typically derived from `render.renderId`
54
+ - include useful diagnostics in `metadata`, such as `render_id`, composition ID, mode, and output details
55
+ - do not compute customer wallet debits in template code
56
+ - do not set platform pricing policy in template code
57
+
58
+ The platform billing service applies wallet mutations and pricing centrally. The default customer charge currently uses an approximately `20%` safety-buffer markup over reported base cost.
59
+
60
+ Job-status billing response fields are also platform-managed. Template developers do not need to shape the API response; they only need to keep reporting real usage through existing helpers where applicable. The customer-facing job response exposes `billing.consumed_usd` and does not expose internal `base_cost_usd`.
61
+
29
62
  ## Third-Party Publish Rule
30
63
 
31
64
  Third-party template developers publish template code by pushing git commits to GitHub. That is the only code-distribution step they own.
32
65
 
66
+ Default hosted update rule:
67
+
68
+ - for an already-registered template, the default hosted handoff is `publish-update-hosted --commit-sha <sha>`
69
+ - do not default to prod-side branch-head import for normal template updates
70
+ - if the source repo is private, treat artifact publish as the normal path, not as a fallback
71
+ - if `gh` is available, prefer an authenticated local clone such as `gh repo clone <owner>/<repo>` before publishing a hosted update
72
+ - checked-in `about/preview-*` files only become live hosted preview media after platform import and activation sync them into `templates/:template_id/about/*`
73
+
33
74
  Important nuance:
34
75
 
35
76
  - GitHub is relevant for the hosted handoff, not for normal local template authoring
@@ -44,6 +85,25 @@ The third-party developer responsibility is:
44
85
  - for an already-registered template update, publish the exact GitHub commit SHA with `publish-update-hosted`
45
86
  - stop there and hand off to the platform team
46
87
 
88
+ Preferred private-repo publish pattern:
89
+
90
+ ```bash
91
+ gh repo clone mevdragon/vidfarm_templates ./vidfarm_templates
92
+ git -C ./vidfarm_templates rev-parse HEAD
93
+ node dist/src/cli.js publish-update-hosted \
94
+ --env-file .env \
95
+ --repo-dir ./vidfarm_templates \
96
+ --template-id <template-id> \
97
+ --slug-id <template-slug> \
98
+ --repo-url https://github.com/mevdragon/vidfarm_templates.git \
99
+ --branch main \
100
+ --template-module-path src/<template-folder>/src/template.ts \
101
+ --skill-path src/<template-folder>/SKILL.md \
102
+ --install-command "npm install --prefix src/<template-folder>" \
103
+ --build-command "npm run build --prefix src/<template-folder>" \
104
+ --commit-sha <exact-github-commit>
105
+ ```
106
+
47
107
  The third-party developer should not:
48
108
 
49
109
  - run `import-source-prod`
@@ -55,27 +115,47 @@ The third-party developer should not:
55
115
 
56
116
  Private repo rule:
57
117
 
118
+ - if the registered source repo is private, do not treat prod-side `git ls-remote` or raw GitHub import as the primary publish mechanism
119
+ - for private repos, the reliable default is: authenticated local clone -> `publish-update-hosted --commit-sha ...` -> platform review -> admin approve/activate
58
120
  - if the registered source repo is private, assume the intended hosted setup is that Vidfarm has already been granted access to it
59
121
  - when repo sharing is needed, the repo should be shared with GitHub username `mevdragon`
60
122
  - do not treat a private repo itself as a problem if that access assumption is already stated
61
123
 
62
124
  For third-party developers, Remotion is local and storage should be accessed through Vidfarm helpers. Do not require cloud Remotion setup or hand-written S3 integration for normal template work.
63
125
 
126
+ ## Media Storage Boundary
127
+
128
+ Template job results must keep binary media out of JSON. If a workflow produces, fetches, or accepts image/audio/video bytes, write those bytes through `ctx.storage.putBuffer(...)` and put the returned URL in the job output, manifest, and render inputs.
129
+
130
+ Rules:
131
+
132
+ - use `ctx.storage.putBuffer(...)`, `ctx.storage.putJson(...)`, and `ctx.storage.putText(...)` for artifacts
133
+ - return artifact URLs in fields like `imageUrl`, `thumbnailUrl`, `audioUrl`, `videoUrl`, `files`, `manifest`, and render input objects
134
+ - do not persist `data:image/...;base64,...`, raw base64 strings, Buffers, or large inline SVG/image strings in `result.output`
135
+ - accepting a `data:image/*` input is allowed, but decode it and store it as an artifact before including it in any durable output
136
+ - generated provider media should be stored immediately; never use `Buffer.from(bytes).toString("base64")` as a durable result value
137
+ - Remotion render props may reference artifact URLs; use short-lived inline data only inside a private render helper if it is not returned, logged, or written to a manifest
138
+ - keep manifests lightweight enough to inspect in job history and webhooks; they should describe artifacts by URL, not embed artifact bytes
139
+
140
+ This boundary matters because job results are saved in SQLite, returned by REST APIs, included in webhooks, and surfaced in editor history. Embedding base64 media can turn one small job result into multi-megabyte JSON and break UI history views.
141
+
64
142
  ## Agent Operating Rule
65
143
 
66
144
  If the user gives you a media file, a screenshot, a folder of source assets, or a link to an original viral post and says some variant of "turn this into a template", you should default to this workflow:
67
145
 
68
146
  1. inspect the source media and extract the repeatable format
69
- 2. scaffold a new template with `vidfarm-devcli generate-template`
70
- 3. stage the source notes and preview media inside the template
71
- 4. run `analyze-viral-dna`
72
- 5. run `analyze-visual-dna`
147
+ 2. start the native harness workflow with `vidfarm-devcli autocreate-template <input_path> <output_path>`
148
+ 3. review the generated run folder, manifest, and `agent_prompt.md`
149
+ 4. generate the preservation decision, production graph, and template plan
150
+ 5. run or consume `analyze-viral-dna` and `analyze-visual-dna`
73
151
  6. implement the template operations and jobs
74
152
  7. wire prompt logic, provider usage, storage writes, and local Remotion output
75
153
  8. expose the template through the standard REST routes
76
154
  9. validate the template locally with `validate-template` plus at least one real job run
77
155
  10. update the template-local `SKILL.md` so future agents can operate it
78
156
 
157
+ Use `generate-template` directly only when the developer already knows the template architecture and wants a plain starter scaffold. Use `autocreate-template` when source media needs to be analyzed into a reusable format.
158
+
79
159
  Do not stop after scaffolding. The expected outcome is a runnable template, not just a folder.
80
160
 
81
161
  If the user gives revision feedback in natural language, treat that as a normal template-authoring input, not as a vague suggestion. Example revision prompts:
@@ -164,6 +244,8 @@ For a third-party developer, the hosted publish handoff is:
164
244
  3. if the template is already registered and the location did not change, publish the exact GitHub commit SHA with `publish-update-hosted`; that command uploads a signed artifact for that commit
165
245
  4. stop there, then tell the platform operator which commit was submitted if they ask
166
246
 
247
+ If the repo is private or prod-side GitHub access is uncertain, use the exact same `publish-update-hosted` flow anyway. It packages the commit locally and avoids relying on hosted `git ls-remote` or hosted branch-head import as the update path.
248
+
167
249
  Registration data should be treated like this:
168
250
 
169
251
  - `repo_url`: the GitHub repo that contains the template code
@@ -191,6 +273,7 @@ When reasoning about hosted visibility:
191
273
  - the required developer-side outcome is that the intended commit is pushed to the registered branch
192
274
  - do not infer hosted GitHub access failure from a local CLI auth error
193
275
  - for hosted template updates, the review artifact is uploaded from the developer machine and prod later imports it from S3, so server-side GitHub access is not part of the normal publish path
276
+ - if prod-side import fails on `git ls-remote`, GitHub username/password prompts, or private-repo access, the correct fix is usually to publish the exact commit as an artifact from a locally authenticated checkout, not to keep retrying branch-head import
194
277
 
195
278
  If a developer can register a source but receives `403 Admin access required` when trying to import or activate it, that is the expected boundary, not a blocker they are supposed to solve. It means the handoff point was reached correctly.
196
279
 
@@ -206,6 +289,12 @@ If the user explicitly says "template deploy cycle", interpret that as the inter
206
289
  2. approve and activate the new release
207
290
  3. run the prod deploy script if platform code changed, or reuse the current prod image for a formal restart if the change was template-only
208
291
 
292
+ Operator preference rule:
293
+
294
+ - if a pending artifact-backed release already exists for the intended commit, prefer approving and activating that release instead of asking prod to resolve branch head from GitHub
295
+ - activation is the step that syncs checked-in template `about/` preview assets into hosted storage under `templates/:template_id/about/*`
296
+ - if a hosted template exists in the catalog but its preview media redirects to missing S3 keys, re-activating the intended release on a platform build that contains the sync logic is the correct fix
297
+
209
298
  Do not assume "template deploy cycle" means "deploy the entire dirty root repo". If the root worktree has unrelated changes and the release is template-only, prefer reusing the current prod image with:
210
299
 
211
300
  ```bash
@@ -237,6 +326,7 @@ The contract is:
237
326
  - `configSchema` defines editable per-user template config
238
327
  - `about.viral_dna` and `about.visual_dna` explain why the format wins
239
328
  - `about.proposal_generator` tells directors and agents how to turn product/about context into template-native post ideas
329
+ - `about.skeleton_prompt` gives directors and agents a fill-in-the-blanks prompt scaffold for the template
240
330
  - `about.sample_prompts` shows future users and agents how to prompt the template well
241
331
  - `SKILL.md` teaches humans and agents how to call the template correctly
242
332
  - the canonical template entrypoint is `src/template.ts`
@@ -251,6 +341,17 @@ The platform-owned helper surface on `ctx.providers` currently includes:
251
341
 
252
342
  Every public template action should remain async and job-based. Prefer one or more named operations behind `POST /api/v1/templates/:templateId/operations/:operationName` instead of inventing custom synchronous endpoints.
253
343
 
344
+ Keep operation design reasonably coarse-grained. These routes are customer-facing, usage-limited API calls, so avoid exploding one user action into a large number of tiny operations unless the workflow genuinely needs that split.
345
+
346
+ Vidfarm already has native queueing for template jobs. When a task needs multiple runs, do not invent a custom batch manager, worker pool, queue coordinator, or other fancy orchestration layer in the template or in temporary validation code. The default pattern is:
347
+
348
+ - submit jobs in a reasonable loop
349
+ - record the returned job IDs
350
+ - poll those jobs through the standard job endpoints
351
+ - if completion will take a while, tell the user to check back later instead of overengineering lifecycle control
352
+
353
+ Use extra job-management code only when the user explicitly asks for it and there is a concrete platform requirement that the built-in queue cannot satisfy.
354
+
254
355
  Templates are expected to evolve through multiple revisions. One-shot generation is not the standard. The standard is:
255
356
 
256
357
  - create a working first pass
@@ -297,6 +398,42 @@ const TEMPLATE_PROVIDER_REQUIREMENTS = {
297
398
  } as const;
298
399
  ```
299
400
 
401
+ Recommended baseline model set, matching the current repo examples unless a template has a specific reason to differ:
402
+
403
+ ```ts
404
+ const TEMPLATE_PROVIDER_RECOMMENDATIONS = {
405
+ text: {
406
+ openai: "gpt-5.4",
407
+ gemini: "gemini-3.1-flash-lite",
408
+ openrouter: "qwen/qwen3.6-flash"
409
+ },
410
+ layout_analysis: {
411
+ openai: "gpt-5.4",
412
+ gemini: "gemini-3.1-flash-lite",
413
+ openrouter: "qwen/qwen3.6-flash"
414
+ },
415
+ image: {
416
+ openai: "gpt-image-1",
417
+ gemini: "gemini-3.1-flash-image-preview",
418
+ openrouter: "google/gemini-3.1-flash-image-preview"
419
+ },
420
+ video: {
421
+ openai: "sora-2",
422
+ gemini: "veo-3.0-generate-001"
423
+ },
424
+ tts: {
425
+ openai: "gpt-4o-mini-tts-2025-12-15",
426
+ gemini: "gemini-3.1-flash-tts-preview",
427
+ openrouter: "google/gemini-3.1-flash-tts-preview"
428
+ },
429
+ stt: {
430
+ openai: "gpt-4o-mini-transcribe-2025-12-15",
431
+ gemini: "gemini-3.1-flash-lite-preview",
432
+ openrouter: "openai/gpt-4o-mini-transcribe"
433
+ }
434
+ } as const;
435
+ ```
436
+
300
437
  Important:
301
438
 
302
439
  - this is documentation for humans and agents, not a framework-consumed schema field
@@ -332,7 +469,9 @@ npx @mevdragon/vidfarm-devcli presign-preview-media \
332
469
  --directory drafts/preview
333
470
  ```
334
471
 
335
- That command calls the hosted Vidfarm API with the user's `VIDFARM_API_KEY`, mints a presigned PUT URL scoped under `developer/<user_id>/*`, stores each uploaded file under a UUID path segment while preserving the original filename, uploads the file automatically when `--file` is provided, and returns both the `storage_key` and a public-read `preview_media_url`. Public readability for `developer/<user_id>/*` comes from Vidfarm bucket policy, not from public write access, so objects may be read directly by URL but should not be treated as listable or writable without authenticated API access. Agents should prefer that path for hosted preview uploads whenever the input is a local media file path.
472
+ That command calls the hosted Vidfarm API with the user's `VIDFARM_API_KEY`, mints a presigned PUT URL scoped under `developer/<user_id>/*`, stores each uploaded file under a UUID path segment while preserving the original filename, uploads the file automatically when `--file` is provided, and returns both the `storage_key` and a public-read `preview_media_url`. Public readability for `developer/<user_id>/*` comes from Vidfarm bucket policy, not from public write access, so objects may be read directly by URL but should not be treated as listable or writable without authenticated API access. Agents should prefer that path for hosted preview uploads whenever the input is a local media file path, and should paste the returned absolute `preview_media_url` directly into `about.preview_media` when the template needs to work immediately in the hosted catalog.
473
+
474
+ Do not assume a checked-in repo asset like `about/preview-01.png` already exists at `templates/:template_id/about/*` in hosted S3. That stable template namespace is populated by the platform import and activation flow, not by the developer presign command. Before admin import/activation, the immediately valid hosted preview URL is the returned `developer/<user_id>/*` public URL.
336
475
 
337
476
  ### 2. Start local runtime
338
477
 
@@ -354,6 +493,63 @@ Keep the identifiers separate:
354
493
  - `about.title` is the user-facing display title and should not be prefixed with `Vidfarm Template` unless that phrase is genuinely part of the brand or concept
355
494
  - avoid redundant titles like `Vidfarm Template UGC Hooks V1` when `UGC Hooks V1` is the actual display name
356
495
 
496
+ ### 3a. Use the native auto-create harness for media-to-template work
497
+
498
+ When the developer says "autocreate a template based on media in `<input_path>` and output template to `<output_path>`", use:
499
+
500
+ ```bash
501
+ npx @mevdragon/vidfarm-devcli autocreate-template <input_path> <output_path>
502
+ ```
503
+
504
+ Alias:
505
+
506
+ ```bash
507
+ npx @mevdragon/vidfarm-devcli autocreate <input_path> <output_path>
508
+ ```
509
+
510
+ The command accepts either positional paths or explicit flags:
511
+
512
+ ```bash
513
+ npx @mevdragon/vidfarm-devcli autocreate-template \
514
+ --input-path ./drafts/my_format \
515
+ --output-path ./templates/vidfarm_template_my_format \
516
+ --link-to-original "https://www.tiktok.com/@example/video/1234567890"
517
+ ```
518
+
519
+ What this does:
520
+
521
+ - creates `auto-create-templates/runs/<run_id>/`
522
+ - stages source notes and preview media under `source/`
523
+ - creates the standard analyzer artifact folders: `frames`, `audio`, `transcripts`, `ocr`, `motion`, `dna`, `extraction`, and `plan`
524
+ - snapshots the current reusable harness files into `runs/<run_id>/harness/` for traceability
525
+ - runs basic `ffprobe`/`ffmpeg` extraction when source video and local tools are available
526
+ - scaffolds the output template with the same starter logic as `generate-template`
527
+ - writes `manifest.json` and `agent_prompt.md` as the agent handoff
528
+
529
+ Useful options:
530
+
531
+ - `--run-id <id>`: choose the run folder name
532
+ - `--slug-id <slug>`: override the slug derived from the output folder
533
+ - `--template-id <uuid>`: pin the template UUID
534
+ - `--skip-dna-analysis`: scaffold without calling Gemini DNA analysis
535
+ - `--skip-media-probes`: skip local `ffprobe`/`ffmpeg` artifact generation
536
+ - `--skip-scaffold`: create only the run artifacts and handoff prompt
537
+ - `--harness-dir <path>`: use a local harness checkout other than `auto-create-templates/`
538
+ - `--force`: replace an existing output template folder
539
+
540
+ After running `autocreate-template`, continue the harness workflow instead of stopping at scaffold:
541
+
542
+ 1. inspect `auto-create-templates/runs/<run_id>/agent_prompt.md`
543
+ 2. create `dna/preservation_decision.json`
544
+ 3. create `extraction/production_graph.json` matching `production-graph.schema.json`
545
+ 4. create `plan/template_plan.json` matching `template-plan.schema.json`
546
+ 5. implement `src/template.ts`, metadata, prompts, operations, jobs, and template-local `SKILL.md`
547
+ 6. run `validate-template` and at least one real local job
548
+
549
+ The reusable harness lives in `auto-create-templates/AUTO_CREATE_TEMPLATES.md`. It is intentionally included in the devcli package as editable source material. Future improvements to the harness should be made there; each auto-create run stores a snapshot of the harness files used for that run so older runs remain explainable.
550
+
551
+ ### 3b. Generate a plain starter template
552
+
357
553
  Example:
358
554
 
359
555
  ```bash
@@ -418,7 +614,7 @@ These commands:
418
614
  - sync the generated DNA module back into the template
419
615
  - populate the strings consumed by `about.viral_dna`, `about.visual_dna`, and `about.link_to_original`
420
616
 
421
- After DNA analysis, add `about.proposal_generator` and `about.sample_prompts` manually. The standard now requires both. `proposal_generator` should help a director combine product/about information with the template's format to invent many post proposals, and `sample_prompts` should show what strong final prompts look like. Do not leave either as optional polish.
617
+ After DNA analysis, add `about.proposal_generator`, `about.skeleton_prompt`, and `about.sample_prompts` manually. The standard now requires all three. `proposal_generator` should help a director combine product/about information with the template's format to invent many post proposals. `skeleton_prompt` should provide the default fill-in-the-blanks structure a director can instantiate quickly. `sample_prompts` should show what strong final prompts look like. Do not leave any of them as optional polish.
422
618
 
423
619
  Required-field rule:
424
620
 
@@ -445,6 +641,7 @@ For a new template, make sure it has:
445
641
  - `about.preview_media`
446
642
  - `about.link_to_original`
447
643
  - `about.proposal_generator` with a reusable instruction for proposal generation
644
+ - `about.skeleton_prompt` with a reusable fill-in-the-blanks prompt scaffold
448
645
  - `about.sample_prompts` with multiple concrete examples
449
646
  - `configSchema`
450
647
  - `operations`
@@ -469,6 +666,7 @@ The platform route shape is fixed. A template should work behind:
469
666
 
470
667
  - `GET /api/v1/templates/:templateId`
471
668
  - `GET /api/v1/templates/:templateId/skill`
669
+ - `GET /api/v1/rate-limit-status`
472
670
  - `POST /api/v1/templates/:templateId/config`
473
671
  - `POST /api/v1/templates/:templateId/operations/:operationName`
474
672
  - `GET /api/v1/templates/:templateId/jobs/:jobId`
@@ -477,6 +675,65 @@ The platform route shape is fixed. A template should work behind:
477
675
 
478
676
  Do not invent one-off REST endpoints for template behavior that already fits an operation workflow.
479
677
 
678
+ Template-local docs do not need to restate platform plan names or operation quota numbers unless a template adds stricter limits of its own.
679
+
680
+ Every template-local `SKILL.md` must also include TypeScript route templates for those routes. Treat this as part of the template standard, not optional documentation. The type block must name the concrete template slug, list every operation as a string-literal union, define each operation payload, and show the standard wrapper bodies.
681
+
682
+ Minimum block to adapt per template:
683
+
684
+ ```ts
685
+ type TemplateSlug = "vidfarm_template_example";
686
+ type TemplateOperation = "create_asset" | "render_video";
687
+
688
+ type TemplateConfigRequest = {
689
+ config: {
690
+ defaultProvider?: "openai" | "gemini" | "openrouter" | "perplexity";
691
+ [key: string]: unknown;
692
+ };
693
+ };
694
+
695
+ type SubmitTemplateOperation<TPayload> = {
696
+ tracer?: string;
697
+ payload: TPayload;
698
+ webhook_url?: string;
699
+ };
700
+
701
+ type QueuedJobResponse = {
702
+ job_id: string;
703
+ tracer?: string;
704
+ status: "queued";
705
+ };
706
+
707
+ type JobStatusResponse<TOutput = unknown> = {
708
+ job_id: string;
709
+ template_id: TemplateSlug;
710
+ operation_name: TemplateOperation;
711
+ tracer?: string;
712
+ status: "queued" | "running" | "succeeded" | "failed" | "cancelled";
713
+ progress?: number;
714
+ output?: TOutput;
715
+ error?: string;
716
+ };
717
+
718
+ type TemplateRoute =
719
+ | `GET /api/v1/templates/${TemplateSlug}`
720
+ | `GET /api/v1/templates/${TemplateSlug}/skill`
721
+ | `POST /api/v1/templates/${TemplateSlug}/config`
722
+ | `POST /api/v1/templates/${TemplateSlug}/operations/${TemplateOperation}`
723
+ | `GET /api/v1/templates/${TemplateSlug}/jobs`
724
+ | `GET /api/v1/templates/${TemplateSlug}/jobs/${string}`
725
+ | `GET /api/v1/templates/${TemplateSlug}/jobs/${string}/logs`
726
+ | `POST /api/v1/templates/${TemplateSlug}/jobs/${string}/cancel`;
727
+ ```
728
+
729
+ For collection-style REST reads, use cursor pagination instead of assuming a single unbounded response:
730
+
731
+ - send `limit`
732
+ - if the response returns `next_cursor`, request the next page with `cursor=<that value>`
733
+ - this applies to template job lists, structured logs, artifacts, and the admin source/release queues
734
+
735
+ If the template accepts custom HTML, attachment URLs, generated image prompts, render-slide manifests, provider/model choices, or template-specific output artifacts, include those fields in the route types instead of leaving them as `Record<string, unknown>`.
736
+
480
737
  ### 8. Validate end to end
481
738
 
482
739
  Run:
@@ -500,6 +757,8 @@ Minimum bar:
500
757
  - inspect produced artifacts
501
758
  - if you need ad hoc scripts or test-run inputs to drive this validation, keep them under a sibling `tmp/` folder and not inside `src/`
502
759
 
760
+ For multi-job validation, keep it simple: create the jobs in a loop, wait or poll, inspect the finished results, and move on. Do not turn local validation into a custom batch-processing subsystem.
761
+
503
762
  The expected result is that another agent can rerun the template without reverse-engineering the workflow.
504
763
 
505
764
  ## Golden Path: Natural-Language Revisions
@@ -553,7 +812,7 @@ A revision is not complete just because the code compiles. It is complete when:
553
812
  - the requested change is visible in the output
554
813
  - the change does not obviously regress the core format
555
814
  - the template can still be rerun by another user or agent
556
- - `about.proposal_generator` and `about.sample_prompts` still reflect the best current way to ideate and prompt the template
815
+ - `about.proposal_generator`, `about.skeleton_prompt`, and `about.sample_prompts` still reflect the best current way to ideate and prompt the template
557
816
  - the usage instructions still match the implementation
558
817
 
559
818
  ## Template Contract
@@ -574,6 +833,8 @@ export const myTemplate = defineTemplate({
574
833
  link_to_original: "https://www.tiktok.com/@example/video/1234567890",
575
834
  proposal_generator:
576
835
  "Given the director's product, audience, and positioning, propose multiple UGC hook post ideas that fit this template. Return ideas that can either be used directly as prompts or expanded into a larger series of related prompts.",
836
+ skeleton_prompt:
837
+ "Create a [number]-slide UGC hook post for [audience] about [topic or product]. Hook: [opening]. Middle beats: [proof, story, objection, or comparison]. Ending: [CTA or payoff]. Tone: [voice].",
577
838
  sample_prompts: [
578
839
  "Create a 3-slide UGC hook sequence for a sleep supplement targeting new parents.",
579
840
  "Make a creator-style launch teaser for a skincare serum with one hook, one proof point, and one CTA.",
@@ -620,6 +881,7 @@ Keep these roles clear:
620
881
  - `about.preview_media` is required and should contain checked-in preview asset paths that represent the template well
621
882
  - `about.link_to_original` is required and should point to the original inspiration post or source reference when one exists
622
883
  - `about.proposal_generator` is required and should help directors turn product/about context into a list of strong post proposals for that template
884
+ - `about.skeleton_prompt` is required and should give directors a template-native fill-in-the-blanks prompt scaffold they can instantiate quickly
623
885
  - `about.sample_prompts` is required and should contain realistic, high-signal examples that teach users how to get good results
624
886
  - `operations` define the public API
625
887
  - `jobs` implement the actual work
@@ -637,6 +899,7 @@ Required fields checklist:
637
899
  - `about.preview_media`
638
900
  - `about.link_to_original`
639
901
  - `about.proposal_generator`
902
+ - `about.skeleton_prompt`
640
903
  - `about.sample_prompts`
641
904
  - `configSchema`
642
905
  - at least one operation
@@ -644,15 +907,148 @@ Required fields checklist:
644
907
  - `smokeTestPayload` for every operation
645
908
  - template-local `SKILL.md`
646
909
 
910
+ ## Caption Style Standard
911
+
912
+ For TikTok-native captions, use the platform caption standard exposed by `vidfarm-devcli session` under `starter_style_options`.
913
+
914
+ Check the currently installed CLI values with:
915
+
916
+ ```bash
917
+ npx @mevdragon/vidfarm-devcli session
918
+ ```
919
+
920
+ The current standard version is `2026-05-30`. The CLI response includes `caption_standard_version`, `fonts`, `text_background_colors`, `presets`, `package_dependencies`, the source standard file, and the starter template style file.
921
+
922
+ Canonical font IDs:
923
+
924
+ - `tiktok_sans_semibold`: default native TikTok caption font, backed by `@fontsource/tiktok-sans` or the bundled `TikTokSans-SemiBold.ttf` starter asset
925
+ - `montserrat_semibold`: rounded modern caption style
926
+ - `source_code_pro_bold`: bold monospace caption style
927
+ - `yesteryear`: script caption style
928
+ - `georgia_bold`: bundled Georgia-style bold serif caption, backed by Libre Baskerville from Fontsource
929
+ - `abel`: condensed caption style
930
+
931
+ Legacy aliases remain accepted for older starters:
932
+
933
+ - `montserrat` -> `montserrat_semibold`
934
+ - `source_code_pro` -> `source_code_pro_bold`
935
+
936
+ Font package dependencies exposed by the CLI:
937
+
938
+ - `@fontsource/tiktok-sans`
939
+ - `@fontsource/montserrat`
940
+ - `@fontsource/source-code-pro`
941
+ - `@fontsource/libre-baskerville`
942
+
943
+ Bundled starter assets may also be available for template-local rendering:
944
+
945
+ - `TikTokSans-SemiBold.ttf`
946
+ - `Montserrat[wght].ttf`
947
+ - `SourceCodePro[wght].ttf`
948
+ - `Yesteryear-Regular.ttf`
949
+ - `Abel-Regular.ttf`
950
+
951
+ Canonical text background color IDs:
952
+
953
+ - `black`: `#000000`
954
+ - `red`: `#EA403F`
955
+ - `orange`: `#FF933D`
956
+ - `yellow`: `#F2CD46`
957
+ - `lime_green`: `#78C25E`
958
+ - `teal`: `#77C8A6`
959
+ - `light_blue`: `#3496F0`
960
+ - `dark_blue`: `#3496F0`
961
+ - `violet`: `#5756D4`
962
+ - `pink`: `#F7D7E9`
963
+ - `brown`: `#A3895B`
964
+ - `dark_green`: `#32523B`
965
+ - `blue_gray`: `#2F688C`
966
+ - `light_gray`: `#92979E`
967
+ - `dark_gray`: `#333333`
968
+
969
+ Canonical style presets:
970
+
971
+ - `tiktok_native_white`: TikTok Sans SemiBold, white fill, no color chip, native black shadow
972
+ - `tiktok_native_chip`: TikTok Sans SemiBold, white fill, red default color chip, native black shadow
973
+ - `tiktok_editor_gray`: TikTok Sans SemiBold, dark fill, light gray default chip, no shadow
974
+
975
+ Templates that expose caption styling should use these IDs in `configSchema`, operation payloads, manifests, and docs instead of inventing local names or hardcoding unrelated font stacks. If a template intentionally uses a format-specific typography system, document the exception in the template-local `SKILL.md`.
976
+
977
+ The caption standard is a default, not a hard lock. Templates may support `captionFont: "custom"` or template-specific text rendering when the user explicitly needs typography outside the standard. In that case, keep the standard options available, document the custom fields, and prefer bundled or template-local font assets over system fonts or remote Google Fonts URLs.
978
+
647
979
  Best-practice rule:
648
980
 
981
+ - when creating a new template, the agent should author `about.proposal_generator`, `about.skeleton_prompt`, `about.sample_prompts`, and the template-local `SKILL.md` in the same pass without waiting for a separate follow-up request
649
982
  - every template should ship with sample prompts
650
983
  - every template should ship with a proposal generator prompt
984
+ - every template should ship with a skeleton prompt that captures the default prompt structure
651
985
  - proposal generation should support a workflow of proposal -> prompts -> posts
986
+ - proposal generation should use the skeleton prompt as a quality harness, so the ideas it emits can be instantiated cleanly without inventing a brand-new structure every time
652
987
  - proposal outputs should be useful either as direct one-off prompts or as seeds for a whole series
988
+ - sample prompts should feel like strong filled-out versions of the skeleton prompt, not disconnected examples
653
989
  - include more than one example so users can see the range of valid requests
654
990
  - prefer prompts that are specific enough to be reusable exemplars, not vague one-liners
655
- - refresh both `about.proposal_generator` and `about.sample_prompts` when the template's prompting strategy or supported use cases change
991
+ - refresh `about.proposal_generator`, `about.skeleton_prompt`, and `about.sample_prompts` when the template's prompting strategy or supported use cases change
992
+
993
+ ## Typical Template Patterns
994
+
995
+ When a developer says "use typical template patterns", interpret that as the default template-authoring contract below unless the template has a strong reason to differ.
996
+
997
+ Authoring defaults:
998
+
999
+ - when creating a new template, automatically write `about.proposal_generator`, `about.skeleton_prompt`, `about.sample_prompts`, and the template-local `SKILL.md`
1000
+ - the template-local `SKILL.md` should explain the template's operations, expected payloads, sample requests, provider caveats, and any format-specific guidance future agents need
1001
+ - if the template intentionally does not follow one of these patterns, call that out explicitly in the template-local `SKILL.md`
1002
+
1003
+ Asset-input defaults:
1004
+
1005
+ - image-generating or slide-generating operations should usually accept either an AI image prompt or an exact image source supplied by the director
1006
+ - video-aware operations should usually accept either an AI video prompt or an exact video source supplied by the director when the format benefits from source footage
1007
+ - exact media sources should accept either direct URLs or raw prompt text in the same high-level input family when practical
1008
+ - URL detection should be robust enough to handle normal query strings and signed URLs; do not assume a media URL has a clean extension with no params
1009
+ - media-type detection should prefer explicit user fields first, then MIME type or fetch metadata when available, then conservative URL/path heuristics as a fallback
1010
+ - if a template supports file uploads or attachment arrays, document whether it expects a single asset, multiple assets, or either
1011
+
1012
+ Operation-pattern defaults:
1013
+
1014
+ - for most image-generation or slide-generation capabilities, provide two operations or two clearly documented modes of one operation
1015
+ - one mode should be an explicit director-controlled path where the caller can provide exact copy, exact media, or exact slide instructions
1016
+ - one mode should be a full-auto AI path where the caller provides a higher-level prompt or brief and the template decides the detailed text, imagery, and slide plan
1017
+ - name these modes clearly in the template-local `SKILL.md` so future agents and developers can tell which route is deterministic versus generative
1018
+
1019
+ Slideshow-to-video defaults:
1020
+
1021
+ - any operation that turns slideshow media into a video should, by default, accept `[{ media_url: string, duration_ms: number }]`
1022
+ - `media_url` may point to either an image or a video, and the slideshow renderer should handle both
1023
+ - when video clips are supplied in slideshow media, preserve the clip visually for the requested slot duration using a documented strategy such as trim, loop, freeze-last-frame, or fit-to-slot
1024
+ - when the template needs richer control than this default shape, extend it rather than replacing it with an unrelated format
1025
+
1026
+ Remotion arbitrary-slide default:
1027
+
1028
+ - include an arbitrary slide operation when it fits the template family, backed by Remotion rendering
1029
+ - that operation should accept either an AI image prompt or custom HTML as the slide source
1030
+ - the intended use is arbitrary inserts such as outro call-to-action slides, sponsor cards, transitions, or other one-off slides that do not need a dedicated template-specific generator
1031
+ - if custom HTML is accepted, document the styling, sanitization, and asset-loading constraints in the template-local `SKILL.md`
1032
+
1033
+ Recommended input-shape convention:
1034
+
1035
+ ```ts
1036
+ const TYPICAL_MEDIA_SOURCE = z.object({
1037
+ media_url: z.string().url().optional(),
1038
+ image_url: z.string().url().optional(),
1039
+ video_url: z.string().url().optional(),
1040
+ image_prompt: z.string().optional(),
1041
+ video_prompt: z.string().optional(),
1042
+ html: z.string().optional(),
1043
+ duration_ms: z.number().int().positive().optional()
1044
+ });
1045
+ ```
1046
+
1047
+ Notes:
1048
+
1049
+ - templates may expose clearer, narrower schemas than this when that improves usability
1050
+ - prefer explicit fields like `image_prompt`, `image_url`, `video_prompt`, and `video_url` over guessing from one overloaded string when designing a new schema
1051
+ - if you still accept a single overloaded field for convenience, document the precedence rules clearly
656
1052
 
657
1053
  ## Provider Rules
658
1054
 
@@ -660,12 +1056,19 @@ Templates should use the provider abstractions already available on `ctx.provide
660
1056
 
661
1057
  Rules:
662
1058
 
1059
+ - templates do not need to support all of `openai`, `gemini`, and `openrouter`; supporting at least one real provider path is usually enough unless the template explicitly promises broader portability
663
1060
  - use the configured provider path instead of hardcoding one provider everywhere
664
1061
  - let templates work with whichever supported provider key the developer actually has
665
1062
  - keep prompts and model choices configurable when useful
666
1063
  - use image attachments when the format depends on source references
667
1064
  - avoid requiring multiple provider accounts unless the template genuinely needs them
668
1065
 
1066
+ Recommended defaults when a template supports these providers:
1067
+
1068
+ - `openai`: `gpt-5.4` for `text` and `layout_analysis`, `gpt-image-1` for `image`, `sora-2` for `video`, `gpt-4o-mini-tts-2025-12-15` for `tts`, `gpt-4o-mini-transcribe-2025-12-15` for `stt`
1069
+ - `gemini`: `gemini-3.1-flash-lite` for `text` and `layout_analysis`, `gemini-3.1-flash-image-preview` for `image`, `veo-3.0-generate-001` for `video`, `gemini-3.1-flash-tts-preview` for `tts`, `gemini-3.1-flash-lite-preview` for `stt`
1070
+ - `openrouter`: `qwen/qwen3.6-flash` for `text` and `layout_analysis`, `google/gemini-3.1-flash-image-preview` as the recommended paid `image` default where runtime support exists, `google/gemini-3.1-flash-tts-preview` with PCM for `tts`, `openai/gpt-4o-mini-transcribe` for `stt`
1071
+
669
1072
  Important distinction:
670
1073
 
671
1074
  - runtime template generation can use OpenAI, OpenRouter, Gemini, or Perplexity according to template logic
@@ -692,6 +1095,12 @@ Rules:
692
1095
  - prefer `putJson`, `putText`, `putBuffer`, and `getPublicUrl`
693
1096
  - do not scatter files across arbitrary top-level prefixes
694
1097
 
1098
+ Hosted preview-media rule for developers:
1099
+
1100
+ - if an agent uploads preview media with `presign-preview-media`, the resulting hosted `about.preview_media` entry should be the returned absolute `developer/<user_id>/*` URL
1101
+ - only use `templates/:template_id/about/*` in `about.preview_media` when that object already exists there, typically after platform import/activation sync or another platform-managed copy step
1102
+ - a repo-local file such as `about/preview-01.png` is fine for source control and for platform sync, but it is not by itself an immediately valid hosted catalog URL
1103
+
695
1104
  The runtime may back these writes with local filesystem storage or S3 depending on environment. The template should not care.
696
1105
 
697
1106
  ## API Usage
@@ -719,6 +1128,8 @@ After changes, validate with as many of these as apply:
719
1128
  7. poll the job and fetch logs
720
1129
  8. inspect produced artifacts
721
1130
 
1131
+ If you need several runs, submit them in a reasonable loop and poll the returned job IDs. Rely on Vidfarm's native queueing instead of adding bespoke batch scheduling or coordination logic.
1132
+
722
1133
  If you changed slideshow, overlay, or video output behavior, also validate:
723
1134
 
724
1135
  1. output images are the expected aspect ratio