@mevdragon/vidfarm-devcli 0.2.8 → 0.2.9

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 +327 -4
  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
@@ -0,0 +1,88 @@
1
+ import { createId } from "../lib/ids.js";
2
+ import { nowIso } from "../lib/time.js";
3
+ import { database } from "../db.js";
4
+ import { StorageService } from "./storage.js";
5
+ const storage = new StorageService();
6
+ function normalizeTracerList(values) {
7
+ return [...new Set(values.map((value) => value.trim()).filter(Boolean))];
8
+ }
9
+ function buildThreadStoragePrefix(customerId, templateId, threadId) {
10
+ return storage.developerScopedKey(customerId, "chat-threads", templateId, threadId);
11
+ }
12
+ function buildThreadChunkKey(prefix, createdAt) {
13
+ const sortableTime = createdAt.replace(/[^0-9]/g, "");
14
+ return `${prefix}/chunks/${sortableTime}-${createId("chunk")}.json`;
15
+ }
16
+ async function readChunkMessages(key) {
17
+ const raw = await storage.readText(key);
18
+ if (!raw) {
19
+ return [];
20
+ }
21
+ const parsed = JSON.parse(raw);
22
+ return Array.isArray(parsed.messages) ? parsed.messages : [];
23
+ }
24
+ export const chatThreads = {
25
+ async listThreads(input) {
26
+ const threads = database.listChatThreadMetas(input);
27
+ const withMessages = await Promise.all(threads.map(async (thread) => ({
28
+ ...thread,
29
+ messages: await this.loadThreadMessages(thread)
30
+ })));
31
+ return withMessages;
32
+ },
33
+ async getThread(input) {
34
+ const thread = database.getChatThreadMeta(input.customerId, input.threadId);
35
+ if (!thread) {
36
+ return null;
37
+ }
38
+ return {
39
+ ...thread,
40
+ messages: await this.loadThreadMessages(thread)
41
+ };
42
+ },
43
+ async appendExchange(input) {
44
+ const createdAt = nowIso();
45
+ const storagePrefix = buildThreadStoragePrefix(input.customerId, input.templateId, input.threadId);
46
+ const chunk = {
47
+ version: 1,
48
+ threadId: input.threadId,
49
+ customerId: input.customerId,
50
+ templateId: input.templateId,
51
+ createdAt,
52
+ messages: input.messages
53
+ };
54
+ await storage.putJson(buildThreadChunkKey(storagePrefix, createdAt), chunk);
55
+ const updated = database.appendChatThreadMessages({
56
+ threadId: input.threadId,
57
+ customerId: input.customerId,
58
+ title: input.title || "New chat",
59
+ templateId: input.templateId,
60
+ storagePrefix,
61
+ tracers: normalizeTracerList(input.tracers),
62
+ messageCountDelta: input.messages.length,
63
+ lastMessageAt: createdAt
64
+ });
65
+ return updated ? this.getThread({ customerId: input.customerId, threadId: updated.id }) : null;
66
+ },
67
+ async updateThread(input) {
68
+ const updated = database.updateChatThreadState({
69
+ ...input,
70
+ tracers: input.tracers ? normalizeTracerList(input.tracers) : undefined
71
+ });
72
+ return updated ? this.getThread({ customerId: input.customerId, threadId: updated.id }) : null;
73
+ },
74
+ async deleteThread(input) {
75
+ const existing = database.deleteChatThread(input.customerId, input.threadId);
76
+ if (!existing) {
77
+ return null;
78
+ }
79
+ const keys = await storage.listKeys(`${existing.storagePrefix}/`);
80
+ await Promise.all(keys.map((key) => storage.deleteObject(key)));
81
+ return existing;
82
+ },
83
+ async loadThreadMessages(thread) {
84
+ const keys = (await storage.listKeys(`${thread.storagePrefix}/chunks/`)).sort();
85
+ const messageGroups = await Promise.all(keys.map((key) => readChunkMessages(key)));
86
+ return messageGroups.flat();
87
+ }
88
+ };
@@ -1,8 +1,8 @@
1
1
  import { StorageService } from "./storage.js";
2
2
  const JOB_LOG_PREFIX = "job-logs";
3
- const JOB_LOG_CHUNK_INTERVAL_MS = 60000;
3
+ const JOB_LOG_CHUNK_INTERVAL_MS = 60_000;
4
4
  const JOB_LOG_CHUNK_MAX_BYTES = 1024 * 1024;
