@keepylabs/cutroom 0.5.5 → 0.5.7
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/cutroom.mjs +32 -12
- package/package.json +1 -1
package/cutroom.mjs
CHANGED
|
@@ -8,7 +8,25 @@ var __export = (target, all) => {
|
|
|
8
8
|
|
|
9
9
|
// src/community/local/server.ts
|
|
10
10
|
import { homedir as homedir3 } from "node:os";
|
|
11
|
-
import { join as join4 } from "node:path";
|
|
11
|
+
import { delimiter, join as join4 } from "node:path";
|
|
12
|
+
|
|
13
|
+
// src/community/local/proc.ts
|
|
14
|
+
import { spawnSync } from "node:child_process";
|
|
15
|
+
var WIN = process.platform === "win32";
|
|
16
|
+
var quote = (a) => /[\s"&|<>^()%!,;=']/.test(a) ? `"${a.replace(/"/g, '\\"')}"` : a;
|
|
17
|
+
function run(cmd, args, opt = {}) {
|
|
18
|
+
const o = { encoding: "utf8", ...opt };
|
|
19
|
+
if (WIN && cmd === "npx") return spawnSync(["npx", ...args].map(quote).join(" "), { ...o, shell: true });
|
|
20
|
+
return spawnSync(cmd, args, o);
|
|
21
|
+
}
|
|
22
|
+
var has = (bin) => spawnSync(WIN ? "where" : "which", [bin], { stdio: "ignore" }).status === 0;
|
|
23
|
+
var installLine = (tool) => WIN ? { ffmpeg: "winget install --id Gyan.FFmpeg -e", node: "winget install --id OpenJS.NodeJS.LTS -e", "node-update": "winget upgrade --id OpenJS.NodeJS.LTS -e" }[tool] : { ffmpeg: "brew install ffmpeg", node: "brew install node", "node-update": "brew upgrade node" }[tool];
|
|
24
|
+
var NODE_MIN = 22;
|
|
25
|
+
function nodeMajor() {
|
|
26
|
+
const r = spawnSync("node", ["--version"], { encoding: "utf8", shell: WIN });
|
|
27
|
+
const m = (r.stdout ?? "").match(/v(\d+)/);
|
|
28
|
+
return m ? Number(m[1]) : 0;
|
|
29
|
+
}
|
|
12
30
|
|
|
13
31
|
// node_modules/@modelcontextprotocol/server/dist/chunk-Br0eD_fh.mjs
|
|
14
32
|
var __create = Object.create;
|
|
@@ -21541,10 +21559,10 @@ import { homedir as homedir2 } from "node:os";
|
|
|
21541
21559
|
import { basename, extname, join as join3, resolve as resolve2 } from "node:path";
|
|
21542
21560
|
|
|
21543
21561
|
// src/community/local/measure.ts
|
|
21544
|
-
import { execFileSync, spawnSync } from "node:child_process";
|
|
21562
|
+
import { execFileSync, spawnSync as spawnSync2 } from "node:child_process";
|
|
21545
21563
|
import { mkdirSync, readFileSync } from "node:fs";
|
|
21546
21564
|
import { join } from "node:path";
|
|
21547
|
-
var ffmpegErr = (args) =>
|
|
21565
|
+
var ffmpegErr = (args) => spawnSync2("ffmpeg", ["-nostdin", "-hide_banner", ...args], { encoding: "utf8", maxBuffer: 64 * 1024 * 1024 }).stderr ?? "";
|
|
21548
21566
|
function probe(file) {
|
|
21549
21567
|
const info = JSON.parse(execFileSync("ffprobe", ["-v", "error", "-print_format", "json", "-show_format", "-show_streams", file], { encoding: "utf8" }));
|
|
21550
21568
|
const v = info.streams.find((s) => s.codec_type === "video");
|
|
@@ -21635,13 +21653,12 @@ function technicalChecks(file) {
|
|
|
21635
21653
|
}
|
|
21636
21654
|
|
|
21637
21655
|
// src/community/local/tools.ts
|
|
21638
|
-
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
21639
21656
|
import { createWriteStream, existsSync, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync } from "node:fs";
|
|
21640
21657
|
import { homedir } from "node:os";
|
|
21641
21658
|
import { join as join2, resolve } from "node:path";
|
|
21642
21659
|
import { Readable } from "node:stream";
|
|
21643
21660
|
import { pipeline } from "node:stream/promises";
|
|
21644
|
-
var VERSION = "0.5.
|
|
21661
|
+
var VERSION = "0.5.7";
|
|
21645
21662
|
var GATEWAY = () => (process.env.CUTROOM_GATEWAY || "https://keepylabs.com/api/cutroom").replace(/\/$/, "");
|
|
21646
21663
|
var HOME = () => process.env.CUTROOM_HOME || join2(homedir(), "Cutroom");
|
|
21647
21664
|
async function call(op, body = {}, fetchImpl = fetch) {
|
|
@@ -21663,7 +21680,6 @@ async function call(op, body = {}, fetchImpl = fetch) {
|
|
|
21663
21680
|
if (!res.ok) throw new Error(json?.error ?? `Cutroom error (HTTP ${res.status}).`);
|
|
21664
21681
|
return json;
|
|
21665
21682
|
}
|
|
21666
|
-
var has = (bin) => spawnSync2("which", [bin]).status === 0;
|
|
21667
21683
|
var slug = (s) => s.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 40);
|
|
21668
21684
|
var day = () => (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
21669
21685
|
var fmt = (t) => `${Math.floor(t / 60)}:${(t % 60).toFixed(1).padStart(4, "0")}`;
|
|
@@ -21675,8 +21691,12 @@ async function download(url2, target) {
|
|
|
21675
21691
|
}
|
|
21676
21692
|
async function doctor() {
|
|
21677
21693
|
const checks = [
|
|
21678
|
-
{ name: "ffmpeg", ok: has("ffmpeg") && has("ffprobe"), fix: "
|
|
21679
|
-
|
|
21694
|
+
{ name: "ffmpeg", ok: has("ffmpeg") && has("ffprobe"), fix: installLine("ffmpeg") },
|
|
21695
|
+
(() => {
|
|
21696
|
+
const v = has("npx") ? nodeMajor() : 0;
|
|
21697
|
+
if (!v) return { name: "Node.js (for rendering)", ok: false, fix: installLine("node") };
|
|
21698
|
+
return v >= NODE_MIN ? { name: `Node.js ${v} (for rendering)`, ok: true } : { name: `Node.js ${v} is too old (rendering needs ${NODE_MIN} or newer)`, ok: false, fix: installLine("node-update") };
|
|
21699
|
+
})()
|
|
21680
21700
|
];
|
|
21681
21701
|
let member = null;
|
|
21682
21702
|
try {
|
|
@@ -21700,7 +21720,7 @@ function beatBounds(duration3, cuts, words) {
|
|
|
21700
21720
|
return [...out, duration3];
|
|
21701
21721
|
}
|
|
21702
21722
|
function localWords(file, dir) {
|
|
21703
|
-
const r =
|
|
21723
|
+
const r = run("npx", ["--yes", "hyperframes@0.8.99", "transcribe", file, "--json", "-d", dir], { cwd: dir, encoding: "utf8", maxBuffer: 1 << 28 });
|
|
21704
21724
|
try {
|
|
21705
21725
|
const meta2 = JSON.parse(r.stdout.trim().split("\n").pop() ?? "{}");
|
|
21706
21726
|
if (r.status !== 0 || !meta2.ok) return null;
|
|
@@ -21880,7 +21900,7 @@ async function creatorTeardown(input) {
|
|
|
21880
21900
|
var HF = "hyperframes@0.8.99";
|
|
21881
21901
|
var day2 = () => (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
21882
21902
|
var slug2 = (s) => s.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 40) || "reel";
|
|
21883
|
-
var sh = (cmd, args, cwd) =>
|
|
21903
|
+
var sh = (cmd, args, cwd) => run(cmd, args, { cwd, encoding: "utf8", maxBuffer: 256 * 1024 * 1024 });
|
|
21884
21904
|
var tail = (s) => (s ?? "").trim().split("\n").slice(-6).join("\n");
|
|
21885
21905
|
var projectFile = (folder) => join3(folder, ".cutroom", "project.json");
|
|
21886
21906
|
var resolveProject = (p) => {
|
|
@@ -22223,13 +22243,13 @@ async function qaVideo(input) {
|
|
|
22223
22243
|
}
|
|
22224
22244
|
|
|
22225
22245
|
// src/community/local/server.ts
|
|
22226
|
-
process.env.PATH = [process.env.PATH, "/opt/homebrew/bin", "/usr/local/bin", join4(homedir3(), ".local", "bin")].filter(Boolean).join(
|
|
22246
|
+
process.env.PATH = (WIN ? [process.env.PATH, join4(process.env.LOCALAPPDATA ?? join4(homedir3(), "AppData", "Local"), "Microsoft", "WinGet", "Links"), "C:\\Program Files\\nodejs"] : [process.env.PATH, "/opt/homebrew/bin", "/usr/local/bin", join4(homedir3(), ".local", "bin")]).filter(Boolean).join(delimiter);
|
|
22227
22247
|
var result = (value) => ({ content: [{ type: "text", text: typeof value === "string" ? value : JSON.stringify(value, null, 2) }] });
|
|
22228
22248
|
var failure2 = (error2) => ({ isError: true, content: [{ type: "text", text: error2 instanceof Error ? error2.message : String(error2) }] });
|
|
22229
22249
|
var safe = (op) => Promise.resolve().then(op).then(result).catch(failure2);
|
|
22230
22250
|
var INSTRUCTIONS = `Cutroom: short-form video help. Speak plainly; the user is not technical. Never show tool or effect codes; use plain names.
|
|
22231
22251
|
|
|
22232
|
-
Setup or any failure: cutroom_doctor, then a short checklist. Missing ffmpeg or Node.js: ask, then run
|
|
22252
|
+
Setup or any failure: cutroom_doctor, then a short checklist. Missing ffmpeg or Node.js: ask, then run the fix line cutroom_doctor gives (brew on a Mac, winget on Windows). Key problem: reconnect Cutroom with their key from the Cutroom key space on Whop; never ask them to paste the key into the chat.
|
|
22233
22253
|
|
|
22234
22254
|
Finish a video (a raw video of them talking: edit it, captions, effects, make it a reel): get_method('finish_video') first and follow it step by step. Nothing renders until they approve the plan.
|
|
22235
22255
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@keepylabs/cutroom",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.7",
|
|
4
4
|
"description": "Cutroom for Claude Code: hooks and scripts with scoring, reel breakdowns, creator teardowns, and finishing your own videos with QA. Needs a Keepy Labs membership key.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|