@officexapp/vidfarm-devcli 0.21.28 → 0.21.30

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 (30) hide show
  1. package/.agents/skills/editor-capabilities/SKILL.md +26 -0
  2. package/.agents/skills/vidfarm/SKILL.md +53 -2
  3. package/.agents/skills/vidfarm/recipes/bulk-scripting-with-a-regime.md +65 -0
  4. package/.agents/skills/vidfarm/recipes/cutout-graphics-for-explainers.md +78 -7
  5. package/.agents/skills/vidfarm/recipes/local-edit-render-approve.md +2 -2
  6. package/.agents/skills/vidfarm/recipes/retheme-template.md +1 -1
  7. package/.agents/skills/vidfarm/references/automation-and-local-dev.md +66 -5
  8. package/.agents/skills/vidfarm/references/editor-workflows.md +94 -1
  9. package/.agents/skills/vidfarm/references/hooks-and-virality.md +237 -0
  10. package/.agents/skills/vidfarm/references/onboarding.md +1 -1
  11. package/.agents/skills/vidfarm/regimes/README.md +77 -0
  12. package/.agents/skills/vidfarm/regimes/explainer.QA_REGIME.md +82 -0
  13. package/.agents/skills/vidfarm/regimes/hooks.QA_REGIME.md +117 -0
  14. package/.agents/skills/vidfarm/regimes/product-demo.QA_REGIME.md +92 -0
  15. package/.agents/skills/vidfarm/regimes/short-form.QA_REGIME.md +163 -0
  16. package/.agents/skills/vidfarm/regimes/ugc-testimonial.QA_REGIME.md +82 -0
  17. package/SKILL.director.md +599 -19
  18. package/SKILL.md +18 -2
  19. package/demo/dist/app.js +103 -103
  20. package/dist/src/cli.js +925 -18
  21. package/dist/src/devcli/doctor.js +13 -0
  22. package/dist/src/devcli/handoff.js +162 -0
  23. package/dist/src/devcli/hyperframes-cli.js +12 -0
  24. package/dist/src/devcli/interaction-mode.js +154 -0
  25. package/dist/src/devcli/qa-check.js +173 -0
  26. package/dist/src/devcli/qa-regime.js +396 -0
  27. package/dist/src/devcli/sticker-pack.js +396 -0
  28. package/dist/src/devcli/storyboard.js +243 -0
  29. package/dist/src/devcli/studio-brand.js +196 -0
  30. package/package.json +8 -1
