@mevdragon/vidfarm-devcli 0.2.13 → 0.3.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.
Files changed (200) hide show
  1. package/README.md +11 -4
  2. package/SKILL.director.md +97 -0
  3. package/SKILL.platform.md +66 -6
  4. package/dist/src/cli.js +137 -1524
  5. package/dist/src/dev-serve.js +169 -0
  6. package/package.json +5 -24
  7. package/.env.example +0 -60
  8. package/auto-create-hyperframe-templates/AUTO_CREATE_HYPERFRAME_TEMPLATES.md +0 -275
  9. package/auto-create-hyperframe-templates/extractor-system-prompt.md +0 -128
  10. package/auto-create-hyperframe-templates/input-manifest.schema.json +0 -56
  11. package/auto-create-hyperframe-templates/lambda-memory-estimator.md +0 -118
  12. package/auto-create-hyperframe-templates/production-graph.schema.json +0 -314
  13. package/auto-create-hyperframe-templates/runbook.md +0 -198
  14. package/auto-create-hyperframe-templates/scripts/create-hyperframe-template.mjs +0 -368
  15. package/auto-create-hyperframe-templates/template-plan.schema.json +0 -311
  16. package/auto-create-hyperframe-templates/template-planner-prompt.md +0 -144
  17. package/auto-create-templates/AUTO_CREATE_TEMPLATES.md +0 -599
  18. package/auto-create-templates/extractor-system-prompt.md +0 -119
  19. package/auto-create-templates/production-graph.schema.json +0 -276
  20. package/auto-create-templates/runbook.md +0 -140
  21. package/auto-create-templates/template-plan.schema.json +0 -301
  22. package/auto-create-templates/template-planner-prompt.md +0 -137
  23. package/dist/src/account-pages-legacy.js +0 -9336
  24. package/dist/src/account-pages-legacy.js.map +0 -1
  25. package/dist/src/account-pages.js +0 -61
  26. package/dist/src/account-pages.js.map +0 -1
  27. package/dist/src/app.js +0 -14023
  28. package/dist/src/app.js.map +0 -1
  29. package/dist/src/cli.js.map +0 -1
  30. package/dist/src/composition-runtime.js +0 -581
  31. package/dist/src/composition-runtime.js.map +0 -1
  32. package/dist/src/config.js +0 -140
  33. package/dist/src/config.js.map +0 -1
  34. package/dist/src/context.js +0 -492
  35. package/dist/src/context.js.map +0 -1
  36. package/dist/src/dev-app-legacy.js +0 -694
  37. package/dist/src/dev-app-legacy.js.map +0 -1
  38. package/dist/src/dev-app.js +0 -6
  39. package/dist/src/dev-app.js.map +0 -1
  40. package/dist/src/domain.js +0 -2
  41. package/dist/src/domain.js.map +0 -1
  42. package/dist/src/editor-chat-history.js +0 -82
  43. package/dist/src/editor-chat-history.js.map +0 -1
  44. package/dist/src/editor-chat.js +0 -311
  45. package/dist/src/editor-chat.js.map +0 -1
  46. package/dist/src/frontend/flockposter-cache-store.js +0 -124
  47. package/dist/src/frontend/flockposter-cache-store.js.map +0 -1
  48. package/dist/src/frontend/homepage-client.js +0 -117
  49. package/dist/src/frontend/homepage-client.js.map +0 -1
  50. package/dist/src/frontend/homepage-shared.js +0 -4
  51. package/dist/src/frontend/homepage-shared.js.map +0 -1
  52. package/dist/src/frontend/homepage-store.js +0 -28
  53. package/dist/src/frontend/homepage-store.js.map +0 -1
  54. package/dist/src/frontend/homepage-view.js +0 -260
  55. package/dist/src/frontend/homepage-view.js.map +0 -1
  56. package/dist/src/frontend/page-runtime-client.js +0 -103
  57. package/dist/src/frontend/page-runtime-client.js.map +0 -1
  58. package/dist/src/frontend/page-runtime-store.js +0 -9
  59. package/dist/src/frontend/page-runtime-store.js.map +0 -1
  60. package/dist/src/frontend/sentry.js +0 -42
  61. package/dist/src/frontend/sentry.js.map +0 -1
  62. package/dist/src/frontend/template-editor-chat.js +0 -3767
  63. package/dist/src/frontend/template-editor-chat.js.map +0 -1
  64. package/dist/src/help-page.js +0 -333
  65. package/dist/src/help-page.js.map +0 -1
  66. package/dist/src/homepage.js +0 -919
  67. package/dist/src/homepage.js.map +0 -1
  68. package/dist/src/hyperframes/composition.js +0 -180
  69. package/dist/src/hyperframes/composition.js.map +0 -1
  70. package/dist/src/index.js +0 -16
  71. package/dist/src/index.js.map +0 -1
  72. package/dist/src/instrument.js +0 -30
  73. package/dist/src/instrument.js.map +0 -1
  74. package/dist/src/lib/crypto.js +0 -45
  75. package/dist/src/lib/crypto.js.map +0 -1
  76. package/dist/src/lib/dev-log.js +0 -54
  77. package/dist/src/lib/dev-log.js.map +0 -1
  78. package/dist/src/lib/display-name.js +0 -11
  79. package/dist/src/lib/display-name.js.map +0 -1
  80. package/dist/src/lib/ids.js +0 -24
  81. package/dist/src/lib/ids.js.map +0 -1
  82. package/dist/src/lib/images.js +0 -19
  83. package/dist/src/lib/images.js.map +0 -1
  84. package/dist/src/lib/json.js +0 -15
  85. package/dist/src/lib/json.js.map +0 -1
  86. package/dist/src/lib/template-dna.js +0 -543
  87. package/dist/src/lib/template-dna.js.map +0 -1
  88. package/dist/src/lib/template-paths.js +0 -28
  89. package/dist/src/lib/template-paths.js.map +0 -1
  90. package/dist/src/lib/template-style-options.js +0 -203
  91. package/dist/src/lib/template-style-options.js.map +0 -1
  92. package/dist/src/lib/time.js +0 -7
  93. package/dist/src/lib/time.js.map +0 -1
  94. package/dist/src/lib/video-quality-harness.js +0 -60
  95. package/dist/src/lib/video-quality-harness.js.map +0 -1
  96. package/dist/src/page-runtime.js +0 -2
  97. package/dist/src/page-runtime.js.map +0 -1
  98. package/dist/src/page-shell.js +0 -2393
  99. package/dist/src/page-shell.js.map +0 -1
  100. package/dist/src/primitive-context.js +0 -299
  101. package/dist/src/primitive-context.js.map +0 -1
  102. package/dist/src/primitive-registry.js +0 -2181
  103. package/dist/src/primitive-registry.js.map +0 -1
  104. package/dist/src/primitive-sdk.js +0 -4
  105. package/dist/src/primitive-sdk.js.map +0 -1
  106. package/dist/src/primitives/remotion/html-image.js +0 -30
  107. package/dist/src/primitives/remotion/html-image.js.map +0 -1
  108. package/dist/src/primitives/remotion/media-slideshow.js +0 -60
  109. package/dist/src/primitives/remotion/media-slideshow.js.map +0 -1
  110. package/dist/src/react-page-shell.js +0 -35
  111. package/dist/src/react-page-shell.js.map +0 -1
  112. package/dist/src/ready-post-schedule-component.js +0 -1515
  113. package/dist/src/ready-post-schedule-component.js.map +0 -1
  114. package/dist/src/registry.js +0 -296
  115. package/dist/src/registry.js.map +0 -1
  116. package/dist/src/runtime.js +0 -31
  117. package/dist/src/runtime.js.map +0 -1
  118. package/dist/src/services/api-call-history.js +0 -249
  119. package/dist/src/services/api-call-history.js.map +0 -1
  120. package/dist/src/services/auth.js +0 -152
  121. package/dist/src/services/auth.js.map +0 -1
  122. package/dist/src/services/billing.js +0 -231
  123. package/dist/src/services/billing.js.map +0 -1
  124. package/dist/src/services/chat-threads.js +0 -92
  125. package/dist/src/services/chat-threads.js.map +0 -1
  126. package/dist/src/services/fork-access.js +0 -94
  127. package/dist/src/services/fork-access.js.map +0 -1
  128. package/dist/src/services/ghostcut.js +0 -132
  129. package/dist/src/services/ghostcut.js.map +0 -1
  130. package/dist/src/services/hyperframes.js +0 -1014
  131. package/dist/src/services/hyperframes.js.map +0 -1
  132. package/dist/src/services/job-capacity.js +0 -14
  133. package/dist/src/services/job-capacity.js.map +0 -1
  134. package/dist/src/services/job-logs.js +0 -197
  135. package/dist/src/services/job-logs.js.map +0 -1
  136. package/dist/src/services/jobs.js +0 -136
  137. package/dist/src/services/jobs.js.map +0 -1
  138. package/dist/src/services/media-processing.js +0 -743
  139. package/dist/src/services/media-processing.js.map +0 -1
  140. package/dist/src/services/primitive-media-lambda.js +0 -280
  141. package/dist/src/services/primitive-media-lambda.js.map +0 -1
  142. package/dist/src/services/providers.js +0 -2870
  143. package/dist/src/services/providers.js.map +0 -1
  144. package/dist/src/services/rate-limits.js +0 -237
  145. package/dist/src/services/rate-limits.js.map +0 -1
  146. package/dist/src/services/remotion.js +0 -688
  147. package/dist/src/services/remotion.js.map +0 -1
  148. package/dist/src/services/serverless-auth.js +0 -374
  149. package/dist/src/services/serverless-auth.js.map +0 -1
  150. package/dist/src/services/serverless-jobs.js +0 -1074
  151. package/dist/src/services/serverless-jobs.js.map +0 -1
  152. package/dist/src/services/serverless-provider-keys.js +0 -401
  153. package/dist/src/services/serverless-provider-keys.js.map +0 -1
  154. package/dist/src/services/serverless-records.js +0 -1086
  155. package/dist/src/services/serverless-records.js.map +0 -1
  156. package/dist/src/services/serverless-template-configs.js +0 -67
  157. package/dist/src/services/serverless-template-configs.js.map +0 -1
  158. package/dist/src/services/storage.js +0 -382
  159. package/dist/src/services/storage.js.map +0 -1
  160. package/dist/src/services/template-certification.js +0 -475
  161. package/dist/src/services/template-certification.js.map +0 -1
  162. package/dist/src/services/template-loader.js +0 -99
  163. package/dist/src/services/template-loader.js.map +0 -1
  164. package/dist/src/services/template-runtime-bundles.js +0 -217
  165. package/dist/src/services/template-runtime-bundles.js.map +0 -1
  166. package/dist/src/services/template-sources.js +0 -1017
  167. package/dist/src/services/template-sources.js.map +0 -1
  168. package/dist/src/services/video-normalization.js +0 -2
  169. package/dist/src/services/video-normalization.js.map +0 -1
  170. package/dist/src/services/webhooks.js +0 -62
  171. package/dist/src/services/webhooks.js.map +0 -1
  172. package/dist/src/template-editor-pages.js +0 -6624
  173. package/dist/src/template-editor-pages.js.map +0 -1
  174. package/dist/src/template-editor-shell.js +0 -2713
  175. package/dist/src/template-editor-shell.js.map +0 -1
  176. package/dist/src/template-sdk.js +0 -4
  177. package/dist/src/template-sdk.js.map +0 -1
  178. package/dist/src/worker.js +0 -17
  179. package/dist/src/worker.js.map +0 -1
  180. package/public/assets/homepage-app.js +0 -54
  181. package/public/assets/homepage-client-app.js +0 -80
  182. package/public/assets/page-runtime-client-app.js +0 -94
  183. package/readme.secret.md +0 -89
  184. package/templates/vidfarm_template_0000/README.md +0 -106
  185. package/templates/vidfarm_template_0000/SKILL.md +0 -266
  186. package/templates/vidfarm_template_0000/assets/Abel-Regular.ttf +0 -0
  187. package/templates/vidfarm_template_0000/assets/DMSerifDisplay-Regular.ttf +0 -0
  188. package/templates/vidfarm_template_0000/assets/Montserrat[wght].ttf +0 -0
  189. package/templates/vidfarm_template_0000/assets/SourceCodePro[wght].ttf +0 -0
  190. package/templates/vidfarm_template_0000/assets/TikTokSans-SemiBold.ttf +0 -0
  191. package/templates/vidfarm_template_0000/assets/Yesteryear-Regular.ttf +0 -0
  192. package/templates/vidfarm_template_0000/composition.json +0 -11
  193. package/templates/vidfarm_template_0000/src/lib/images.js +0 -221
  194. package/templates/vidfarm_template_0000/src/remotion/Root.js +0 -33
  195. package/templates/vidfarm_template_0000/src/remotion/index.js +0 -3
  196. package/templates/vidfarm_template_0000/src/sdk.js +0 -3
  197. package/templates/vidfarm_template_0000/src/style-options.js +0 -200
  198. package/templates/vidfarm_template_0000/src/template-dna.js +0 -9
  199. package/templates/vidfarm_template_0000/src/template.js +0 -1566
  200. package/templates/vidfarm_template_0000/template.config.json +0 -21
