demobite 1.0.5 → 1.0.6
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/package.json +1 -1
- package/scripts/record.mjs +14 -0
- package/skill/SKILL.md +2 -1
- package/skill/scripts/upload.mjs +14 -1
package/package.json
CHANGED
package/scripts/record.mjs
CHANGED
|
@@ -36,6 +36,20 @@ for (const [i, s] of STORYBOARD.steps.entries()) {
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
const DIR = path.resolve(outArg);
|
|
39
|
+
|
|
40
|
+
// RE-TAKE (founder 2026-09-02): the storyboard IS the bite's DNA. Keep a verbatim
|
|
41
|
+
// copy in the take dir so upload.mjs can stage it as the recording recipe —
|
|
42
|
+
// selectors, urls, typed text, hideCss — the wire manifest alone cannot re-film.
|
|
43
|
+
const ENGINE_VERSION = "1.0.6";
|
|
44
|
+
fs.mkdirSync(DIR, { recursive: true });
|
|
45
|
+
fs.writeFileSync(path.join(DIR, "storyboard.json"), JSON.stringify(STORYBOARD, null, 2));
|
|
46
|
+
try {
|
|
47
|
+
const cfgPath = path.resolve(".recorder/config.json");
|
|
48
|
+
const cfg = fs.existsSync(cfgPath) ? JSON.parse(fs.readFileSync(cfgPath, "utf8")) : {};
|
|
49
|
+
// Only the public shape — NEVER the api_key or workspace.
|
|
50
|
+
const config = { app: STORYBOARD.app ?? cfg.app ?? null, url: STORYBOARD.url ?? cfg.url ?? null, frame: cfg.frame ?? { width: 1920, height: 1080 }, base: cfg.base ?? "https://app.demobites.com" };
|
|
51
|
+
fs.writeFileSync(path.join(DIR, "recipe.json"), JSON.stringify({ version: 1, lane: "skill", engine: ENGINE_VERSION, config }, null, 2));
|
|
52
|
+
} catch (e) { console.error("recipe.json not written:", e.message); }
|
|
39
53
|
fs.mkdirSync(DIR, { recursive: true });
|
|
40
54
|
|
|
41
55
|
// LAW (supersampled capture, measured 2026-08-09): deviceScaleFactor is a
|
package/skill/SKILL.md
CHANGED
|
@@ -281,7 +281,8 @@ DELETE <base>/api/recorder/key (Authorization: Bearer <api_key>)
|
|
|
281
281
|
-> { revoked: true } (logout)
|
|
282
282
|
|
|
283
283
|
PUT <base>/api/recorder/stage (Authorization: Bearer <api_key>)
|
|
284
|
-
{ filename, sizeBytes, previewSizeBytes, manifest }
|
|
284
|
+
{ filename, sizeBytes, previewSizeBytes, manifest, recipe? }
|
|
285
|
+
// recipe = { version:1, lane:'skill', engine, storyboard, config:{app,url,frame,base} } — the RE-TAKE DNA (never the api_key)
|
|
285
286
|
-> { stagingId, uploadUrl, previewUploadUrl, videoKey, previewUrl }
|
|
286
287
|
|
|
287
288
|
GET <base>/api/recorder/stage?id=<stagingId> (Authorization: Bearer <api_key>)
|
package/skill/scripts/upload.mjs
CHANGED
|
@@ -40,6 +40,19 @@ const base = cfg.base.replace(/\/+$/, "");
|
|
|
40
40
|
|
|
41
41
|
const cleanPath = path.join(dir, "clean.mp4");
|
|
42
42
|
const wirePath = path.join(dir, "manifest.demobites.json");
|
|
43
|
+
// Recording recipe (RE-TAKE, 2026-09-02): storyboard + public config, written by
|
|
44
|
+
// record.mjs. Staged next to the manifest so the bite can be re-filmed later.
|
|
45
|
+
// Absent on takes filmed by older engines — staging still works without it.
|
|
46
|
+
let recipe = null;
|
|
47
|
+
try {
|
|
48
|
+
const sbPath = path.join(dir, "storyboard.json");
|
|
49
|
+
const rcPath = path.join(dir, "recipe.json");
|
|
50
|
+
if (fs.existsSync(sbPath)) {
|
|
51
|
+
const rc = fs.existsSync(rcPath) ? JSON.parse(fs.readFileSync(rcPath, "utf8")) : {};
|
|
52
|
+
recipe = { version: 1, lane: rc.lane ?? "skill", engine: rc.engine ?? null, storyboard: JSON.parse(fs.readFileSync(sbPath, "utf8")), config: rc.config ?? {} };
|
|
53
|
+
if (recipe.config && "api_key" in recipe.config) delete recipe.config.api_key;
|
|
54
|
+
}
|
|
55
|
+
} catch (e) { console.error("recipe skipped:", e.message); }
|
|
43
56
|
if (!fs.existsSync(cleanPath)) { console.error(`${cleanPath} not found. Run: node scripts/trim.mjs ${dir}`); process.exit(1); }
|
|
44
57
|
if (!fs.existsSync(wirePath)) { console.error(`${wirePath} not found. Run: node scripts/manifest.mjs ${dir}`); process.exit(1); }
|
|
45
58
|
const manifest = JSON.parse(fs.readFileSync(wirePath, "utf8"));
|
|
@@ -124,7 +137,7 @@ try {
|
|
|
124
137
|
stageRes = await fetch(`${base}/api/recorder/stage`, {
|
|
125
138
|
method: "PUT",
|
|
126
139
|
headers: authHeaders,
|
|
127
|
-
body: JSON.stringify({ filename: "take.zip", sizeBytes, previewSizeBytes, manifest }),
|
|
140
|
+
body: JSON.stringify({ filename: "take.zip", sizeBytes, previewSizeBytes, manifest, ...(recipe ? { recipe } : {}) }),
|
|
128
141
|
});
|
|
129
142
|
} catch (e) {
|
|
130
143
|
console.error(`Could not reach ${base}: ${e.message}`);
|