@@ -0,0 +1,196 @@
1
+ // Whitelabel the LOCAL hyperframes Studio UI as VidFarm.
2
+ //
3
+ // The web editor (`/editor`, `vidfarm serve`) mounts the sealed <StudioApp/>
4
+ // through demo/src/VidfarmStudioEditor.tsx, which already swaps the upstream
5
+ // "HeyGen · HyperFrames" header logo and rewrites the product name in copy.
6
+ // But `hyperframes preview` (and `vidfarm hf preview`) boots the studio SPA
7
+ // straight out of `node_modules/hyperframes/dist/studio/index.html` — that
8
+ // bundle never passes through our editor entry, so it renders upstream branding
9
+ // on a Vidfarm director's screen.
10
+ //
11
+ // The studio server reads that index.html **per request** (studioServer.ts's
12
+ // SPA fallback), so a one-time on-disk patch of the shell is enough: no fork, no
13
+ // dist rewriting of the JS, no proxy in the middle. We inject a marker-delimited
14
+ // <style> + <script> block that does exactly what the web editor does in JS —
15
+ // hide `svg[aria-label="Hyperframes"]`, insert a VidFarm wordmark, and rename
16
+ // the product in text nodes / tooltips / clipboard writes.
17
+ //
18
+ // The patch is idempotent and versioned: a stale block is replaced, an up-to-date
19
+ // one is left alone, and a fresh `npm install` (which restores the pristine file)
20
+ // is re-patched on the next hyperframes spawn. `.hyperframes/` paths, the
21
+ // `data-hyperframes-*` DOM hooks, and CLI verbs are deliberately preserved /
22
+ // mapped, same as the web editor — renaming those would send an agent hunting
23
+ // for files that do not exist.
24
+ import { existsSync, readFileSync, writeFileSync } from "node:fs";
25
+ import path from "node:path";
26
+ import { resolveHyperframesCli } from "./hyperframes-cli.js";
27
+ /** Bump when the injected block changes — older blocks are replaced in place. */
28
+ const BRAND_VERSION = 1;
29
+ const MARK_OPEN = `<!-- vidfarm-studio-brand v${BRAND_VERSION} -->`;
30
+ const MARK_OPEN_ANY = /<!-- vidfarm-studio-brand v\d+ -->/;
31
+ const MARK_CLOSE = "<!-- /vidfarm-studio-brand -->";
32
+ // Tab icon: a self-contained gold "V" plate (data URI, so we never have to ship
33
+ // or overwrite a file inside the hyperframes package). Matches the header
34
+ // wordmark's badge below.
35
+ const VIDFARM_FAVICON = "data:image/svg+xml," +
36
+ encodeURIComponent('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">' +
37
+ '<rect width="100" height="100" rx="26" fill="#f5c518"/>' +
38
+ '<path d="M26 28h14l10 30 10-30h14L58 76H42z" fill="#1c1608"/>' +
39
+ "</svg>");
40
+ /**
41
+ * Locate `hyperframes/dist/studio/index.html` next to the resolved CLI entry.
42
+ * Returns null when hyperframes is not installed locally (the `npx -y` fallback
43
+ * path — nothing on disk of ours to patch).
44
+ */
45
+ export function resolveStudioIndexPath() {
46
+ const cli = resolveHyperframesCli();
47
+ if (!cli)
48
+ return null;
49
+ const indexPath = path.join(path.dirname(cli), "studio", "index.html");
50
+ return existsSync(indexPath) ? indexPath : null;
51
+ }
52
+ /** The injected head block: hide the upstream mark, paint ours, rename the product. */
53
+ function brandBlock() {
54
+ return `${MARK_OPEN}
55
+ <style>
56
+ /* Belt-and-suspenders: kill the upstream mark before the script runs so it
57
+ never flashes. The wordmark below is inserted in its place. */
58
+ svg[aria-label="Hyperframes"] { display: none !important; }
59
+ </style>
60
+ <script>
61
+ (function () {
62
+ var MARK = "data-vidfarm-logo";
63
+
64
+ function wordmark() {
65
+ var el = document.createElement("div");
66
+ el.setAttribute(MARK, "");
67
+ el.style.cssText = "display:inline-flex;align-items:center;gap:8px;user-select:none;line-height:1";
68
+ var badge = document.createElement("span");
69
+ badge.style.cssText =
70
+ "display:inline-grid;place-items:center;width:24px;height:24px;border-radius:7px;" +
71
+ "background:#f5c518;color:#1c1608;font-weight:800;font-size:14px;font-family:system-ui,sans-serif";
72
+ badge.textContent = "V";
73
+ var word = document.createElement("span");
74
+ word.style.cssText =
75
+ "font-weight:800;font-size:15px;letter-spacing:-.01em;color:#fffbe6;font-family:system-ui,sans-serif";
76
+ word.textContent = "VidFarm";
77
+ el.appendChild(badge);
78
+ el.appendChild(word);
79
+ return el;
80
+ }
81
+
82
+ function swapLogo() {
83
+ var logos = document.querySelectorAll('svg[aria-label="Hyperframes"]');
84
+ for (var i = 0; i < logos.length; i += 1) {
85
+ var svg = logos[i];
86
+ var prev = svg.previousElementSibling;
87
+ if ((prev && prev.hasAttribute && prev.hasAttribute(MARK)) || svg.getAttribute("data-vidfarm-hidden") === "1") continue;
88
+ svg.setAttribute("data-vidfarm-hidden", "1");
89
+ svg.style.display = "none";
90
+ if (svg.parentElement) svg.parentElement.insertBefore(wordmark(), svg);
91
+ }
92
+ }
93
+
94
+ // Same rewrite table as the web editor: CLI verbs and .hyperframes/ paths are
95
+ // matched BEFORE the bare product name, so real files/commands survive.
96
+ function rewrite(text) {
97
+ return text
98
+ .replace(/\\bhyperframes (render|preview|lint|check|publish|init|add)\\b/g, "vidfarm $1")
99
+ .replace(/(^|[^./\\w-])[Hh]yper[Ff]rames(?![./\\w-])/g, "$1Vidfarm")
100
+ .replace(/(^|[^./\\w-])[Hh]yper[Ff]rame(?![s./\\w-])/g, "$1Vidfarm")
101
+ .replace(/\\bHeyGen\\b/g, "Vidfarm");
102
+ }
103
+
104
+ function needsRewrite(text) {
105
+ return /[Hh]yper[Ff]rame|HeyGen/.test(text) && rewrite(text) !== text;
106
+ }
107
+
108
+ function swapText() {
109
+ var walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT);
110
+ var pending = [];
111
+ for (var node = walker.nextNode(); node; node = walker.nextNode()) {
112
+ var tag = node.parentElement && node.parentElement.tagName;
113
+ if (tag === "SCRIPT" || tag === "STYLE") continue;
114
+ if (needsRewrite(node.nodeValue || "")) pending.push(node);
115
+ }
116
+ for (var i = 0; i < pending.length; i += 1) pending[i].nodeValue = rewrite(pending[i].nodeValue || "");
117
+ var attrs = ["title", "aria-label", "placeholder"];
118
+ var els = document.querySelectorAll("[title],[aria-label],[placeholder]");
119
+ for (var j = 0; j < els.length; j += 1) {
120
+ for (var k = 0; k < attrs.length; k += 1) {
121
+ var value = els[j].getAttribute(attrs[k]);
122
+ if (value && needsRewrite(value)) els[j].setAttribute(attrs[k], rewrite(value));
123
+ }
124
+ }
125
+ }
126
+
127
+ function apply() {
128
+ swapLogo();
129
+ swapText();
130
+ }
131
+
132
+ function start() {
133
+ apply();
134
+ new MutationObserver(apply).observe(document.body, { childList: true, subtree: true, characterData: true });
135
+ // Lint / storyboard panels hand agent prompts to the clipboard — rebrand on the way out.
136
+ try {
137
+ if (navigator.clipboard && navigator.clipboard.writeText) {
138
+ var original = navigator.clipboard.writeText.bind(navigator.clipboard);
139
+ navigator.clipboard.writeText = function (data) {
140
+ return original(typeof data === "string" ? rewrite(data) : data);
141
+ };
142
+ }
143
+ } catch (err) { /* clipboard locked down — branding is best-effort */ }
144
+ }
145
+
146
+ if (document.body) start();
147
+ else document.addEventListener("DOMContentLoaded", start);
148
+ })();
149
+ </script>
150
+ ${MARK_CLOSE}`;
151
+ }
152
+ /**
153
+ * Patch the installed studio shell in place. Never throws — a read-only or
154
+ * missing node_modules just means the director sees upstream branding, which is
155
+ * cosmetic and must not fail a render.
156
+ */
157
+ export function applyVidfarmStudioBrand(indexPathOverride) {
158
+ const indexPath = indexPathOverride ?? resolveStudioIndexPath();
159
+ if (!indexPath)
160
+ return "unavailable";
161
+ let html;
162
+ try {
163
+ html = readFileSync(indexPath, "utf-8");
164
+ }
165
+ catch {
166
+ return "unavailable";
167
+ }
168
+ const current = brandBlock();
169
+ if (html.includes(MARK_OPEN) && html.includes(MARK_CLOSE)) {
170
+ // Up-to-date block already present (same version) — but the block body can
171
+ // still drift if BRAND_VERSION was not bumped during development, so compare.
172
+ if (html.includes(current))
173
+ return "already-branded";
174
+ }
175
+ // Strip any previous (older-version or drifted) block before re-injecting.
176
+ let out = html.replace(new RegExp(`${MARK_OPEN_ANY.source}[\\s\\S]*?${MARK_CLOSE.replace(/[/]/g, "\\/")}`), "");
177
+ out = out.replace(/<title>[\s\S]*?<\/title>/, "<title>VidFarm Studio</title>");
178
+ // Tab icon (no-op once already swapped — the upstream href is gone by then).
179
+ out = out.replace(/href="\/favicon\.svg"/, `href="${VIDFARM_FAVICON}"`);
180
+ if (out.includes("</head>")) {
181
+ out = out.replace("</head>", `${current}\n </head>`);
182
+ }
183
+ else {
184
+ out = `${current}\n${out}`;
185
+ }
186
+ if (out === html)
187
+ return "already-branded";
188
+ try {
189
+ writeFileSync(indexPath, out, "utf-8");
190
+ }
191
+ catch {
192
+ return "unavailable";
193
+ }
194
+ return "patched";
195
+ }
196
+ //# sourceMappingURL=studio-brand.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@officexapp/vidfarm-devcli",
3
- "version": "0.21.28",
3
+ "version": "0.21.30",
4
4
  "description": "Local bridge for the Vidfarm Trackpad Editor. `vidfarm serve <template_id>` boots the FULL editor on localhost (disk-backed records/storage, free in-process render); edit composition.html on disk (Claude Code, Codex, etc.) and the browser live-morphs it.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -17,18 +17,24 @@
