@mevdragon/vidfarm-devcli 0.20.6 → 0.20.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/editor-capabilities/SKILL.md +15 -1
- package/.agents/skills/vidfarm-director/SKILL.md +106 -0
- package/.agents/skills/vidfarm-director/recipes/find-and-fork-template.md +16 -0
- package/.agents/skills/vidfarm-director/recipes/local-edit-render-approve.md +13 -0
- package/.agents/skills/vidfarm-director/recipes/onboard-a-new-director.md +13 -0
- package/.agents/skills/vidfarm-director/recipes/retheme-template.md +17 -0
- package/.agents/skills/vidfarm-director/references/assets-and-sourcing.md +111 -0
- package/.agents/skills/vidfarm-director/references/automation-and-local-dev.md +243 -0
- package/.agents/skills/vidfarm-director/references/core-workflows.md +273 -0
- package/.agents/skills/vidfarm-director/references/editor-workflows.md +365 -0
- package/.agents/skills/vidfarm-director/references/onboarding.md +28 -0
- package/.agents/skills/vidfarm-director/references/primitives.md +265 -0
- package/SKILL.director.md +476 -260
- package/dist/src/cli.js +362 -96
- package/dist/src/devcli/clips.js +15 -10
- package/dist/src/devcli/doctor.js +2 -2
- package/dist/src/devcli/local-backend.js +46 -2
- package/dist/src/services/clip-curation/cost.js +5 -1
- package/dist/src/services/clip-curation/gemini.js +10 -0
- package/package.json +30 -10
- package/SKILL.platform.md +0 -432
- package/demo/README.md +0 -28
- package/demo/dist/app.css +0 -1
- package/demo/dist/app.js +0 -1850
- package/demo/dist/chunks/chunk-DXB73IDG.js +0 -1
- package/demo/dist/chunks/chunk-S7OWAJDS.js +0 -36
- package/demo/dist/chunks/chunk-VTIBZ6AN.js +0 -1
- package/demo/dist/chunks/dist-ADSJKBVE.js +0 -332
- package/demo/dist/chunks/domEditingLayers-VZMLL4AP-SGHWPND4.js +0 -1
- package/demo/dist/chunks/hyperframes-player-XB65TCD6.js +0 -425
- package/demo/dist/chunks/lib-XAQ37YOE.js +0 -1
- package/demo/dist/chunks/src-TJ2QYA4U.js +0 -207
- package/demo/dist/favicon.ico +0 -0
- package/demo/dist/icons/timeline/audio.svg +0 -7
- package/demo/dist/icons/timeline/captions.svg +0 -5
- package/demo/dist/icons/timeline/composition.svg +0 -12
- package/demo/dist/icons/timeline/image.svg +0 -18
- package/demo/dist/icons/timeline/music.svg +0 -10
- package/demo/dist/icons/timeline/text.svg +0 -3
- package/demo/dist/index.html +0 -15
- package/dist/src/account-pages-legacy.js +0 -9396
- package/dist/src/account-pages.js +0 -61
- package/dist/src/app.js +0 -21603
- package/dist/src/composition-runtime.js +0 -1053
- package/dist/src/config.js +0 -217
- package/dist/src/context.js +0 -447
- package/dist/src/dev-app-legacy.js +0 -739
- package/dist/src/dev-app.js +0 -6
- package/dist/src/devcli/migrate-local.js +0 -140
- package/dist/src/devcli/sync.js +0 -368
- package/dist/src/domain.js +0 -5
- package/dist/src/editor-chat-history.js +0 -82
- package/dist/src/editor-chat.js +0 -828
- package/dist/src/editor-dark-theme.js +0 -1128
- package/dist/src/frontend/debug.js +0 -71
- package/dist/src/frontend/discover-client.js +0 -130
- package/dist/src/frontend/discover-store.js +0 -23
- package/dist/src/frontend/file-directory.js +0 -1018
- package/dist/src/frontend/flockposter-cache-store.js +0 -124
- package/dist/src/frontend/homepage-client.js +0 -446
- package/dist/src/frontend/homepage-shared.js +0 -201
- package/dist/src/frontend/homepage-store.js +0 -66
- package/dist/src/frontend/homepage-view.js +0 -705
- package/dist/src/frontend/page-runtime-client.js +0 -132
- package/dist/src/frontend/page-runtime-store.js +0 -9
- package/dist/src/frontend/sentry.js +0 -42
- package/dist/src/frontend/template-editor-chat.js +0 -4181
- package/dist/src/help-page.js +0 -346
- package/dist/src/homepage.js +0 -1458
- package/dist/src/index.js +0 -16
- package/dist/src/instrument.js +0 -30
- package/dist/src/landing-page.js +0 -384
- package/dist/src/page-runtime.js +0 -2
- package/dist/src/page-shell.js +0 -1452
- package/dist/src/primitive-context.js +0 -416
- package/dist/src/primitive-registry.js +0 -3940
- package/dist/src/primitive-sdk.js +0 -4
- package/dist/src/primitives/hyperframes-media.js +0 -108
- package/dist/src/react-page-shell.js +0 -35
- package/dist/src/ready-post-schedule-component.js +0 -1540
- package/dist/src/registry.js +0 -296
- package/dist/src/reskin/agency-page.js +0 -299
- package/dist/src/reskin/calendar-page.js +0 -568
- package/dist/src/reskin/chat-page.js +0 -942
- package/dist/src/reskin/discover-page.js +0 -1788
- package/dist/src/reskin/document.js +0 -1587
- package/dist/src/reskin/help-page.js +0 -357
- package/dist/src/reskin/index-page.js +0 -62
- package/dist/src/reskin/inpaint-clipper-page.js +0 -890
- package/dist/src/reskin/inpaint-page.js +0 -2554
- package/dist/src/reskin/inpaint-video-page.js +0 -1339
- package/dist/src/reskin/job-runs-page.js +0 -477
- package/dist/src/reskin/library-page.js +0 -1634
- package/dist/src/reskin/login-page.js +0 -262
- package/dist/src/reskin/portfolio-page.js +0 -687
- package/dist/src/reskin/pricing-page.js +0 -390
- package/dist/src/reskin/settings-page.js +0 -732
- package/dist/src/reskin/theme.js +0 -711
- package/dist/src/runtime.js +0 -35
- package/dist/src/services/api-call-history.js +0 -249
- package/dist/src/services/auth.js +0 -152
- package/dist/src/services/billing-pricing.js +0 -39
- package/dist/src/services/billing.js +0 -241
- package/dist/src/services/cast.js +0 -127
- package/dist/src/services/chat-threads.js +0 -92
- package/dist/src/services/clip-records.js +0 -250
- package/dist/src/services/clip-search.js +0 -77
- package/dist/src/services/clip-vectors.js +0 -125
- package/dist/src/services/composition-sanitize.js +0 -124
- package/dist/src/services/composition-watch.js +0 -79
- package/dist/src/services/elevenlabs.js +0 -222
- package/dist/src/services/file-directory.js +0 -117
- package/dist/src/services/fork-access.js +0 -93
- package/dist/src/services/fork-manifest.js +0 -42
- package/dist/src/services/ghostcut.js +0 -179
- package/dist/src/services/hyperframes.js +0 -3654
- package/dist/src/services/job-capacity.js +0 -14
- package/dist/src/services/job-logs.js +0 -197
- package/dist/src/services/jobs.js +0 -136
- package/dist/src/services/local-dynamo.js +0 -0
- package/dist/src/services/media-processing.js +0 -766
- package/dist/src/services/primitive-media-lambda.js +0 -280
- package/dist/src/services/providers.js +0 -2748
- package/dist/src/services/rate-limits.js +0 -262
- package/dist/src/services/scene-annotations.js +0 -32
- package/dist/src/services/serverless-auth.js +0 -382
- package/dist/src/services/serverless-jobs.js +0 -1084
- package/dist/src/services/serverless-provider-keys.js +0 -409
- package/dist/src/services/serverless-records.js +0 -1515
- package/dist/src/services/serverless-template-configs.js +0 -75
- package/dist/src/services/storage.js +0 -461
- package/dist/src/services/swipe-customize.js +0 -437
- package/dist/src/services/template-certification.js +0 -413
- package/dist/src/services/template-loader.js +0 -99
- package/dist/src/services/template-runtime-bundles.js +0 -217
- package/dist/src/services/template-sources.js +0 -1017
- package/dist/src/services/upstream.js +0 -248
- package/dist/src/services/video-normalization.js +0 -2
- package/dist/src/services/webhooks.js +0 -62
- package/dist/src/template-editor-pages.js +0 -2576
- package/dist/src/template-editor-shell.js +0 -2893
- package/dist/src/template-sdk.js +0 -4
- package/dist/src/worker.js +0 -17
- package/public/assets/discover-client-app.js +0 -1
- package/public/assets/file-directory-app.js +0 -3
- package/public/assets/homepage-app.js +0 -54
- package/public/assets/homepage-client-app.js +0 -80
- package/public/assets/page-runtime-client-app.js +0 -94
- package/public/assets/placeholders/scene-placeholder.png +0 -0
- package/src/assets/SELLING_AWARENESS_STAGES.md +0 -579
- package/src/assets/SELLING_WITH_HOOKS.md +0 -377
- package/src/assets/SELLING_WITH_VSLS.md +0 -606
- package/src/assets/favicon.ico +0 -0
- package/src/assets/logo-vidfarm.png +0 -0
package/dist/src/registry.js
DELETED
|
@@ -1,296 +0,0 @@
|
|
|
1
|
-
import { existsSync, readdirSync } from "node:fs";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import { z } from "zod";
|
|
4
|
-
import { config } from "./config.js";
|
|
5
|
-
import { devLog } from "./lib/dev-log.js";
|
|
6
|
-
import { loadTemplateFromModule } from "./services/template-loader.js";
|
|
7
|
-
import { loadTemplateFromRuntimeRelease } from "./services/template-runtime-bundles.js";
|
|
8
|
-
import { serverlessRecords } from "./services/serverless-records.js";
|
|
9
|
-
class TemplateRegistry {
|
|
10
|
-
localTemplates = new Map();
|
|
11
|
-
releaseTemplates = new Map();
|
|
12
|
-
activeReleases = new Map();
|
|
13
|
-
runtimeTemplates = new Map();
|
|
14
|
-
initialized = false;
|
|
15
|
-
initPromise = null;
|
|
16
|
-
async ensureInitialized() {
|
|
17
|
-
if (this.initialized) {
|
|
18
|
-
return;
|
|
19
|
-
}
|
|
20
|
-
if (this.initPromise) {
|
|
21
|
-
return this.initPromise;
|
|
22
|
-
}
|
|
23
|
-
this.initPromise = (async () => {
|
|
24
|
-
await this.loadActiveReleaseSnapshots();
|
|
25
|
-
if (shouldLoadLocalTemplates()) {
|
|
26
|
-
await this.loadLocalTemplates();
|
|
27
|
-
devLog("template_registry.local_loaded", {
|
|
28
|
-
count: this.localTemplates.size,
|
|
29
|
-
template_ids: [...this.localTemplates.keys()]
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
this.initialized = true;
|
|
33
|
-
this.initPromise = null;
|
|
34
|
-
devLog("template_registry.initialized", {
|
|
35
|
-
local_count: this.localTemplates.size,
|
|
36
|
-
release_count: this.releaseTemplates.size,
|
|
37
|
-
runtime_count: this.runtimeTemplates.size
|
|
38
|
-
});
|
|
39
|
-
})();
|
|
40
|
-
return this.initPromise;
|
|
41
|
-
}
|
|
42
|
-
list() {
|
|
43
|
-
const merged = new Map();
|
|
44
|
-
for (const template of this.releaseTemplates.values()) {
|
|
45
|
-
merged.set(template.id, template);
|
|
46
|
-
}
|
|
47
|
-
for (const template of this.localTemplates.values()) {
|
|
48
|
-
merged.set(template.id, template);
|
|
49
|
-
}
|
|
50
|
-
for (const template of this.runtimeTemplates.values()) {
|
|
51
|
-
merged.set(template.id, template);
|
|
52
|
-
}
|
|
53
|
-
return [...merged.values()].sort((a, b) => a.id.localeCompare(b.id));
|
|
54
|
-
}
|
|
55
|
-
get(templateId) {
|
|
56
|
-
return this.findTemplate(templateId, this.runtimeTemplates)
|
|
57
|
-
?? this.findTemplate(templateId, this.localTemplates)
|
|
58
|
-
?? this.findTemplate(templateId, this.releaseTemplates);
|
|
59
|
-
}
|
|
60
|
-
async listMetadata() {
|
|
61
|
-
try {
|
|
62
|
-
const releases = await serverlessRecords.listActiveTemplateReleases?.() ?? [];
|
|
63
|
-
for (const release of releases) {
|
|
64
|
-
this.cacheReleaseSnapshot(release);
|
|
65
|
-
}
|
|
66
|
-
const releaseTemplates = releases
|
|
67
|
-
.filter((release) => release.templateSnapshot)
|
|
68
|
-
.map((release) => templateFromSnapshot(release.templateSnapshot, release));
|
|
69
|
-
return await this.mergeLocalMetadata(releaseTemplates);
|
|
70
|
-
}
|
|
71
|
-
catch (error) {
|
|
72
|
-
devLog("template_registry.metadata.list_failed", {
|
|
73
|
-
message: error instanceof Error ? error.message : String(error)
|
|
74
|
-
}, "warn");
|
|
75
|
-
await this.ensureInitialized();
|
|
76
|
-
return this.list();
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
async listMetadataPage(input = {}) {
|
|
80
|
-
try {
|
|
81
|
-
const page = await serverlessRecords.listActiveTemplateReleasePage?.(input);
|
|
82
|
-
if (!page) {
|
|
83
|
-
return { templates: await this.listMetadata(), nextCursor: null };
|
|
84
|
-
}
|
|
85
|
-
for (const release of page.items) {
|
|
86
|
-
this.cacheReleaseSnapshot(release);
|
|
87
|
-
}
|
|
88
|
-
const releaseTemplates = page.items
|
|
89
|
-
.filter((release) => release.templateSnapshot)
|
|
90
|
-
.map((release) => templateFromSnapshot(release.templateSnapshot, release));
|
|
91
|
-
return {
|
|
92
|
-
templates: await this.mergeLocalMetadata(releaseTemplates),
|
|
93
|
-
nextCursor: page.nextCursor
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
catch (error) {
|
|
97
|
-
devLog("template_registry.metadata.page_failed", {
|
|
98
|
-
message: error instanceof Error ? error.message : String(error)
|
|
99
|
-
}, "warn");
|
|
100
|
-
return { templates: await this.listMetadata(), nextCursor: null };
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
async getMetadata(templateId) {
|
|
104
|
-
const cached = this.get(templateId);
|
|
105
|
-
if (cached) {
|
|
106
|
-
return cached;
|
|
107
|
-
}
|
|
108
|
-
try {
|
|
109
|
-
const release = await serverlessRecords.getActiveTemplateReleaseByTemplateId?.(templateId);
|
|
110
|
-
if (release?.templateSnapshot) {
|
|
111
|
-
return this.cacheReleaseSnapshot(release);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
catch (error) {
|
|
115
|
-
devLog("template_registry.metadata.get_failed", {
|
|
116
|
-
template_id: templateId,
|
|
117
|
-
message: error instanceof Error ? error.message : String(error)
|
|
118
|
-
}, "warn");
|
|
119
|
-
}
|
|
120
|
-
await this.ensureInitialized();
|
|
121
|
-
return this.get(templateId);
|
|
122
|
-
}
|
|
123
|
-
async getExecutable(templateId) {
|
|
124
|
-
const runtime = this.findTemplate(templateId, this.runtimeTemplates) ?? this.findTemplate(templateId, this.localTemplates);
|
|
125
|
-
if (runtime) {
|
|
126
|
-
return runtime;
|
|
127
|
-
}
|
|
128
|
-
let releaseTemplate = this.findTemplate(templateId, this.releaseTemplates);
|
|
129
|
-
let release = releaseTemplate ? this.activeReleases.get(releaseTemplate.id) : null;
|
|
130
|
-
if (!release) {
|
|
131
|
-
try {
|
|
132
|
-
const activeRelease = await serverlessRecords.getActiveTemplateReleaseByTemplateId?.(templateId);
|
|
133
|
-
if (activeRelease?.templateSnapshot) {
|
|
134
|
-
releaseTemplate = this.cacheReleaseSnapshot(activeRelease);
|
|
135
|
-
release = activeRelease;
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
catch (error) {
|
|
139
|
-
devLog("template_registry.executable.active_release_lookup_failed", {
|
|
140
|
-
template_id: templateId,
|
|
141
|
-
message: error instanceof Error ? error.message : String(error)
|
|
142
|
-
}, "warn");
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
if (!release) {
|
|
146
|
-
await this.ensureInitialized();
|
|
147
|
-
const initializedRuntime = this.findTemplate(templateId, this.runtimeTemplates) ?? this.findTemplate(templateId, this.localTemplates);
|
|
148
|
-
if (initializedRuntime) {
|
|
149
|
-
return initializedRuntime;
|
|
150
|
-
}
|
|
151
|
-
releaseTemplate = this.findTemplate(templateId, this.releaseTemplates);
|
|
152
|
-
release = releaseTemplate ? this.activeReleases.get(releaseTemplate.id) : null;
|
|
153
|
-
}
|
|
154
|
-
if (!release) {
|
|
155
|
-
return null;
|
|
156
|
-
}
|
|
157
|
-
const template = await loadTemplateFromRuntimeRelease(release);
|
|
158
|
-
this.runtimeTemplates.set(template.id, template);
|
|
159
|
-
return template;
|
|
160
|
-
}
|
|
161
|
-
registerRuntimeTemplate(template) {
|
|
162
|
-
this.runtimeTemplates.set(template.id, template);
|
|
163
|
-
}
|
|
164
|
-
cacheReleaseSnapshot(release) {
|
|
165
|
-
if (!release.templateSnapshot) {
|
|
166
|
-
return null;
|
|
167
|
-
}
|
|
168
|
-
const template = templateFromSnapshot(release.templateSnapshot, release);
|
|
169
|
-
this.releaseTemplates.set(template.id, template);
|
|
170
|
-
this.activeReleases.set(template.id, release);
|
|
171
|
-
return template;
|
|
172
|
-
}
|
|
173
|
-
async loadLocalTemplates() {
|
|
174
|
-
this.localTemplates.clear();
|
|
175
|
-
for (const modulePath of discoverLocalTemplateModulePaths(process.cwd())) {
|
|
176
|
-
const template = await loadTemplateFromModule(modulePath);
|
|
177
|
-
this.localTemplates.set(template.id, template);
|
|
178
|
-
devLog("template_registry.local_template.loaded", {
|
|
179
|
-
template_id: template.id,
|
|
180
|
-
slug_id: template.slugId,
|
|
181
|
-
module_path: modulePath
|
|
182
|
-
});
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
async loadActiveReleaseSnapshots() {
|
|
186
|
-
this.releaseTemplates.clear();
|
|
187
|
-
this.activeReleases.clear();
|
|
188
|
-
let releases = [];
|
|
189
|
-
try {
|
|
190
|
-
releases = await serverlessRecords.listActiveTemplateReleases?.() ?? [];
|
|
191
|
-
}
|
|
192
|
-
catch (error) {
|
|
193
|
-
devLog("template_registry.active_releases.load_failed", {
|
|
194
|
-
message: error instanceof Error ? error.message : String(error)
|
|
195
|
-
}, "warn");
|
|
196
|
-
return;
|
|
197
|
-
}
|
|
198
|
-
for (const release of releases) {
|
|
199
|
-
if (!release.templateSnapshot) {
|
|
200
|
-
continue;
|
|
201
|
-
}
|
|
202
|
-
this.cacheReleaseSnapshot(release);
|
|
203
|
-
}
|
|
204
|
-
devLog("template_registry.active_releases.loaded", {
|
|
205
|
-
count: this.releaseTemplates.size,
|
|
206
|
-
template_ids: [...this.releaseTemplates.keys()]
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
async mergeLocalMetadata(templates) {
|
|
210
|
-
if (shouldLoadLocalTemplates()) {
|
|
211
|
-
await this.ensureInitialized();
|
|
212
|
-
}
|
|
213
|
-
const merged = new Map();
|
|
214
|
-
for (const template of templates) {
|
|
215
|
-
merged.set(template.id, template);
|
|
216
|
-
}
|
|
217
|
-
for (const template of this.localTemplates.values()) {
|
|
218
|
-
merged.set(template.id, template);
|
|
219
|
-
}
|
|
220
|
-
for (const template of this.runtimeTemplates.values()) {
|
|
221
|
-
merged.set(template.id, template);
|
|
222
|
-
}
|
|
223
|
-
return [...merged.values()].sort((a, b) => a.id.localeCompare(b.id));
|
|
224
|
-
}
|
|
225
|
-
findTemplate(templateKey, source) {
|
|
226
|
-
return source.get(templateKey) ?? [...source.values()].find((template) => template.slugId === templateKey) ?? null;
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
function templateFromSnapshot(snapshot, release) {
|
|
230
|
-
const snapshotAbout = snapshot.about;
|
|
231
|
-
const operations = Object.fromEntries(snapshot.operations.map((operation) => [
|
|
232
|
-
operation.name,
|
|
233
|
-
{
|
|
234
|
-
description: operation.description,
|
|
235
|
-
inputSchema: z.record(z.string(), z.unknown()),
|
|
236
|
-
workflow: operation.workflow,
|
|
237
|
-
providerHint: operation.providerHint ?? undefined,
|
|
238
|
-
webhookSupport: operation.webhookSupport ?? undefined
|
|
239
|
-
}
|
|
240
|
-
]));
|
|
241
|
-
return {
|
|
242
|
-
id: snapshot.id,
|
|
243
|
-
slugId: snapshot.slugId,
|
|
244
|
-
version: snapshot.version,
|
|
245
|
-
about: {
|
|
246
|
-
...snapshot.about,
|
|
247
|
-
links_to_inspiration: normalizeTemplateInspirationLinks(snapshotAbout.links_to_inspiration, snapshot.about.link_to_original),
|
|
248
|
-
sound: normalizeTemplateSound(snapshotAbout.sound)
|
|
249
|
-
},
|
|
250
|
-
examples: snapshot.examples,
|
|
251
|
-
skillPath: release.skillPath,
|
|
252
|
-
configSchema: z.record(z.string(), z.unknown()),
|
|
253
|
-
operations,
|
|
254
|
-
jobs: {}
|
|
255
|
-
};
|
|
256
|
-
}
|
|
257
|
-
function normalizeTemplateInspirationLinks(value, linkToOriginal) {
|
|
258
|
-
if (Array.isArray(value)) {
|
|
259
|
-
return value.filter((entry) => typeof entry === "string");
|
|
260
|
-
}
|
|
261
|
-
return linkToOriginal ? [linkToOriginal] : [];
|
|
262
|
-
}
|
|
263
|
-
function normalizeTemplateSound(value) {
|
|
264
|
-
return {
|
|
265
|
-
sound_title: typeof value?.sound_title === "string" ? value.sound_title : "",
|
|
266
|
-
sound_url: typeof value?.sound_url === "string" ? value.sound_url : ""
|
|
267
|
-
};
|
|
268
|
-
}
|
|
269
|
-
function shouldLoadLocalTemplates() {
|
|
270
|
-
if (config.VIDFARM_LOAD_LOCAL_TEMPLATES === "true") {
|
|
271
|
-
return true;
|
|
272
|
-
}
|
|
273
|
-
if (config.VIDFARM_LOAD_LOCAL_TEMPLATES === "false") {
|
|
274
|
-
return false;
|
|
275
|
-
}
|
|
276
|
-
return !config.isProduction;
|
|
277
|
-
}
|
|
278
|
-
function discoverLocalTemplateModulePaths(rootDir) {
|
|
279
|
-
const templatesDir = path.resolve(rootDir, "templates");
|
|
280
|
-
if (!existsSync(templatesDir)) {
|
|
281
|
-
return [];
|
|
282
|
-
}
|
|
283
|
-
return readdirSync(templatesDir, { withFileTypes: true })
|
|
284
|
-
.filter((entry) => entry.isDirectory() && entry.name.startsWith("vidfarm_template_"))
|
|
285
|
-
.filter((entry) => (entry.name !== "vidfarm_template_0000"
|
|
286
|
-
|| process.env.NODE_ENV !== "production"
|
|
287
|
-
|| process.env.VIDFARM_DEPLOYMENT_TARGET === "serverless-staging"))
|
|
288
|
-
.map((entry) => [
|
|
289
|
-
path.join(templatesDir, entry.name, "src", "template.js"),
|
|
290
|
-
path.join(templatesDir, entry.name, "src", "template.ts")
|
|
291
|
-
].find((modulePath) => existsSync(modulePath)))
|
|
292
|
-
.filter((modulePath) => Boolean(modulePath))
|
|
293
|
-
.sort((a, b) => a.localeCompare(b));
|
|
294
|
-
}
|
|
295
|
-
export const templateRegistry = new TemplateRegistry();
|
|
296
|
-
//# sourceMappingURL=registry.js.map
|
|
@@ -1,299 +0,0 @@
|
|
|
1
|
-
// /reskin/agency — the Agency / client-workspaces screen, MIGRATED to real
|
|
2
|
-
// production data + behavior (farmville design system).
|
|
3
|
-
//
|
|
4
|
-
// This mirrors src/account-pages-legacy.ts → renderAgencyPage: an agency
|
|
5
|
-
// managing its client sub-accounts. The live page's client list is NOT
|
|
6
|
-
// server-fetched — it is read CLIENT-SIDE from this browser's localStorage
|
|
7
|
-
// account registry (the same cache the app writes when you sign into a client
|
|
8
|
-
// account), so the server can only render an empty shell + template and the
|
|
9
|
-
// real client cards are built in JS. This reskin replicates that exact read and
|
|
10
|
-
// wires the real per-client actions:
|
|
11
|
-
// • "Open workspace" → opens the client's /u/:id/library in a new tab
|
|
12
|
-
// • "Copy login" → copies the client's autologin URL
|
|
13
|
-
// • "Add client login"→ opens /agency-client-login
|
|
14
|
-
// localStorage contract (identical keys/fields to the live page):
|
|
15
|
-
// index key: "vidfarm:agency:accounts:index" → string[] of userIds
|
|
16
|
-
// entry key: "vidfarm:agency:account_<userId>" → { apiKey, email,
|
|
17
|
-
// displayName, lastSeenAt, autologinUrl? }
|
|
18
|
-
// autologinUrl falls back to "/auto-login?api_key=<encodeURIComponent(apiKey)>"
|
|
19
|
-
//
|
|
20
|
-
// The old reskin rendered fabricated per-client stats (projects, scheduled,
|
|
21
|
-
// wallet, seats, plan, status) and aggregate tiles — NONE of those live in the
|
|
22
|
-
// cache, so they are dropped. Cards now show only real cached fields (name,
|
|
23
|
-
// email, user id, last-seen). Avatars are text initials (no emoji).
|
|
24
|
-
import { reskinDocument, rkEscape } from "./document.js";
|
|
25
|
-
export function renderReskinAgency(input = { userId: null, currentAccountId: null, name: null, email: null, loggedIn: false }) {
|
|
26
|
-
const loggedIn = input.loggedIn ?? Boolean(input.userId);
|
|
27
|
-
const signedInHint = loggedIn && input.email
|
|
28
|
-
? `<span class="rk-agency-hint">Managing from ${rkEscape(input.email)}</span>`
|
|
29
|
-
: "";
|
|
30
|
-
const PLUS = `<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 5v14M5 12h14"/></svg>`;
|
|
31
|
-
// The invite / "add a client workspace" card is a static, always-real CTA to
|
|
32
|
-
// the /agency-client-login flow. It lives inside the grid alongside the
|
|
33
|
-
// JS-injected client cards (which render into [data-rk-agency-cards]).
|
|
34
|
-
const inviteCard = `<article class="rk-card rk-agency-invite" data-rk-agency-invite>
|
|
35
|
-
<span class="rk-tile rk-tile-lg rk-tile-gold rk-agency-invite-ic">${PLUS}</span>
|
|
36
|
-
<h3 class="rk-agency-invite-title">Add a client workspace</h3>
|
|
37
|
-
<p class="rk-muted rk-agency-invite-copy">Link a client's account and get an autologin so your team can post on their behalf.</p>
|
|
38
|
-
<a class="rk-btn rk-btn-gold" href="/agency-client-login" target="_blank" rel="noreferrer">Add client login <span class="rk-arrow">→</span></a>
|
|
39
|
-
</article>`;
|
|
40
|
-
const body = `
|
|
41
|
-
<main class="rk-container rk-page">
|
|
42
|
-
<div class="rk-page-head rk-agency-head">
|
|
43
|
-
<div class="rk-agency-head-copy">
|
|
44
|
-
<h1 class="rk-h1">Agency clients</h1>
|
|
45
|
-
<p class="rk-sub">Every client workspace cached on this device — open their library, or copy a one-tap login to post on their behalf.</p>
|
|
46
|
-
</div>
|
|
47
|
-
<div class="rk-agency-head-cta">
|
|
48
|
-
${signedInHint}
|
|
49
|
-
<a class="rk-btn rk-btn-gold rk-btn-lg" href="/agency-client-login" target="_blank" rel="noreferrer">Add client login <span class="rk-arrow">→</span></a>
|
|
50
|
-
</div>
|
|
51
|
-
</div>
|
|
52
|
-
|
|
53
|
-
<section class="rk-agency-panel">
|
|
54
|
-
<div class="rk-spread rk-wrap rk-agency-toolbar">
|
|
55
|
-
<div class="rk-agency-toolbar-copy">
|
|
56
|
-
<span class="rk-eyebrow">Clients</span>
|
|
57
|
-
<h2 class="rk-agency-h2"><span data-rk-agency-count>0</span> client workspace<span data-rk-agency-plural>s</span></h2>
|
|
58
|
-
</div>
|
|
59
|
-
<div class="rk-agency-search-wrap">
|
|
60
|
-
<span class="rk-agency-search-ic" aria-hidden="true"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="7"/><path d="m20 20-3.5-3.5"/></svg></span>
|
|
61
|
-
<input class="rk-input rk-agency-search" type="search" placeholder="Search name, email, or user id" autocomplete="off" spellcheck="false" data-rk-agency-search />
|
|
62
|
-
</div>
|
|
63
|
-
</div>
|
|
64
|
-
<div class="rk-grid rk-grid-3 rk-agency-grid" data-rk-agency-grid>
|
|
65
|
-
<div class="rk-agency-cards" data-rk-agency-cards></div>
|
|
66
|
-
${inviteCard}
|
|
67
|
-
</div>
|
|
68
|
-
<div class="rk-agency-empty" data-rk-agency-empty hidden>
|
|
69
|
-
<p class="rk-muted" data-rk-agency-empty-msg>No cached accounts found in this browser yet.</p>
|
|
70
|
-
</div>
|
|
71
|
-
</section>
|
|
72
|
-
</main>`;
|
|
73
|
-
const pageCss = `
|
|
74
|
-
.rk-agency-head{grid-template-columns:minmax(0,1fr) auto;align-items:end;gap:20px}
|
|
75
|
-
.rk-agency-head-copy{display:grid;gap:4px;min-width:0}
|
|
76
|
-
.rk-agency-head-cta{display:flex;align-items:center;gap:12px;flex:none}
|
|
77
|
-
.rk-agency-hint{font-size:13px;color:var(--rk-text-muted);white-space:normal;overflow-wrap:anywhere}
|
|
78
|
-
@media(max-width:760px){.rk-agency-head{grid-template-columns:1fr}.rk-agency-head-cta{flex-wrap:wrap}}
|
|
79
|
-
|
|
80
|
-
.rk-agency-panel{background:var(--rk-bg-section);border:1px solid var(--rk-border);border-radius:var(--rk-r-3xl);padding:24px}
|
|
81
|
-
.rk-agency-toolbar{margin-bottom:20px}
|
|
82
|
-
.rk-agency-toolbar-copy{display:grid;gap:4px}
|
|
83
|
-
.rk-agency-h2{font-size:var(--rk-text-2xl);letter-spacing:-.02em;color:var(--rk-ink)}
|
|
84
|
-
.rk-agency-search-wrap{position:relative;width:min(360px,100%)}
|
|
85
|
-
.rk-agency-search-ic{position:absolute;left:15px;top:50%;transform:translateY(-50%);font-size:14px;opacity:.6;pointer-events:none}
|
|
86
|
-
.rk-agency-search{padding-left:40px;background:#fff;border-radius:var(--rk-r-full)}
|
|
87
|
-
@media(max-width:620px){.rk-agency-search-wrap{width:100%}}
|
|
88
|
-
|
|
89
|
-
.rk-agency-grid{align-items:stretch}
|
|
90
|
-
/* the JS card wrapper is transparent to the grid so cards + invite share tracks */
|
|
91
|
-
.rk-agency-cards{display:contents}
|
|
92
|
-
.rk-agency-card{padding:22px;display:flex;flex-direction:column;gap:16px}
|
|
93
|
-
.rk-agency-card-top{display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:12px;align-items:start}
|
|
94
|
-
.rk-agency-avatar{font-family:var(--rk-font-display);font-weight:800;font-size:22px}
|
|
95
|
-
.rk-agency-card-id{min-width:0;display:grid;gap:2px}
|
|
96
|
-
.rk-agency-name{font-size:var(--rk-text-lg);font-weight:800;font-family:var(--rk-font-display);color:var(--rk-ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
|
97
|
-
.rk-agency-email{font-size:13px;color:var(--rk-text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;cursor:pointer;transition:color var(--rk-dur) var(--rk-ease)}
|
|
98
|
-
.rk-agency-email:hover{color:var(--rk-gold-700)}
|
|
99
|
-
.rk-agency-seen-pill{flex:none;align-self:start;white-space:nowrap}
|
|
100
|
-
.rk-agency-idrow{display:flex}
|
|
101
|
-
.rk-agency-user{font-family:var(--rk-font-mono);font-size:12px;color:var(--rk-text-faint);cursor:pointer;transition:color var(--rk-dur) var(--rk-ease);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}
|
|
102
|
-
.rk-agency-user:hover{color:var(--rk-n-600)}
|
|
103
|
-
.rk-agency-card-foot{display:flex;align-items:center;flex-wrap:wrap;gap:8px;margin-top:auto}
|
|
104
|
-
.rk-agency-open{font-weight:600}
|
|
105
|
-
|
|
106
|
-
.rk-agency-invite{border-style:dashed;border-color:var(--rk-border-strong);background:linear-gradient(180deg,var(--rk-gold-tint),#fff 70%);display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;gap:12px;min-height:240px}
|
|
107
|
-
.rk-agency-invite-ic{display:grid;place-items:center}
|
|
108
|
-
.rk-agency-invite-title{font-size:var(--rk-text-lg);font-family:var(--rk-font-display);font-weight:800;color:var(--rk-ink)}
|
|
109
|
-
.rk-agency-invite-copy{font-size:13px;max-width:26ch}
|
|
110
|
-
|
|
111
|
-
.rk-agency-empty{display:none;flex-direction:column;align-items:center;gap:12px;padding:56px 20px;text-align:center}
|
|
112
|
-
.rk-agency-empty[data-rk-shown="1"]{display:flex}
|
|
113
|
-
`;
|
|
114
|
-
// Client-side: replicate the live localStorage account-registry read, build
|
|
115
|
-
// real farmville client cards, and wire the real actions. Written with string
|
|
116
|
-
// concatenation (not template literals) to avoid nested-`${}` escaping.
|
|
117
|
-
const script = `
|
|
118
|
-
(function(){
|
|
119
|
-
var ACCOUNT_REGISTRY_INDEX_KEY = "vidfarm:agency:accounts:index";
|
|
120
|
-
var ACCOUNT_REGISTRY_ENTRY_PREFIX = "vidfarm:agency:account_";
|
|
121
|
-
var TINTS = ["gold","sky","violet","green","coral","ink"];
|
|
122
|
-
|
|
123
|
-
var root=document;
|
|
124
|
-
var cardsWrap=root.querySelector('[data-rk-agency-cards]');
|
|
125
|
-
var invite=root.querySelector('[data-rk-agency-invite]');
|
|
126
|
-
var search=root.querySelector('[data-rk-agency-search]');
|
|
127
|
-
var empty=root.querySelector('[data-rk-agency-empty]');
|
|
128
|
-
var emptyMsg=root.querySelector('[data-rk-agency-empty-msg]');
|
|
129
|
-
var countEl=root.querySelector('[data-rk-agency-count]');
|
|
130
|
-
var pluralEl=root.querySelector('[data-rk-agency-plural]');
|
|
131
|
-
var searchQuery="";
|
|
132
|
-
|
|
133
|
-
function escapeHtml(value){
|
|
134
|
-
return String(value==null?"":value)
|
|
135
|
-
.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")
|
|
136
|
-
.replace(/"/g,""").replace(/'/g,"'");
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
function initials(name){
|
|
140
|
-
var letters=String(name||"").replace(/&/g," ").split(/\\s+/)
|
|
141
|
-
.map(function(w){var m=w.match(/[a-z0-9]/i);return m?m[0]:"";})
|
|
142
|
-
.filter(Boolean);
|
|
143
|
-
var out=(letters[0]||"")+(letters[1]||"");
|
|
144
|
-
return (out||"?").toUpperCase();
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
function tintFor(seed){
|
|
148
|
-
var s=String(seed||""),h=0;
|
|
149
|
-
for(var i=0;i<s.length;i++){h=(h*31+s.charCodeAt(i))>>>0;}
|
|
150
|
-
return TINTS[h%TINTS.length];
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
function relTime(iso){
|
|
154
|
-
var t=Date.parse(iso||"");
|
|
155
|
-
if(isNaN(t))return "";
|
|
156
|
-
var diff=Date.now()-t; if(diff<0)diff=0;
|
|
157
|
-
var m=Math.floor(diff/60000);
|
|
158
|
-
if(m<1)return "just now";
|
|
159
|
-
if(m<60)return m+"m ago";
|
|
160
|
-
var hr=Math.floor(m/60);
|
|
161
|
-
if(hr<24)return hr+"h ago";
|
|
162
|
-
var d=Math.floor(hr/24);
|
|
163
|
-
if(d<7)return d+"d ago";
|
|
164
|
-
try{return new Date(t).toLocaleDateString("en-US",{month:"short",day:"numeric"});}catch(_){return d+"d ago";}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
function readAccountIds(){
|
|
168
|
-
try{
|
|
169
|
-
var raw=window.localStorage.getItem(ACCOUNT_REGISTRY_INDEX_KEY);
|
|
170
|
-
var parsed=raw?JSON.parse(raw):[];
|
|
171
|
-
return Array.isArray(parsed)?parsed.filter(function(v){return typeof v==="string"&&v;}):[];
|
|
172
|
-
}catch(_){return [];}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
function readAccounts(){
|
|
176
|
-
return readAccountIds().map(function(userId){
|
|
177
|
-
try{
|
|
178
|
-
var raw=window.localStorage.getItem(ACCOUNT_REGISTRY_ENTRY_PREFIX+userId);
|
|
179
|
-
if(!raw)return null;
|
|
180
|
-
var parsed=JSON.parse(raw);
|
|
181
|
-
if(!parsed||typeof parsed!=="object"||typeof parsed.apiKey!=="string"||!parsed.apiKey)return null;
|
|
182
|
-
return {
|
|
183
|
-
userId:userId,
|
|
184
|
-
email:typeof parsed.email==="string"?parsed.email:"",
|
|
185
|
-
displayName:typeof parsed.displayName==="string"?parsed.displayName:"",
|
|
186
|
-
lastSeenAt:typeof parsed.lastSeenAt==="string"?parsed.lastSeenAt:"",
|
|
187
|
-
autologinUrl:typeof parsed.autologinUrl==="string"?parsed.autologinUrl:"/auto-login?api_key="+encodeURIComponent(parsed.apiKey)
|
|
188
|
-
};
|
|
189
|
-
}catch(_){return null;}
|
|
190
|
-
}).filter(Boolean).sort(function(a,b){return Date.parse(b.lastSeenAt||"")-Date.parse(a.lastSeenAt||"");});
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
function matchesSearch(account){
|
|
194
|
-
var needle=searchQuery.trim().toLowerCase();
|
|
195
|
-
if(!needle)return true;
|
|
196
|
-
return [account.displayName,account.email,account.userId]
|
|
197
|
-
.some(function(v){return String(v||"").toLowerCase().indexOf(needle)!==-1;});
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
function cardHtml(account){
|
|
201
|
-
var title=account.displayName||account.email||account.userId;
|
|
202
|
-
var tint=tintFor(account.userId);
|
|
203
|
-
var seen=relTime(account.lastSeenAt);
|
|
204
|
-
var seenPill=seen?'<span class="rk-pill rk-agency-seen-pill">Active '+escapeHtml(seen)+'</span>':'';
|
|
205
|
-
var openTarget="/u/"+encodeURIComponent(account.userId)+"/library";
|
|
206
|
-
return ''
|
|
207
|
-
+'<article class="rk-card rk-card-hover rk-agency-card">'
|
|
208
|
-
+'<div class="rk-agency-card-top">'
|
|
209
|
-
+'<span class="rk-tile rk-tile-lg rk-tile-'+tint+' rk-agency-avatar">'+escapeHtml(initials(title))+'</span>'
|
|
210
|
-
+'<div class="rk-agency-card-id">'
|
|
211
|
-
+'<h3 class="rk-agency-name">'+escapeHtml(title)+'</h3>'
|
|
212
|
-
+'<div class="rk-agency-email" role="button" tabindex="0" data-rk-copy-text="'+escapeHtml(account.email||"")+'" title="Copy email">'+escapeHtml(account.email||"No email")+'</div>'
|
|
213
|
-
+'</div>'
|
|
214
|
-
+seenPill
|
|
215
|
-
+'</div>'
|
|
216
|
-
+'<div class="rk-agency-idrow">'
|
|
217
|
-
+'<span class="rk-agency-user" role="button" tabindex="0" data-rk-copy-text="'+escapeHtml(account.userId)+'" title="Copy user id">User '+escapeHtml(account.userId)+'</span>'
|
|
218
|
-
+'</div>'
|
|
219
|
-
+'<div class="rk-agency-card-foot">'
|
|
220
|
-
+'<button class="rk-btn rk-btn-ink rk-btn-sm rk-agency-open" type="button" data-rk-open-tab="'+escapeHtml(openTarget)+'">Open workspace <span class="rk-arrow">→</span></button>'
|
|
221
|
-
+'<button class="rk-btn rk-btn-ghost rk-btn-sm" type="button" data-rk-copy-login="'+escapeHtml(account.autologinUrl)+'">Copy login</button>'
|
|
222
|
-
+'</div>'
|
|
223
|
-
+'</article>';
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
function flash(el,label){
|
|
227
|
-
if(!el)return;
|
|
228
|
-
var prev=el.textContent;
|
|
229
|
-
el.textContent=label;
|
|
230
|
-
window.setTimeout(function(){el.textContent=prev;},1300);
|
|
231
|
-
}
|
|
232
|
-
function copy(value,el){
|
|
233
|
-
if(!value)return;
|
|
234
|
-
if(navigator.clipboard&&navigator.clipboard.writeText){
|
|
235
|
-
navigator.clipboard.writeText(value).then(function(){flash(el,"Copied");},function(){flash(el,"Clipboard blocked");});
|
|
236
|
-
}else{flash(el,"Clipboard blocked");}
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
function wire(){
|
|
240
|
-
if(!cardsWrap)return;
|
|
241
|
-
cardsWrap.querySelectorAll('[data-rk-copy-text]').forEach(function(el){
|
|
242
|
-
var run=function(){copy(el.getAttribute('data-rk-copy-text'),el);};
|
|
243
|
-
el.addEventListener('click',run);
|
|
244
|
-
el.addEventListener('keydown',function(e){if(e.key==='Enter'||e.key===' '){e.preventDefault();run();}});
|
|
245
|
-
});
|
|
246
|
-
cardsWrap.querySelectorAll('[data-rk-copy-login]').forEach(function(btn){
|
|
247
|
-
btn.addEventListener('click',function(){
|
|
248
|
-
var rel=btn.getAttribute('data-rk-copy-login')||'';
|
|
249
|
-
var abs=rel;try{abs=new URL(rel,window.location.origin).toString();}catch(_){}
|
|
250
|
-
copy(abs,btn);
|
|
251
|
-
});
|
|
252
|
-
});
|
|
253
|
-
cardsWrap.querySelectorAll('[data-rk-open-tab]').forEach(function(btn){
|
|
254
|
-
btn.addEventListener('click',function(){
|
|
255
|
-
var target=btn.getAttribute('data-rk-open-tab');
|
|
256
|
-
if(target)window.open(target,'_blank','noopener,noreferrer');
|
|
257
|
-
});
|
|
258
|
-
});
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
function render(){
|
|
262
|
-
if(!cardsWrap)return;
|
|
263
|
-
var accounts=readAccounts();
|
|
264
|
-
var total=accounts.length;
|
|
265
|
-
if(countEl)countEl.textContent=String(total);
|
|
266
|
-
if(pluralEl)pluralEl.textContent=total===1?'':'s';
|
|
267
|
-
|
|
268
|
-
var filtered=accounts.filter(matchesSearch);
|
|
269
|
-
cardsWrap.innerHTML=filtered.map(cardHtml).join('');
|
|
270
|
-
wire();
|
|
271
|
-
|
|
272
|
-
// hide the "add client" invite while actively searching (it isn't a result)
|
|
273
|
-
if(invite)invite.hidden=!!searchQuery.trim();
|
|
274
|
-
|
|
275
|
-
if(empty&&emptyMsg){
|
|
276
|
-
var showEmpty=false,msg='';
|
|
277
|
-
if(total===0){showEmpty=true;msg='No cached accounts found in this browser yet.';}
|
|
278
|
-
else if(filtered.length===0){showEmpty=true;msg='No agency clients match that search.';}
|
|
279
|
-
emptyMsg.textContent=msg;
|
|
280
|
-
empty.hidden=!showEmpty;
|
|
281
|
-
empty.setAttribute('data-rk-shown',showEmpty?'1':'0');
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
if(search){
|
|
286
|
-
search.addEventListener('input',function(){searchQuery=search.value||'';render();});
|
|
287
|
-
}
|
|
288
|
-
render();
|
|
289
|
-
})();`;
|
|
290
|
-
return reskinDocument({
|
|
291
|
-
title: "vidfarm reskin — Agency",
|
|
292
|
-
description: "Reskinned vidfarm agency page — cached client workspaces, open library, copy autologin.",
|
|
293
|
-
activeSlug: "agency",
|
|
294
|
-
pageCss,
|
|
295
|
-
body,
|
|
296
|
-
script
|
|
297
|
-
});
|
|
298
|
-
}
|
|
299
|
-
//# sourceMappingURL=agency-page.js.map
|