@@ -0,0 +1,169 @@
1
+ import { createServer } from "node:http";
2
+ import { existsSync, mkdirSync, readFileSync, watch, writeFileSync } from "node:fs";
3
+ import path from "node:path";
4
+ import { parseArgs } from "node:util";
5
+ // vidfarm dev-serve — a tiny HTTP layer that lets the browser editor point at
6
+ // a local directory of composition files instead of the deployed API. The
7
+ // editor detects dev mode from `?dev=<url>` (or localStorage) and rewrites
8
+ // its fork API calls to hit this server. File changes fan out via SSE so the
9
+ // editor can reload the composition on save-from-disk (e.g. Claude Code
10
+ // edits the file directly).
11
+ const CORS_HEADERS = {
12
+ "access-control-allow-origin": "*",
13
+ "access-control-allow-methods": "GET,PUT,PATCH,POST,OPTIONS",
14
+ "access-control-allow-headers": "content-type,authorization",
15
+ "access-control-max-age": "600"
16
+ };
17
+ export async function runDevServeCommand(argv) {
18
+ const parsed = parseArgs({
19
+ args: argv,
20
+ options: {
21
+ dir: { type: "string", default: "." },
22
+ port: { type: "string", default: "4321" }
23
+ }
24
+ });
25
+ const rootDir = path.resolve(process.cwd(), parsed.values.dir);
26
+ const port = Number(parsed.values.port);
27
+ if (!existsSync(rootDir)) {
28
+ mkdirSync(rootDir, { recursive: true });
29
+ }
30
+ let nextClientId = 1;
31
+ const clients = new Set();
32
+ function broadcast(event, data) {
33
+ const payload = `event: ${event}\ndata: ${JSON.stringify(data)}\n\n`;
34
+ for (const client of clients) {
35
+ try {
36
+ client.res.write(payload);
37
+ }
38
+ catch {
39
+ clients.delete(client);
40
+ }
41
+ }
42
+ }
43
+ // fs.watch fires on any child change. Coalesce bursts so a single save
44
+ // doesn't spam the editor with 3 reload events.
45
+ let reloadTimer = null;
46
+ const scheduleReload = (filename) => {
47
+ if (reloadTimer)
48
+ clearTimeout(reloadTimer);
49
+ reloadTimer = setTimeout(() => {
50
+ reloadTimer = null;
51
+ broadcast("reload", { file: filename, at: Date.now() });
52
+ console.log(`[dev-serve] reload → ${filename ?? "(unknown)"}`);
53
+ }, 80);
54
+ };
55
+ try {
56
+ watch(rootDir, { recursive: true }, (_type, filename) => {
57
+ scheduleReload(filename ?? null);
58
+ });
59
+ }
60
+ catch (error) {
61
+ console.warn(`[dev-serve] watch failed: ${error instanceof Error ? error.message : String(error)}`);
62
+ }
63
+ const server = createServer((req, res) => handleRequest(req, res, rootDir, clients, nextClientId++));
64
+ server.listen(port, () => {
65
+ console.log(`[dev-serve] serving ${rootDir}`);
66
+ console.log(`[dev-serve] listening on http://localhost:${port}`);
67
+ console.log(`[dev-serve] editor: open with ?dev=${encodeURIComponent(`http://localhost:${port}`)}`);
68
+ });
69
+ process.on("SIGINT", () => {
70
+ console.log("\n[dev-serve] shutting down");
71
+ server.close(() => process.exit(0));
72
+ });
73
+ }
74
+ function handleRequest(req, res, rootDir, clients, clientId) {
75
+ const method = (req.method ?? "GET").toUpperCase();
76
+ const url = new URL(req.url ?? "/", `http://localhost`);
77
+ const pathname = url.pathname;
78
+ if (method === "OPTIONS") {
79
+ res.writeHead(204, CORS_HEADERS);
80
+ res.end();
81
+ return;
82
+ }
83
+ if (pathname === "/_events" && method === "GET") {
84
+ res.writeHead(200, {
85
+ ...CORS_HEADERS,
86
+ "content-type": "text/event-stream",
87
+ "cache-control": "no-cache",
88
+ connection: "keep-alive"
89
+ });
90
+ res.write(`event: hello\ndata: ${JSON.stringify({ at: Date.now() })}\n\n`);
91
+ const client = { res, id: clientId };
92
+ clients.add(client);
93
+ req.on("close", () => clients.delete(client));
94
+ return;
95
+ }
96
+ const filePath = resolveFilePath(rootDir, pathname);
97
+ if (!filePath) {
98
+ respondJson(res, 404, { ok: false, error: `Not found: ${pathname}` });
99
+ return;
100
+ }
101
+ if (method === "GET") {
102
+ if (!existsSync(filePath)) {
103
+ respondJson(res, 404, { ok: false, error: `Missing ${path.basename(filePath)}` });
104
+ return;
105
+ }
106
+ const body = readFileSync(filePath);
107
+ const contentType = pathname.endsWith(".html") ? "text/html; charset=utf-8" : "application/json";
108
+ res.writeHead(200, { ...CORS_HEADERS, "content-type": contentType });
109
+ res.end(body);
110
+ return;
111
+ }
112
+ if (method === "PUT" && pathname.endsWith("/composition.html")) {
113
+ readBody(req).then((body) => {
114
+ const html = body.toString("utf8");
115
+ if (!html.includes("data-composition-id=")) {
116
+ respondJson(res, 400, { ok: false, error: "Composition HTML is missing data-composition-id" });
117
+ return;
118
+ }
119
+ mkdirSync(path.dirname(filePath), { recursive: true });
120
+ writeFileSync(filePath, html, "utf8");
121
+ respondJson(res, 200, { ok: true, bytes: html.length });
122
+ }).catch((error) => respondJson(res, 500, { ok: false, error: String(error) }));
123
+ return;
124
+ }
125
+ if (method === "PATCH" && pathname.endsWith("/composition.json")) {
126
+ readBody(req).then((body) => {
127
+ const patch = JSON.parse(body.toString("utf8") || "{}");
128
+ const existing = existsSync(filePath) ? JSON.parse(readFileSync(filePath, "utf8") || "{}") : {};
129
+ const merged = { ...existing, ...patch };
130
+ mkdirSync(path.dirname(filePath), { recursive: true });
131
+ writeFileSync(filePath, JSON.stringify(merged, null, 2), "utf8");
132
+ respondJson(res, 200, merged);
133
+ }).catch((error) => respondJson(res, 500, { ok: false, error: String(error) }));
134
+ return;
135
+ }
136
+ respondJson(res, 405, { ok: false, error: `Method ${method} not allowed on ${pathname}` });
137
+ }
138
+ // Restrict served paths to the working/version composition files. Anything
139
+ // else 404s so this server isn't a random static host.
140
+ function resolveFilePath(rootDir, pathname) {
141
+ const clean = pathname.replace(/^\/+/, "");
142
+ const parts = clean.split("/").filter(Boolean);
143
+ if (parts.length === 0)
144
+ return null;
145
+ const filename = parts[parts.length - 1];
146
+ const allowed = ["composition.html", "composition.json", "manifest.json"];
147
+ if (!allowed.includes(filename))
148
+ return null;
149
+ // Allow: `composition.html`, `versions/1/composition.html`.
150
+ if (parts.length === 1)
151
+ return path.join(rootDir, filename);
152
+ if (parts.length === 3 && parts[0] === "versions" && /^\d+$/.test(parts[1])) {
153
+ return path.join(rootDir, "versions", parts[1], filename);
154
+ }
155
+ return null;
156
+ }
157
+ function respondJson(res, status, body) {
158
+ res.writeHead(status, { ...CORS_HEADERS, "content-type": "application/json" });
159
+ res.end(JSON.stringify(body));
160
+ }
161
+ function readBody(req) {
162
+ return new Promise((resolve, reject) => {
163
+ const chunks = [];
164
+ req.on("data", (chunk) => chunks.push(chunk));
165
+ req.on("end", () => resolve(Buffer.concat(chunks)));
166
+ req.on("error", reject);
167
+ });
168
+ }
169
+ //# sourceMappingURL=dev-serve.js.map
package/package.json CHANGED
@@ -1,37 +1,18 @@
1
1
  {
2
2
  "name": "@mevdragon/vidfarm-devcli",
3
- "version": "0.2.13",
4
- "description": "DEPRECATED. Built for the old REST-API Vidfarm template model. Superseded by the browser-based Trackpad Editor at https://vidfarm.cc/editor/. No longer maintained.",
5
- "deprecated": "This CLI targeted the old REST-API template paradigm. Vidfarm now uses the Trackpad Editor (composition-based editing in the browser). See SKILL.platform.md.",
3
+ "version": "0.3.0",
4
+ "description": "Local bridge for the Vidfarm Trackpad Editor. Point it at a template id, edit composition.html on disk (Claude Code, Codex, etc.), preview live in the browser at https://vidfarm.cc/editor/.",
6
5
  "type": "module",
7
6
  "bin": {
8
7
  "vidfarm": "dist/src/cli.js",
9
8
  "vidfarm-devcli": "dist/src/cli.js"
10
9
  },
11
10
  "files": [
12
- "dist/src",
13
- "public/assets",
14
- "auto-create-templates/AUTO_CREATE_TEMPLATES.md",
15
- "auto-create-templates/extractor-system-prompt.md",
16
- "auto-create-templates/production-graph.schema.json",
17
- "auto-create-templates/runbook.md",
18
- "auto-create-templates/template-plan.schema.json",
19
- "auto-create-templates/template-planner-prompt.md",
20
- "auto-create-hyperframe-templates/AUTO_CREATE_HYPERFRAME_TEMPLATES.md",
21
- "auto-create-hyperframe-templates/extractor-system-prompt.md",
22
- "auto-create-hyperframe-templates/input-manifest.schema.json",
23
- "auto-create-hyperframe-templates/lambda-memory-estimator.md",
24
- "auto-create-hyperframe-templates/production-graph.schema.json",
25
- "auto-create-hyperframe-templates/runbook.md",
26
- "auto-create-hyperframe-templates/scripts/create-hyperframe-template.mjs",
27
- "auto-create-hyperframe-templates/template-plan.schema.json",
28
- "auto-create-hyperframe-templates/template-planner-prompt.md",
29
- "dist/templates/vidfarm_template_0000",
30
- "templates/vidfarm_template_0000",
11
+ "dist/src/cli.js",
12
+ "dist/src/dev-serve.js",
31
13
  "README.md",
32
14
  "SKILL.director.md",
33
15
  "SKILL.platform.md",
34
- ".env.example",
35
16
  "!readme.secret.md"
36
17
  ],
37
18
  "publishConfig": {
@@ -47,7 +28,7 @@
47
28
  "scripts": {
48
29
  "dev": "tsx --import ./src/instrument.ts watch src/index.ts",
49
30
  "dev:frontend": "node scripts/build-homepage-client.mjs --watch",
50
- "dev:cli": "tsx src/cli.ts dev",
31
+ "dev:cli": "tsx src/cli.ts --help",
51
32
  "build:frontend": "node scripts/build-homepage-client.mjs",
52
33
  "build:hyperframes-editor": "cd demo && node scripts/build.mjs",
53
34
  "operator:template-artifact": "node scripts/platform-operator-template-artifact.mjs",
package/.env.example DELETED
@@ -1,60 +0,0 @@
1
- NODE_ENV="development"
2
- PORT="3000"
3
- MOCK_PROVIDER_RESPONSES="false"
4
- MAX_ACTIVE_JOBS_PER_CUSTOMER="30"
5
- PROVIDER_LEASE_INLINE_WAIT_SECONDS="5"
6
- PROVIDER_LEASE_STEP_WAIT_SECONDS="60"
7
- PROVIDER_LEASE_MAX_STEP_WAIT_SECONDS="43200"
8
- MAX_JOB_WALL_CLOCK_SECONDS="86400"
9
-
10
- OPENAI_API_KEY=""
11
- OPENROUTER_API_KEY=""
12
- GEMINI_API_KEY=""
13
- PERPLEXITY_API_KEY=""
14
- GHOSTCUT_KEY=""
15
- GHOSTCUT_SECRET=""
16
-
17
- # Optional. Production CDK wires these automatically. Browser-facing Lambda calls still callback to PUBLIC_BASE_URL for auth.
18
- VIDFARM_ZIP_LAMBDA_URL=""
19
- VIDFARM_ZIP_LAMBDA_SECRET=""
20
- VIDFARM_BILLING_URL=""
21
- VIDFARM_BILLING_SECRET=""
22
- VIDFARM_RATE_LIMITS_TABLE_NAME=""
23
- # Optional production CDK overrides. Leave empty to use deterministic per-account/per-region names.
24
- VIDFARM_STORAGE_S3_BUCKET_NAME=""
25
-
26
- # Optional when calling a hosted Vidfarm API directly.
27
- VIDFARM_USER_ID=""
28
- VIDFARM_API_KEY=""
29
- # Optional director override for production debugging. Send as x-superagency-key.
30
- SUPERAGENCY_KEY=""
31
-
32
- # Optional local overrides. The CLI will choose sensible local defaults.
33
- PUBLIC_BASE_URL="http://localhost:3310"
34
- # Optional public browser-facing chat endpoint. Leave empty locally unless you want the UI to hit a separate chat host directly.
35
- PUBLIC_EDITOR_CHAT_URL=""
36
-
37
- # Optional Sentry setup. SENTRY_DSN powers the Hono Node backend.
38
- # SENTRY_LAMBDA_DSN powers the CDK-managed AWS Lambdas.
39
- # PUBLIC_SENTRY_DSN powers the browser React bundles and may be the same DSN or a separate browser project DSN.
40
- SENTRY_DSN=""
41
- SENTRY_ENVIRONMENT="development"
42
- SENTRY_RELEASE=""
43
- SENTRY_TRACES_SAMPLE_RATE=""
44
- SENTRY_ENABLE_LOGS="true"
45
- SENTRY_SEND_DEFAULT_PII="false"
46
- SENTRY_DEBUG_ROUTE="false"
47
- SENTRY_LAMBDA_DSN=""
48
- SENTRY_LAMBDA_TRACES_SAMPLE_RATE="1.0"
49
- PUBLIC_SENTRY_DSN=""
50
- PUBLIC_SENTRY_TRACES_SAMPLE_RATE=""
51
- PUBLIC_SENTRY_REPLAYS_SESSION_SAMPLE_RATE=""
52
- PUBLIC_SENTRY_REPLAYS_ON_ERROR_SAMPLE_RATE=""
53
- PUBLIC_SENTRY_ENABLE_LOGS="true"
54
- PUBLIC_SENTRY_SEND_DEFAULT_PII="true"
55
- PUBLIC_SENTRY_TRACE_PROPAGATION_TARGETS=""
56
- REMOTION_MODE="local"
57
-
58
-
59
- GHOSTCUT_KEY="_________"
60
- GHOSTCUT_SECRET="_________"
@@ -1,275 +0,0 @@
1
- # Auto-Create HyperFrame Templates Harness
2
-
3
- This harness turns a simple MP4, image, or PNG/JPG/WebP slideshow into an editable HyperFrames composition that can be rendered through the production AWS Lambda stack.
4
-
5
- Use this when the desired output is not a Vidfarm operation package, but a decomposed HyperFrames project:
6
-
7
- ```txt
8
- drafts/<format_slug>/
9
- source.md
10
- preview/
11
- source.mp4
12
- composition.html
13
- composition.json
14
- lambda-site.json
15
- ```
16
-
17
- The goal is to make the source editable in the HyperFrames editor while keeping publish behavior faithful. If a user deletes a source video scene, the final render must show a blank/background gap unless another timed layer covers that range. Do not rely on an always-on source video for publish output.
18
-
19
- ## Start Here
20
-
21
- Give a Codex agent these two things:
22
-
23
- 1. this entry file: `auto-create-hyperframe-templates/AUTO_CREATE_HYPERFRAME_TEMPLATES.md`
24
- 2. one source media folder, preferably shaped like:
25
-
26
- ```txt
27
- drafts/<format_slug>/
28
- source.md
29
- preview/
30
- source.mp4
31
- slide-01.png
32
- slide-02.png
33
- ```
34
-
35
- Then ask:
36
-
37
- ```txt
38
- Use auto-create-hyperframe-templates/AUTO_CREATE_HYPERFRAME_TEMPLATES.md as the harness. Analyze drafts/<format_slug>/, create the run artifacts, generate the HyperFrames production graph and template plan, then write composition.html, composition.json, and lambda-site.json.
39
- ```
40
-
41
- For the current local bridge, you can run:
42
-
43
- ```bash
44
- node auto-create-hyperframe-templates/scripts/create-hyperframe-template.mjs drafts/<format_slug>/preview/source.mp4
45
- ```
46
-
47
- For a slideshow, pass the folder containing the images:
48
-
49
- ```bash
50
- node auto-create-hyperframe-templates/scripts/create-hyperframe-template.mjs drafts/<format_slug>/preview
51
- ```
52
-
53
- Add `--stage-site` when you want the script to call the production HyperFrames Lambda site upload after writing the local artifacts.
54
-
55
- The source can be:
56
-
57
- - one MP4
58
- - a folder of PNG/JPG/WebP slides
59
- - a mixed folder with source video, screenshots, overlay images, audio, and notes
60
-
61
- If `source.md` is missing, create it with the source URL, adaptation goal, expected audience, and any constraints that can be inferred from the files.
62
-
63
- For programmatic runs, write an input manifest matching `input-manifest.schema.json`:
64
-
65
- ```json
66
- {
67
- "mode": "autocreate-hyperframe-template",
68
- "input_path": "drafts/my-format/preview/source.mp4",
69
- "output_path": "drafts/my-format",
70
- "slug_id": "my-format",
71
- "source_mode": "auto",
72
- "render_defaults": {
73
- "width": 720,
74
- "height": 1280,
75
- "fps": 30
76
- },
77
- "lambda": {
78
- "stack_name": "hyperframes-vidfarm-prod",
79
- "region": "us-east-1",
80
- "memory_strategy": "estimate"
81
- },
82
- "publish": {
83
- "prestage_site": false,
84
- "output_url_policy": "signed_https_final_output_only"
85
- }
86
- }
87
- ```
88
-
89
- ## Output Contract
90
-
91
- Every successful run should produce:
92
-
93
- - `composition.html`: a self-contained HyperFrames composition using deterministic HTML/CSS and timed media elements.
94
- - `composition.json`: the editable editor manifest: source assets, scene cuts, layers, caption geometry, viral/visual DNA, and Lambda estimate.
95
- - `lambda-site.json`: the production Lambda site/render metadata: stack, region, memory estimate, site id if pre-staged, and render defaults.
96
- - optional `frames/contact-sheet.jpg`, `source/ffprobe.json`, `transcripts/stt.json`, `ocr/frame_text.json`, and `motion/scene-cuts.json`.
97
-
98
- The `composition.json` should follow `template-plan.schema.json` after planning. The lower-level extraction artifact should follow `production-graph.schema.json`.
99
-
100
- ## Core Principle
101
-
102
- HyperFrames is the editor and deterministic renderer. The harness should decompose the source into layers that remain individually editable:
103
-
104
- - source video scene clips
105
- - source audio
106
- - images or slide frames
107
- - deterministic captions
108
- - deterministic HTML overlays
109
- - shapes, chips, arrows, circles, masks, UI shells, and stickers
110
- - generated assets only when the visual cannot be rebuilt deterministically
111
-
112
- Important readable text should not be baked into generated media unless the source format is explicitly poster/artifact-native and OCR validation is part of the quality harness.
113
-
114
- ## Timeline Rules
115
-
116
- Use absolute seconds in manifests and data attributes. Convert to frames only at render time.
117
-
118
- Required layer fields:
119
-
120
- - `id`
121
- - `kind`
122
- - `start`
123
- - `duration`
124
- - `track`
125
- - `z`
126
- - `mode`
127
- - `source_of_truth`
128
- - `geometry`
129
- - `viral_alignment`
130
-
131
- For video decomposition, split source video into scene layers:
132
-
133
- ```json
134
- {
135
- "id": "scene-2",
136
- "kind": "video",
137
- "start": 3.567,
138
- "duration": 3.033,
139
- "track": 0,
140
- "z": 0,
141
- "mode": "both",
142
- "media": {
143
- "src": "/drafts/example/source.mp4",
144
- "media_start": 3.567,
145
- "fit": "cover"
146
- }
147
- }
148
- ```
149
-
150
- For publish correctness, timed video scene layers should become real timed media layers or publish-time timeline proxies that are rewritten into real timed media. A preview-only playback source may exist for editor scrubbing, but it must be ignored or normalized out during publish.
151
-
152
- Blank gaps are valid. If no layer covers a time range, render the composition background for that range.
153
-
154
- ## Slideshow Rules
155
-
156
- For an image slideshow, create one timed image layer per slide:
157
-
158
- ```json
159
- {
160
- "id": "slide-01-image",
161
- "kind": "image",
162
- "start": 0,
163
- "duration": 3,
164
- "track": 0,
165
- "z": 0,
166
- "mode": "both",
167
- "media": {
168
- "src": "/drafts/example/slide-01.png",
169
- "fit": "cover"
170
- }
171
- }
172
- ```
173
-
174
- Caption text should be separate `caption` or `html` layers unless the source is intentionally a flattened image/poster template.
175
-
176
- ## Caption And Overlay Rules
177
-
178
- Captions are deterministic layout, not an afterthought. Record:
179
-
180
- - font family and fallback
181
- - font weight
182
- - font size in px at the target composition size
183
- - line height
184
- - max width
185
- - x/y/width/height in percentages
186
- - text alignment
187
- - safe-area constraints
188
- - outline, radial halo, shadow, or inline highlight chip behavior
189
- - whether text can wrap and how many lines are allowed
190
-
191
- Caption positions must account for TikTok/Reels unsafe zones. For vertical 9:16 output, preserve:
192
-
193
- - top 8-12 percent for app chrome risk
194
- - right 12-16 percent for action buttons
195
- - bottom 14-20 percent for username, caption, and scrubber risk
196
- - center subject-safe zone when faces/products matter
197
-
198
- Use inline chips that hug measured wrapped lines when the source has caption backgrounds. Do not turn inline chips into full-width bars or large paragraph washes.
199
-
200
- For white TikTok-native captions, prefer a radial halo or outline. Avoid a single directional web drop shadow when the source uses a native black glyph halo.
201
-
202
- For multiline captions, wrap once, choose one shared font size and line height, render one block, then measure per-line chips after layout. Do not render each wrapped line as an independently trimmed text image.
203
-
204
- ## Lambda Memory Estimate
205
-
206
- Each plan must include a `lambda_memory_estimate` with:
207
-
208
- - `recommended_memory_mb`
209
- - `confidence`
210
- - `complexity_scores`
211
- - `rationale`
212
- - `risk_flags`
213
- - `benchmark_override`
214
-
215
- Default to `3072` MB for ordinary 720x1280 or 1080x1920 social-video compositions with one active video stream and deterministic overlays. Use `2048` MB only for static/slideshow/simple 720p outputs or after local evidence that video decode is light. Use `4096` MB for 1080p video, multiple simultaneous videos, heavy DOM/caption effects, or long audio mixing. Reserve `6144+` MB for high-resolution or failure-prone compositions.
216
-
217
- Do not default to `10240` MB. Use it only after timeouts, Chromium memory failures, or a measured case that requires it.
218
-
219
- See `lambda-memory-estimator.md` for the scoring rubric.
220
-
221
- ## Production Lambda Site
222
-
223
- The generated plan should be ready for the deployed production Lambda stack:
224
-
225
- - stack: `hyperframes-vidfarm-prod`
226
- - default region: `us-east-1`
227
- - default memory: `3072`
228
- - output policy: frontend should show only the final downloadable/signed output URL, not AWS console links that require login
229
-
230
- For repeat publishing, pre-stage the project as a Lambda site and write `lambda-site.json`:
231
-
232
- ```json
233
- {
234
- "schema": "vidfarm.hyperframe.lambda-site.v1",
235
- "stack_name": "hyperframes-vidfarm-prod",
236
- "region": "us-east-1",
237
- "site_id": "content-addressed-site-id",
238
- "project_dir": "drafts/example",
239
- "composition_file": "composition.html",
240
- "memory_mb": 3072,
241
- "render_defaults": {
242
- "width": 720,
243
- "height": 1280,
244
- "fps": 30
245
- },
246
- "output_url_policy": "signed_https_final_output_only"
247
- }
248
- ```
249
-
250
- If the site has not been uploaded yet, set `site_id` to `null` and include `site_upload_command` or `site_upload_api`.
251
-
252
- ## Pipeline
253
-
254
- 1. Intake source media and notes.
255
- 2. Extract `ffprobe`, contact sheet, scene cuts, OCR, transcript, and simple layout/subject regions.
256
- 3. Generate `production_graph.json` with `extractor-system-prompt.md`.
257
- 4. Generate `template_plan.json` with `template-planner-prompt.md`.
258
- 5. Write `composition.html`, `composition.json`, and `lambda-site.json`.
259
- 6. Validate locally in the editor.
260
- 7. Stage the project with the production Lambda site flow.
261
- 8. Publish through Lambda and verify the final output URL.
262
-
263
- ## Required Validation
264
-
265
- Before publishing:
266
-
267
- - every timed layer has non-negative `start` and positive `duration`
268
- - no two editable layers overlap on the same track unless the track is intentionally composited
269
- - scene video layers use `media_start`/`playbackStart` rather than an always-on background dependency
270
- - deleting a scene removes that visual range from publish output
271
- - captions are legible at phone size
272
- - caption boxes avoid unsafe TikTok/Reels zones unless the source intentionally uses them
273
- - source audio and source video are separate layers when audio is reused continuously
274
- - Lambda memory estimate has a concrete rationale
275
- - `lambda-site.json` does not contain credentials
@@ -1,128 +0,0 @@
1
- # HyperFrames Production Graph Extractor Prompt
2
-
3
- You are a HyperFrames production analyst.
4
-
5
- Your job is to inspect one MP4, screenshot set, or PNG/JPG/WebP slideshow and extract the repeatable HyperFrames production process as structured JSON. Do not merely describe the media. Convert it into an editable composition graph that can become `composition.html`, `composition.json`, and a production Lambda site.
6
-
7
- Return only JSON matching `production-graph.schema.json`.
8
-
9
- ## Inputs You May Receive
10
-
11
- - source notes
12
- - source video or slides
13
- - contact sheet
14
- - representative frames
15
- - ffprobe metadata
16
- - scene cut list
17
- - STT transcript with word timestamps
18
- - OCR text from frames
19
- - layout analysis with bounding boxes
20
- - existing `composition.html` or `composition.json`
21
- - desired output dimensions and fps
22
-
23
- ## Extraction Rules
24
-
25
- - Treat all supplied media as one reusable HyperFrames format.
26
- - Separate source media, deterministic overlays, captions, audio, and generated assets.
27
- - Identify which visual surfaces are editable layers and which are source-media content.
28
- - Important readable text should default to deterministic HTML/caption layers, not baked generated media.
29
- - Extract exact or inferred timing for scenes, slides, captions, overlays, transitions, zooms, holds, and loop points.
30
- - Record source media slices with `media_start` when a layer uses a segment from a longer MP4.
31
- - Preserve blank gaps as intentional timeline ranges when no layer should be visible.
32
- - Do not depend on an always-on source video for publish correctness. Preview playback sources are allowed only as editor affordances.
33
- - Distinguish `mode: "both"`, `mode: "editor"`, and `mode: "publish"`.
34
- - Use percent geometry for layer placement: `x`, `y`, `width`, `height`.
35
- - Use seconds for `start`, `duration`, `media_start`, and `media_end`.
36
- - Track source audio separately from source video if audio should continue across scene cuts.
37
- - Keep one editable timeline track collision-free unless the track is explicitly marked as composited.
38
- - Identify caption safe areas and collisions with TikTok/Reels chrome.
39
- - Record Lambda memory estimate inputs: resolution, duration, active video streams, source resolution, layer count, DOM complexity, effects, audio mixing, and known risk flags.
40
-
41
- ## Required Analysis Dimensions
42
-
43
- Extract:
44
-
45
- - format summary and source mode
46
- - output dimensions, fps, and total duration
47
- - source asset inventory
48
- - scene or slide timeline
49
- - layer decomposition
50
- - deterministic caption and text surfaces
51
- - HTML overlay surfaces
52
- - media replacement slots
53
- - audio plan
54
- - safe areas and subject bounds
55
- - caption positioning and wrapping rules
56
- - visual rules that must survive adaptation
57
- - editable controls
58
- - generated asset needs, if any
59
- - Lambda memory estimate
60
- - production Lambda site readiness
61
- - validation checklist
62
-
63
- ## Layer Classification
64
-
65
- For every meaningful visual or audio element choose one kind:
66
-
67
- - `video`: timed video layer or scene slice
68
- - `image`: timed image/slide layer
69
- - `audio`: timed audio layer
70
- - `caption`: text intended as subtitle/creator caption
71
- - `html`: custom deterministic HTML overlay, UI card, comment, notification, or app shell
72
- - `shape`: non-text geometric layer
73
- - `effect`: deterministic transform/filter/mask/highlight
74
-
75
- For every layer choose one source of truth:
76
-
77
- - `source_media`: the original media asset is the visual/audio content
78
- - `deterministic_html`: HTML/CSS/text is the source of truth
79
- - `generated_asset`: AI/generated media is the source of truth
80
- - `user_asset`: caller-provided replacement asset is required
81
- - `computed_effect`: derived motion, mask, crop, zoom, or highlight
82
-
83
- ## Caption Rules
84
-
85
- Strongly identify typography:
86
-
87
- - font family match
88
- - fallback font stack
89
- - font weight
90
- - case
91
- - color
92
- - outline, stroke, radial halo, shadow
93
- - background chip style
94
- - line wrapping
95
- - line height
96
- - alignment
97
- - safe area
98
- - phone-size legibility
99
-
100
- When captions have colored backgrounds, classify them as inline highlight chips unless the source clearly uses a panel. Chips must hug measured wrapped lines.
101
-
102
- When captions are white TikTok-native captions, distinguish radial black halo/outline from a web-style directional shadow.
103
-
104
- For multiline captions, require one shared font size and line height for the block. Do not recommend per-line rendered images.
105
-
106
- ## Lambda Memory Estimate Rules
107
-
108
- Estimate memory from composition complexity, not vibes.
109
-
110
- Use these defaults:
111
-
112
- - `2048` MB for static/slideshow/simple image compositions with low DOM complexity.
113
- - `3072` MB for standard 720x1280 or 1080x1920 social video with one active video stream and deterministic overlays.
114
- - `4096` MB for 1080p video, multiple active videos, heavy captions, masks, filters, or long audio.
115
- - `6144` MB or higher only when high resolution, many simultaneous layers, or prior failures justify it.
116
-
117
- Return both a recommendation and a confidence. Include benchmark guidance only when the source sits near a threshold.
118
-
119
- ## Output Bias
120
-
121
- Be concrete. A production graph should be implementable.
122
-
123
- Bad: "Add captions around the video."
124
-
125
- Good: "Render a 2-line white TikTok Sans Semibold caption block at x=8, y=42, width=84, height=14, fontSize=46, lineHeight=1.08, black radial halo, max 18 chars per line, timed 0.0-2.4s."
126
-
127
- Publish correctness bias: if a source video is split into scenes, every scene must be its own timed layer or publish proxy. Deleting scene 2 must delete scene 2 from the final render.
128
-