17
17
  "dist/src/devcli/composition-edit.js",
18
18
  "dist/src/devcli/cost-mode.js",
19
19
  "dist/src/devcli/doctor.js",
20
+ "dist/src/devcli/handoff.js",
20
21
  "dist/src/devcli/greenscreen-local.js",
21
22
  "dist/src/devcli/hyperframes-cli.js",
23
+ "dist/src/devcli/interaction-mode.js",
22
24
  "dist/src/devcli/local-backend.js",
23
25
  "dist/src/devcli/local-frontend-server.js",
24
26
  "dist/src/devcli/local-render.js",
25
27
  "dist/src/devcli/port-utils.js",
26
28
  "dist/src/devcli/process-scan.js",
27
29
  "dist/src/devcli/qa-check.js",
30
+ "dist/src/devcli/qa-regime.js",
28
31
  "dist/src/devcli/sequence.js",
29
32
  "dist/src/devcli/skills.js",
30
33
  "dist/src/devcli/speech.js",
34
+ "dist/src/devcli/sticker-pack.js",
35
+ "dist/src/devcli/studio-brand.js",
31
36
  "dist/src/devcli/stills.js",
37
+ "dist/src/devcli/storyboard.js",
32
38
  "dist/src/devcli/telemetry.js",
33
39
  "dist/src/devcli/timeline-edit.js",
34
40
  "dist/src/devcli/transitions.js",
@@ -88,6 +94,7 @@
88
94
  "check": "tsc -p tsconfig.json --noEmit && npm run check:skills",
89
95
  "test:clips": "node --import tsx --test test/clip-curation.test.ts",
90
96
  "test:qa": "node --import tsx --test test/qa-check.test.ts",
97
+ "test:studio-brand": "node --import tsx --test test/studio-brand.test.ts",
91
98
  "check:skills": "node scripts/build-director-skill-rollup.mjs --check && node scripts/check-skill-routes.mjs",
92
99
  "benchmark:editor-chat": "node --import tsx scripts/benchmark-editor-chat-harness.mjs",
93
100
  "cdk:deploy:prod-serverless": "npm run build && dotenv -e .env.production -- npx aws-cdk deploy --app 'node dist/infra/cdk/bin/vidfarm-prod.js'",