5
- const JOB_LOG_FLUSH_INTERVAL_MS = 5000;
5
+ const JOB_LOG_FLUSH_INTERVAL_MS = 5_000;
6
6
  export class JobLogStore {
7
7
  storage = new StorageService();
8
8
  activeChunks = new Map();
@@ -32,11 +32,18 @@ export class JobLogStore {
32
32
  }
33
33
  }
34
34
  async listEvents(input) {
35
- const limit = Math.max(1, Math.min(input.limit ?? 100, 500));
36
35
  const persisted = await this.readPersistedEvents(input);
37
36
  const buffered = this.readBufferedEvents(input);
38
- const merged = dedupeAndSort([...persisted, ...buffered]);
39
- return merged.slice(-limit);
37
+ const merged = dedupeAndSort([...persisted, ...buffered]).reverse();
38
+ const filtered = input.cursor
39
+ ? merged.filter((event) => (Date.parse(event.createdAt) < Date.parse(input.cursor.createdAt)
40
+ || (event.createdAt === input.cursor.createdAt && event.id < input.cursor.id)))
41
+ : merged;
42
+ if (input.limit === undefined) {
43
+ return filtered;
44
+ }
45
+ const limit = Math.max(1, Math.min(input.limit, 501));
46
+ return filtered.slice(0, limit);
40
47
  }
41
48
  async shutdown() {
42
49
  clearInterval(this.flushTimer);
@@ -81,7 +88,7 @@ export class JobLogStore {
81
88
  const minMs = Math.min(startMs, endMs);
82
89
  const maxMs = Math.max(startMs, endMs);
83
90
  const minuteStarts = [];
84
- for (let cursor = minMs; cursor <= maxMs; cursor += 60000) {
91
+ for (let cursor = minMs; cursor <= maxMs; cursor += 60_000) {
85
92
  minuteStarts.push(cursor);
86
93
  }
87
94
  return minuteStarts;
@@ -155,7 +162,7 @@ function serializedEventSize(event) {
155
162
  return Buffer.byteLength(`${JSON.stringify(event)}\n`, "utf8");
156
163
  }
157
164
  function floorToMinute(timestampMs) {
158
- return Math.floor(timestampMs / 60000) * 60000;
165
+ return Math.floor(timestampMs / 60_000) * 60_000;
159
166
  }
160
167
  function parseChunk(content) {
161
168
  if (!content) {
@@ -4,6 +4,13 @@ import { createId } from "../lib/ids.js";
4
4
  import { addSeconds, nowIso } from "../lib/time.js";
5
5
  import { jobLogStore } from "./job-logs.js";
6
6
  const PENDING_JOB_STATUSES = ["queued", "running", "waiting_for_child", "waiting_for_human"];
7
+ function normalizeWebhookUrl(value) {
8
+ if (typeof value !== "string") {
9
+ return null;
10
+ }
11
+ const trimmed = value.trim();
12
+ return trimmed ? trimmed : null;
13
+ }
7
14
  export class JobsService {
8
15
  assertQueueCapacity(customerId) {
9
16
  if (config.MAX_PENDING_JOBS_GLOBAL <= 0 && config.MAX_PENDING_JOBS_PER_CUSTOMER <= 0) {
@@ -36,7 +43,7 @@ export class JobsService {
36
43
  _providerHint: input.providerHint ?? null
37
44
  },
38
45
  progress: 0,
39
- webhookUrl: input.webhookUrl ?? input.customer.defaultWebhookUrl ?? null,
46
+ webhookUrl: normalizeWebhookUrl(input.webhookUrl) ?? normalizeWebhookUrl(input.customer.defaultWebhookUrl),
40
47
  parentJobId: null,
41
48
  priority: 100,
42
49
  attemptCount: 0,
@@ -73,6 +80,9 @@ export class JobsService {
73
80
  listJobs(input) {
74
81
  return database.listJobsForCustomer(input);
75
82
  }
83
+ renameTracer(input) {
84
+ return database.renameJobsTracer(input);
85
+ }
76
86
  async listLogs(input) {
77
87
  return jobLogStore.listEvents(input);
78
88
  }
@@ -93,6 +103,7 @@ export class JobsService {
93
103
  status: "succeeded",
94
104
  progress,
95
105
  result,
106
+ error: null,
96
107
  completedAt: nowIso()
97
108
  });
98
109
  }
@@ -109,7 +120,7 @@ export class JobsService {
109
120
  database.updateJobStatus({
110
121
  id: job.id,
111
122
  status: nextStatus,
112
- error,
123
+ error: nextStatus === "failed" ? error : null,
113
124
  runAfter: addSeconds(new Date(), delaySeconds),
114
125
  completedAt: nextStatus === "failed" ? nowIso() : null
115
126
  });