@higgsfield/video-editor-mcp 1.1.1-dev.0 → 2.0.0

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 (59) hide show
  1. package/README.md +63 -26
  2. package/dist/cli.mjs +284 -112
  3. package/dist/guide.md +2 -3
  4. package/dist/index.html +1 -1
  5. package/dist/launcher.mjs +34 -14
  6. package/dist/server.mjs +209 -265
  7. package/node_modules/@higgsfield/higgsedit/dist/api.d.ts +481 -0
  8. package/node_modules/@higgsfield/higgsedit/dist/{chunk-PFQYUJQL.mjs → chunk-3XVMJSV2.mjs} +1 -1
  9. package/node_modules/@higgsfield/higgsedit/dist/{chunk-F4CMIG5G.mjs → chunk-4VE54E4U.mjs} +3 -1
  10. package/node_modules/@higgsfield/higgsedit/dist/{chunk-2JYLVSVV.mjs → chunk-55JARHLA.mjs} +205 -65
  11. package/node_modules/@higgsfield/higgsedit/dist/{chunk-YLVXQIPX.mjs → chunk-E4N76T2R.mjs} +1 -1
  12. package/node_modules/@higgsfield/higgsedit/dist/{chunk-OCIZ36XD.mjs → chunk-ECRSOIKI.mjs} +1 -1
  13. package/node_modules/@higgsfield/higgsedit/dist/{chunk-IEPPEDEU.mjs → chunk-ENALCTAD.mjs} +1 -1
  14. package/node_modules/@higgsfield/higgsedit/dist/chunk-HY2E7IWX.mjs +43 -0
  15. package/node_modules/@higgsfield/higgsedit/dist/{chunk-NARTAWRN.mjs → chunk-HYCUOCUQ.mjs} +9 -4
  16. package/node_modules/@higgsfield/higgsedit/dist/{chunk-C3GSB3XZ.mjs → chunk-NLEIBCAK.mjs} +1 -7
  17. package/node_modules/@higgsfield/higgsedit/dist/{chunk-2WKNH7OL.mjs → chunk-O3AVYZ6U.mjs} +1 -1
  18. package/node_modules/@higgsfield/higgsedit/dist/chunk-UXO22E3P.mjs +22 -0
  19. package/node_modules/@higgsfield/higgsedit/dist/{chunk-BH2QF635.mjs → chunk-V5XTCFYK.mjs} +4 -100
  20. package/node_modules/@higgsfield/higgsedit/dist/chunk-W2TANYEH.mjs +118 -0
  21. package/node_modules/@higgsfield/higgsedit/dist/{chunk-DVN4LUXV.mjs → chunk-XY5CCUOZ.mjs} +2 -6
  22. package/node_modules/@higgsfield/higgsedit/dist/{chunk-KIWGVAPJ.mjs → chunk-Y7SAX2P4.mjs} +8 -12
  23. package/node_modules/@higgsfield/higgsedit/dist/chunk-YNAIRXOP.mjs +22 -0
  24. package/node_modules/@higgsfield/higgsedit/dist/{chunk-WENFTPXQ.mjs → chunk-ZO3NDQD3.mjs} +1 -1
  25. package/node_modules/@higgsfield/higgsedit/dist/higgsedit.mjs +13 -13
  26. package/node_modules/@higgsfield/higgsedit/package.json +4 -1
  27. package/package.json +4 -4
  28. package/plugin/.codex-plugin/plugin.json +1 -1
  29. package/plugin/skills/video-editing/SKILL.md +109 -95
  30. package/plugin/mcp.json +0 -10
  31. package/plugin/plugin.json +0 -41
  32. package/plugin/skills/motion-craft/SKILL.md +0 -87
  33. package/plugin/skills/motion-craft/agents/openai.yaml +0 -6
  34. package/plugin/skills/motion-craft/references/causality.md +0 -25
  35. package/plugin/skills/motion-craft/references/composition.md +0 -20
  36. package/plugin/skills/motion-craft/references/easing.md +0 -19
  37. package/plugin/skills/motion-craft/references/qc.md +0 -33
  38. package/plugin/skills/motion-craft/references/recipes.md +0 -31
  39. package/plugin/skills/motion-craft/references/stepped.md +0 -43
  40. package/plugin/skills/motion-craft/references/timing.md +0 -60
  41. package/plugin/skills/motion-craft/references/tsx.md +0 -60
  42. package/plugin/skills/motion-craft/references/typography.md +0 -22
  43. package/plugin/skills/video-editing/agents/openai.yaml +0 -6
  44. package/plugin/skills/video-editing/references/animation-contract.md +0 -45
  45. package/plugin/skills/video-editing/references/assembly.md +0 -58
  46. package/plugin/skills/video-editing/references/caption-systems.md +0 -29
  47. package/plugin/skills/video-editing/references/caption-titling.md +0 -41
  48. package/plugin/skills/video-editing/references/clip-geometry.md +0 -37
  49. package/plugin/skills/video-editing/references/compose.md +0 -283
  50. package/plugin/skills/video-editing/references/editor-measured.md +0 -37
  51. package/plugin/skills/video-editing/references/failure-modes.md +0 -37
  52. package/plugin/skills/video-editing/references/local-setup.md +0 -25
  53. package/plugin/skills/video-editing/references/motion-language.md +0 -27
  54. package/plugin/skills/video-editing/references/provenance.md +0 -7
  55. package/plugin/skills/video-editing/references/sandbox.md +0 -31
  56. package/plugin/skills/video-editing/references/shot-blueprints.md +0 -24
  57. package/plugin/skills/video-editing/references/title-animation.md +0 -29
  58. package/plugin/skills/video-editing/references/tsx-projects.md +0 -187
  59. package/plugin/skills/video-editing/references/workflows.md +0 -41
@@ -554,19 +554,23 @@ async function frame(dir, at, out, depth = 8, allowFontFallback = false) {
554
554
  await session.close();
555
555
  }
556
556
  }
557
- async function sheet(dir, times, out, columns, width, allowFontFallback = false) {
557
+ async function sheetPng(dir, times, columns, width, allowFontFallback = false) {
558
558
  const session = await openCapture(dir, 8, allowFontFallback);
559
559
  try {
560
560
  const frames = times.map((t) => toFrame(t, session.composition.fps, 0));
561
561
  const png = await api(session.page).sheet(frames, { columns, width });
562
562
  await session.assertFonts();
563
- mkdirSync(dirname(resolve(out)), { recursive: true });
564
- writeFileSync(out, Buffer.from(png, "base64"));
565
- return { out: resolve(out), frames };
563
+ return { png: Buffer.from(png, "base64"), frames };
566
564
  } finally {
567
565
  await session.close();
568
566
  }
569
567
  }
568
+ async function sheet(dir, times, out, columns, width, allowFontFallback = false) {
569
+ const { png, frames } = await sheetPng(dir, times, columns, width, allowFontFallback);
570
+ mkdirSync(dirname(resolve(out)), { recursive: true });
571
+ writeFileSync(out, png);
572
+ return { out: resolve(out), frames };
573
+ }
570
574
  function shuffle(items, seed = 7) {
571
575
  const out = [...items];
572
576
  let s = seed;
@@ -610,6 +614,7 @@ export {
610
614
  rateFilter,
611
615
  render,
612
616
  frame,
617
+ sheetPng,
613
618
  sheet,
614
619
  shuffle,
615
620
  verify
@@ -12,11 +12,6 @@ import {
12
12
  parseKey,
13
13
  sourceFacts
14
14
  } from "./chunk-MV2JTTBQ.mjs";
15
- import "./chunk-UDL5AHKO.mjs";
16
- import "./chunk-LTKMGZ6T.mjs";
17
- import "./chunk-P2BGHTRR.mjs";
18
- import "./chunk-PAHMD6SU.mjs";
19
- import "./chunk-2VKQHJMM.mjs";
20
15
  import {
21
16
  Node,
22
17
  Sync,
@@ -28,8 +23,6 @@ import {
28
23
  syncPlacement,
29
24
  walk
30
25
  } from "./chunk-BV5COOQZ.mjs";
31
- import "./chunk-F7YUKEI5.mjs";
32
- import "./chunk-75WO2NOF.mjs";
33
26
 
34
27
  // src/outline.ts
35
28
  import { basename } from "node:path";
@@ -165,6 +158,7 @@ async function outline(dir) {
165
158
  };
166
159
  return { ...base, text: textOf(base) };
167
160
  }
161
+
168
162
  export {
169
163
  outline
170
164
  };
@@ -6,7 +6,7 @@ const __filename = __higgseditPath(import.meta.url);
6
6
  const __dirname = __filename.slice(0, __filename.lastIndexOf("/"));
7
7
 
8
8
  // package.json
9
- var package_default = { name: "@higgsfield/higgsedit", version: "0.2.0", devDependencies: { typescript: "7.0.2" } };
9
+ var package_default = { name: "@higgsfield/higgsedit", version: "1.0.0", devDependencies: { typescript: "7.0.2" } };
10
10
 
11
11
  // src/manifest.ts
12
12
  var CLI_MANIFEST = package_default;
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire as __higgseditRequire } from "node:module";
3
+ import { fileURLToPath as __higgseditPath } from "node:url";
4
+ const require = __higgseditRequire(import.meta.url);
5
+ const __filename = __higgseditPath(import.meta.url);
6
+ const __dirname = __filename.slice(0, __filename.lastIndexOf("/"));
7
+ import {
8
+ outline
9
+ } from "./chunk-NLEIBCAK.mjs";
10
+ import "./chunk-OF6RMSM2.mjs";
11
+ import "./chunk-MV2JTTBQ.mjs";
12
+ import "./chunk-UDL5AHKO.mjs";
13
+ import "./chunk-LTKMGZ6T.mjs";
14
+ import "./chunk-P2BGHTRR.mjs";
15
+ import "./chunk-PAHMD6SU.mjs";
16
+ import "./chunk-2VKQHJMM.mjs";
17
+ import "./chunk-BV5COOQZ.mjs";
18
+ import "./chunk-F7YUKEI5.mjs";
19
+ import "./chunk-75WO2NOF.mjs";
20
+ export {
21
+ outline
22
+ };
@@ -14,7 +14,6 @@ import {
14
14
  outputDir,
15
15
  pool,
16
16
  probeMedia,
17
- resolveMediaPath,
18
17
  textHeight,
19
18
  textWidth,
20
19
  videoSource,
@@ -23,19 +22,9 @@ import {
23
22
  import {
24
23
  transcribe
25
24
  } from "./chunk-L5LWBA6A.mjs";
26
- import "./chunk-PAHMD6SU.mjs";
27
- import "./chunk-BV5COOQZ.mjs";
28
25
  import {
29
26
  parseTime
30
27
  } from "./chunk-F7YUKEI5.mjs";
31
- import {
32
- flag,
33
- parseArgs
34
- } from "./chunk-MCVD2ZQV.mjs";
35
- import "./chunk-75WO2NOF.mjs";
36
-
37
- // src/media/cli.ts
38
- import { resolve } from "node:path";
39
28
 
40
29
  // src/media/time.ts
41
30
  function seconds(value, fps, duration) {
@@ -321,94 +310,9 @@ async function waveform(file, options = {}) {
321
310
  return { path, silences, width: canvas.width, height: canvas.height, rows };
322
311
  }
323
312
 
324
- // src/media/cli.ts
325
- var MEDIA_USAGE = `higgsedit media <command> <path> [options] inspect footage; relative paths resolve against --project <dir> or the cwd
326
-
327
- probe <path> container, duration, per-track codecs
328
- grab <path> [-t 0,1.5,45f,-1f | -c 6 [-s t] [-e t]] [-q small|medium|large|fullres]
329
- [-S|--separate] [--per-sheet n] [--uncapped] [-o dir]
330
- frames as labelled contact sheets (or one PNG each)
331
- filmstrip <path> [-s t] [-e t] [-x scale] [-o png] thumbnail grid with a timecode ruler
332
- waveform <path> [-s t] [-e t] [-x scale] [-o png] [--silence-db -40] [--min-silence 0.4]
333
- loudness PNG plus silent ranges
334
- transcribe <path> [-o json] [--model repo] [--language en]
335
- word-timed transcript JSON (local mlx_whisper)
336
- add --json for machine-readable output
337
- `;
338
- var number = (value, name) => {
339
- if (value === void 0) return void 0;
340
- const n = Number(value);
341
- if (!Number.isFinite(n)) throw new Error(`--${name} takes a number, got "${value}"`);
342
- return n;
343
- };
344
- async function runMedia(argv) {
345
- const [command, ...rest] = argv;
346
- const args = parseArgs(rest, /* @__PURE__ */ new Set(["json", "separate", "S", "uncapped"]));
347
- const target = args.positional[0];
348
- if (!command || !target || command === "help") {
349
- console.log(MEDIA_USAGE);
350
- return command ? 1 : 0;
351
- }
352
- const file = resolveMediaPath(target, resolve(flag(args, "project") ?? process.cwd()));
353
- const output = flag(args, "o", "output");
354
- const window2 = { ...flag(args, "s", "start") !== void 0 ? { start: flag(args, "s", "start") } : {}, ...flag(args, "e", "end") !== void 0 ? { end: flag(args, "e", "end") } : {} };
355
- const scale = number(flag(args, "x", "scale"), "scale");
356
- const print = (value, text) => console.log(args.flags.json === true ? JSON.stringify(value, null, 2) : text());
357
- switch (command) {
358
- case "probe": {
359
- const p = await probeMedia(file);
360
- print(
361
- p,
362
- () => [
363
- `${p.path} ${p.type}, ${p.format ?? "not media"}, ${p.size} bytes${p.duration !== void 0 ? `, ${p.duration.toFixed(3)} s` : ""}`,
364
- ...p.tracks.map((t) => ` #${t.id} ${t.type} ${t.codec ?? "?"}${t.width ? ` ${t.width}x${t.height}` : ""}${t.fps ? ` ${t.fps} fps` : ""}${t.pixFmt ? ` ${t.pixFmt}` : ""}${t.sampleRate ? ` ${t.sampleRate} Hz` : ""}${t.channels ? ` ${t.channels} ch` : ""} ${t.duration.toFixed(3)} s`)
365
- ].join("\n")
366
- );
367
- return 0;
368
- }
369
- case "grab": {
370
- const times = flag(args, "t", "times")?.split(",").map((s) => s.trim()).filter(Boolean);
371
- const count = number(flag(args, "c", "count"), "count");
372
- const perSheet = number(flag(args, "per-sheet"), "per-sheet");
373
- const quality = flag(args, "q", "quality");
374
- const r = await grab(file, {
375
- ...times ? { times } : {},
376
- ...count !== void 0 ? { count } : {},
377
- ...window2,
378
- ...quality ? { quality } : {},
379
- ...args.flags.separate === true || args.flags.S === true ? { separate: true } : {},
380
- ...perSheet !== void 0 ? { perSheet } : {},
381
- ...args.flags.uncapped === true ? { uncapped: true } : {},
382
- ...output ? { output } : {}
383
- });
384
- print(r, () => r.images.map((i) => `${i.timecode} ${i.path}`).join("\n"));
385
- return 0;
386
- }
387
- case "filmstrip": {
388
- const r = await filmstrip(file, { ...window2, ...scale !== void 0 ? { scale } : {}, ...output ? { output } : {} });
389
- print({ path: r.path, width: r.width, height: r.height, columns: r.columns, rows: r.rows }, () => `wrote ${r.path} (${r.columns}x${r.rows} thumbnails, ${r.width}x${r.height})`);
390
- return 0;
391
- }
392
- case "waveform": {
393
- const silenceDb = number(flag(args, "silence-db"), "silence-db");
394
- const minSilence = number(flag(args, "min-silence"), "min-silence");
395
- const r = await waveform(file, { ...window2, ...scale !== void 0 ? { scale } : {}, ...output ? { output } : {}, ...silenceDb !== void 0 ? { silenceDb } : {}, ...minSilence !== void 0 ? { minSilence } : {} });
396
- print({ path: r.path, silences: r.silences }, () => [`wrote ${r.path}`, ...r.silences.length ? r.silences.map((s) => ` silent ${s.start.toFixed(3)}\u2013${s.end.toFixed(3)} s`) : [" no silences"]].join("\n"));
397
- return 0;
398
- }
399
- case "transcribe": {
400
- const model = flag(args, "model");
401
- const language = flag(args, "language");
402
- const r = await transcribeMedia(file, { ...output ? { output } : {}, ...model ? { model } : {}, ...language ? { language } : {} });
403
- print(r, () => `wrote ${r.path} (${r.segments} segments, ${r.words} words${r.language ? `, ${r.language}` : ""})`);
404
- return 0;
405
- }
406
- default:
407
- console.log(MEDIA_USAGE);
408
- return 1;
409
- }
410
- }
411
313
  export {
412
- MEDIA_USAGE,
413
- runMedia
314
+ filmstrip,
315
+ grab,
316
+ transcribeMedia,
317
+ waveform
414
318
  };
@@ -0,0 +1,118 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire as __higgseditRequire } from "node:module";
3
+ import { fileURLToPath as __higgseditPath } from "node:url";
4
+ const require = __higgseditRequire(import.meta.url);
5
+ const __filename = __higgseditPath(import.meta.url);
6
+ const __dirname = __filename.slice(0, __filename.lastIndexOf("/"));
7
+ import {
8
+ filmstrip,
9
+ grab,
10
+ transcribeMedia,
11
+ waveform
12
+ } from "./chunk-V5XTCFYK.mjs";
13
+ import {
14
+ probeMedia,
15
+ resolveMediaPath
16
+ } from "./chunk-QJTILFBS.mjs";
17
+ import "./chunk-L5LWBA6A.mjs";
18
+ import "./chunk-PAHMD6SU.mjs";
19
+ import "./chunk-BV5COOQZ.mjs";
20
+ import "./chunk-F7YUKEI5.mjs";
21
+ import {
22
+ flag,
23
+ parseArgs
24
+ } from "./chunk-MCVD2ZQV.mjs";
25
+ import "./chunk-75WO2NOF.mjs";
26
+
27
+ // src/media/cli.ts
28
+ import { resolve } from "node:path";
29
+ var MEDIA_USAGE = `higgsedit media <command> <path> [options] inspect footage; relative paths resolve against --project <dir> or the cwd
30
+
31
+ probe <path> container, duration, per-track codecs
32
+ grab <path> [-t 0,1.5,45f,-1f | -c 6 [-s t] [-e t]] [-q small|medium|large|fullres]
33
+ [-S|--separate] [--per-sheet n] [--uncapped] [-o dir]
34
+ frames as labelled contact sheets (or one PNG each)
35
+ filmstrip <path> [-s t] [-e t] [-x scale] [-o png] thumbnail grid with a timecode ruler
36
+ waveform <path> [-s t] [-e t] [-x scale] [-o png] [--silence-db -40] [--min-silence 0.4]
37
+ loudness PNG plus silent ranges
38
+ transcribe <path> [-o json] [--model repo] [--language en]
39
+ word-timed transcript JSON (local mlx_whisper)
40
+ add --json for machine-readable output
41
+ `;
42
+ var number = (value, name) => {
43
+ if (value === void 0) return void 0;
44
+ const n = Number(value);
45
+ if (!Number.isFinite(n)) throw new Error(`--${name} takes a number, got "${value}"`);
46
+ return n;
47
+ };
48
+ async function runMedia(argv) {
49
+ const [command, ...rest] = argv;
50
+ const args = parseArgs(rest, /* @__PURE__ */ new Set(["json", "separate", "S", "uncapped"]));
51
+ const target = args.positional[0];
52
+ if (!command || !target || command === "help") {
53
+ console.log(MEDIA_USAGE);
54
+ return command ? 1 : 0;
55
+ }
56
+ const file = resolveMediaPath(target, resolve(flag(args, "project") ?? process.cwd()));
57
+ const output = flag(args, "o", "output");
58
+ const window = { ...flag(args, "s", "start") !== void 0 ? { start: flag(args, "s", "start") } : {}, ...flag(args, "e", "end") !== void 0 ? { end: flag(args, "e", "end") } : {} };
59
+ const scale = number(flag(args, "x", "scale"), "scale");
60
+ const print = (value, text) => console.log(args.flags.json === true ? JSON.stringify(value, null, 2) : text());
61
+ switch (command) {
62
+ case "probe": {
63
+ const p = await probeMedia(file);
64
+ print(
65
+ p,
66
+ () => [
67
+ `${p.path} ${p.type}, ${p.format ?? "not media"}, ${p.size} bytes${p.duration !== void 0 ? `, ${p.duration.toFixed(3)} s` : ""}`,
68
+ ...p.tracks.map((t) => ` #${t.id} ${t.type} ${t.codec ?? "?"}${t.width ? ` ${t.width}x${t.height}` : ""}${t.fps ? ` ${t.fps} fps` : ""}${t.pixFmt ? ` ${t.pixFmt}` : ""}${t.sampleRate ? ` ${t.sampleRate} Hz` : ""}${t.channels ? ` ${t.channels} ch` : ""} ${t.duration.toFixed(3)} s`)
69
+ ].join("\n")
70
+ );
71
+ return 0;
72
+ }
73
+ case "grab": {
74
+ const times = flag(args, "t", "times")?.split(",").map((s) => s.trim()).filter(Boolean);
75
+ const count = number(flag(args, "c", "count"), "count");
76
+ const perSheet = number(flag(args, "per-sheet"), "per-sheet");
77
+ const quality = flag(args, "q", "quality");
78
+ const r = await grab(file, {
79
+ ...times ? { times } : {},
80
+ ...count !== void 0 ? { count } : {},
81
+ ...window,
82
+ ...quality ? { quality } : {},
83
+ ...args.flags.separate === true || args.flags.S === true ? { separate: true } : {},
84
+ ...perSheet !== void 0 ? { perSheet } : {},
85
+ ...args.flags.uncapped === true ? { uncapped: true } : {},
86
+ ...output ? { output } : {}
87
+ });
88
+ print(r, () => r.images.map((i) => `${i.timecode} ${i.path}`).join("\n"));
89
+ return 0;
90
+ }
91
+ case "filmstrip": {
92
+ const r = await filmstrip(file, { ...window, ...scale !== void 0 ? { scale } : {}, ...output ? { output } : {} });
93
+ print({ path: r.path, width: r.width, height: r.height, columns: r.columns, rows: r.rows }, () => `wrote ${r.path} (${r.columns}x${r.rows} thumbnails, ${r.width}x${r.height})`);
94
+ return 0;
95
+ }
96
+ case "waveform": {
97
+ const silenceDb = number(flag(args, "silence-db"), "silence-db");
98
+ const minSilence = number(flag(args, "min-silence"), "min-silence");
99
+ const r = await waveform(file, { ...window, ...scale !== void 0 ? { scale } : {}, ...output ? { output } : {}, ...silenceDb !== void 0 ? { silenceDb } : {}, ...minSilence !== void 0 ? { minSilence } : {} });
100
+ print({ path: r.path, silences: r.silences }, () => [`wrote ${r.path}`, ...r.silences.length ? r.silences.map((s) => ` silent ${s.start.toFixed(3)}\u2013${s.end.toFixed(3)} s`) : [" no silences"]].join("\n"));
101
+ return 0;
102
+ }
103
+ case "transcribe": {
104
+ const model = flag(args, "model");
105
+ const language = flag(args, "language");
106
+ const r = await transcribeMedia(file, { ...output ? { output } : {}, ...model ? { model } : {}, ...language ? { language } : {} });
107
+ print(r, () => `wrote ${r.path} (${r.segments} segments, ${r.words} words${r.language ? `, ${r.language}` : ""})`);
108
+ return 0;
109
+ }
110
+ default:
111
+ console.log(MEDIA_USAGE);
112
+ return 1;
113
+ }
114
+ }
115
+ export {
116
+ MEDIA_USAGE,
117
+ runMedia
118
+ };
@@ -10,15 +10,10 @@ import {
10
10
  } from "./chunk-P2BGHTRR.mjs";
11
11
  import {
12
12
  selectStatus
13
- } from "./chunk-WENFTPXQ.mjs";
14
- import "./chunk-QJTILFBS.mjs";
13
+ } from "./chunk-ZO3NDQD3.mjs";
15
14
  import {
16
15
  findTool
17
16
  } from "./chunk-PAHMD6SU.mjs";
18
- import "./chunk-BV5COOQZ.mjs";
19
- import "./chunk-F7YUKEI5.mjs";
20
- import "./chunk-MCVD2ZQV.mjs";
21
- import "./chunk-75WO2NOF.mjs";
22
17
 
23
18
  // src/doctor.ts
24
19
  import { existsSync, readFileSync } from "node:fs";
@@ -69,6 +64,7 @@ function diagnosisText(d, extra = {}) {
69
64
  ${d.errors.map((e) => ` ${e.replace(/\n/g, "\n ")}`).join("\n")}` : "recent errors: none");
70
65
  return lines.join("\n");
71
66
  }
67
+
72
68
  export {
73
69
  diagnose,
74
70
  diagnosisText
@@ -11,8 +11,6 @@ import {
11
11
  readBody,
12
12
  sendFile
13
13
  } from "./chunk-7PYXSJS7.mjs";
14
- import "./chunk-UDL5AHKO.mjs";
15
- import "./chunk-LTKMGZ6T.mjs";
16
14
  import {
17
15
  launch
18
16
  } from "./chunk-P2BGHTRR.mjs";
@@ -20,8 +18,6 @@ import {
20
18
  ffmpeg,
21
19
  probe
22
20
  } from "./chunk-PAHMD6SU.mjs";
23
- import "./chunk-NUXTKQNM.mjs";
24
- import "./chunk-2VKQHJMM.mjs";
25
21
  import {
26
22
  encodeMaskFile
27
23
  } from "./chunk-BV5COOQZ.mjs";
@@ -32,7 +28,6 @@ import {
32
28
  flag,
33
29
  flags
34
30
  } from "./chunk-MCVD2ZQV.mjs";
35
- import "./chunk-75WO2NOF.mjs";
36
31
 
37
32
  // src/segment.ts
38
33
  import { createHash } from "node:crypto";
@@ -402,16 +397,17 @@ async function runSegment(args, print) {
402
397
  );
403
398
  return 0;
404
399
  }
400
+
405
401
  export {
406
- ORT_FILES,
407
- ensureModel,
408
- mediaSeconds,
409
- modelCached,
410
402
  modelDir,
403
+ modelCached,
404
+ ensureModel,
411
405
  ortDir,
412
- point,
406
+ ORT_FILES,
407
+ segmentBundle,
413
408
  prompts,
414
- runSegment,
415
409
  segment,
416
- segmentBundle
410
+ point,
411
+ mediaSeconds,
412
+ runSegment
417
413
  };
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire as __higgseditRequire } from "node:module";
3
+ import { fileURLToPath as __higgseditPath } from "node:url";
4
+ const require = __higgseditRequire(import.meta.url);
5
+ const __filename = __higgseditPath(import.meta.url);
6
+ const __dirname = __filename.slice(0, __filename.lastIndexOf("/"));
7
+ import {
8
+ diagnose,
9
+ diagnosisText
10
+ } from "./chunk-XY5CCUOZ.mjs";
11
+ import "./chunk-P2BGHTRR.mjs";
12
+ import "./chunk-ZO3NDQD3.mjs";
13
+ import "./chunk-QJTILFBS.mjs";
14
+ import "./chunk-PAHMD6SU.mjs";
15
+ import "./chunk-BV5COOQZ.mjs";
16
+ import "./chunk-F7YUKEI5.mjs";
17
+ import "./chunk-MCVD2ZQV.mjs";
18
+ import "./chunk-75WO2NOF.mjs";
19
+ export {
20
+ diagnose,
21
+ diagnosisText
22
+ };
@@ -349,7 +349,7 @@ async function runSelect(args, print) {
349
349
  const text = flag(args, "text");
350
350
  const prompt = parsePrompt({ ...text !== void 0 ? { text } : {}, ...include.length ? { points: include } : {}, ...exclude.length ? { exclude } : {}, ...box ? { box } : {} });
351
351
  requireSelectBackend();
352
- const { mediaSeconds } = await import("./chunk-KIWGVAPJ.mjs");
352
+ const { mediaSeconds } = await import("./chunk-HY2E7IWX.mjs");
353
353
  const fps = await mediaSeconds.fps(media);
354
354
  const time = mediaSeconds.parse(flag(args, "at", "t"), fps, "--at") ?? 0;
355
355
  const out = flag(args, "o", "out");
@@ -6,7 +6,7 @@ const __filename = __higgseditPath(import.meta.url);
6
6
  const __dirname = __filename.slice(0, __filename.lastIndexOf("/"));
7
7
  import {
8
8
  CLI_MANIFEST
9
- } from "./chunk-2WKNH7OL.mjs";
9
+ } from "./chunk-O3AVYZ6U.mjs";
10
10
  import {
11
11
  flag,
12
12
  parseArgs
@@ -63,21 +63,21 @@ async function main(argv) {
63
63
  return 0;
64
64
  }
65
65
  if (command === "doctor") {
66
- const { diagnose, diagnosisText } = await import("./chunk-DVN4LUXV.mjs");
66
+ const { diagnose, diagnosisText } = await import("./chunk-YNAIRXOP.mjs");
67
67
  const d = await diagnose();
68
68
  print(d, () => diagnosisText(d));
69
69
  return "path" in d.ffmpeg && "path" in d.ffprobe ? 0 : 1;
70
70
  }
71
71
  if (command === "media") {
72
- const { runMedia } = await import("./chunk-BH2QF635.mjs");
72
+ const { runMedia } = await import("./chunk-W2TANYEH.mjs");
73
73
  return runMedia(rest);
74
74
  }
75
75
  if (command === "segment") {
76
- const { runSegment } = await import("./chunk-KIWGVAPJ.mjs");
76
+ const { runSegment } = await import("./chunk-HY2E7IWX.mjs");
77
77
  return runSegment(args, print);
78
78
  }
79
79
  if (command === "select") {
80
- const { runSelect } = await import("./chunk-OCIZ36XD.mjs");
80
+ const { runSelect } = await import("./chunk-ECRSOIKI.mjs");
81
81
  return runSelect(args, print);
82
82
  }
83
83
  if (command === "transcribe") {
@@ -89,7 +89,7 @@ async function main(argv) {
89
89
  return runFonts(parseArgs(rest, /* @__PURE__ */ new Set(["json", "cached"])), print);
90
90
  }
91
91
  if (command === "presets") {
92
- const { runPresets } = await import("./chunk-IEPPEDEU.mjs");
92
+ const { runPresets } = await import("./chunk-ENALCTAD.mjs");
93
93
  return runPresets(args, print);
94
94
  }
95
95
  if (!command || command === "help" || command === "--help" || !dirArg) {
@@ -97,7 +97,7 @@ async function main(argv) {
97
97
  return command ? 1 : 0;
98
98
  }
99
99
  if (command === "init") {
100
- const { scaffold } = await import("./chunk-PFQYUJQL.mjs");
100
+ const { scaffold } = await import("./chunk-3XVMJSV2.mjs");
101
101
  const [w, h] = String(flag(args, "size") ?? "1080x1920").split("x").map(Number);
102
102
  const target = resolve(dirArg);
103
103
  const r = scaffold(target, { width: w, height: h, fps: Number(flag(args, "fps") ?? 30) });
@@ -139,7 +139,7 @@ async function main(argv) {
139
139
  const at = args.positional[1];
140
140
  const out = flag(args, "o", "out");
141
141
  if (!at || !out) throw new Error("usage: higgsedit frame <dir> <t> -o x.png");
142
- const { frame } = await import("./chunk-F4CMIG5G.mjs");
142
+ const { frame } = await import("./chunk-4VE54E4U.mjs");
143
143
  const r = await frame(dir, at, out, depth, allowFontFallback);
144
144
  print(r, () => `wrote ${r.out} (frame ${r.frame}, ${r.ms.toFixed(0)} ms)`);
145
145
  return 0;
@@ -148,7 +148,7 @@ async function main(argv) {
148
148
  const times = flag(args, "times")?.split(",").map((s) => s.trim()).filter(Boolean);
149
149
  const out = flag(args, "o", "out");
150
150
  if (!times?.length || !out) throw new Error("usage: higgsedit sheet <dir> --times 0,1,2 -o sheet.png");
151
- const { sheet } = await import("./chunk-F4CMIG5G.mjs");
151
+ const { sheet } = await import("./chunk-4VE54E4U.mjs");
152
152
  const r = await sheet(dir, times, out, Number(flag(args, "columns") ?? Math.min(4, times.length)), Number(flag(args, "width") ?? 480), allowFontFallback);
153
153
  print(r, () => `wrote ${r.out} (frames ${r.frames.join(", ")})`);
154
154
  return 0;
@@ -159,7 +159,7 @@ async function main(argv) {
159
159
  const encoder = flag(args, "encoder");
160
160
  if (encoder && !ENCODERS.includes(encoder)) throw new Error(`unknown --encoder ${encoder}; use ${ENCODERS.join(", ")}`);
161
161
  const crf = flag(args, "crf");
162
- const { render } = await import("./chunk-F4CMIG5G.mjs");
162
+ const { render } = await import("./chunk-4VE54E4U.mjs");
163
163
  const r = await render(dir, {
164
164
  out,
165
165
  depth,
@@ -185,13 +185,13 @@ async function main(argv) {
185
185
  return 0;
186
186
  }
187
187
  case "verify": {
188
- const { verify } = await import("./chunk-F4CMIG5G.mjs");
188
+ const { verify } = await import("./chunk-4VE54E4U.mjs");
189
189
  const r = await verify(dir, Number(flag(args, "count") ?? 12), depth, allowFontFallback);
190
190
  print(r, () => [`${r.identical ? "identical" : "DIFFERENT"}: ${r.frames.length} frames, ${r.depth}-bit, shuffled order ${r.shuffledOrder.join(",")}`, ...r.frames.map((f, i) => ` ${String(f).padStart(6)} ${r.forward[i]} ${r.shuffled[i] === r.forward[i] ? "=" : "\u2260"}`)].join("\n"));
191
191
  return r.identical ? 0 : 1;
192
192
  }
193
193
  case "outline": {
194
- const { outline } = await import("./chunk-C3GSB3XZ.mjs");
194
+ const { outline } = await import("./chunk-UXO22E3P.mjs");
195
195
  const o = await outline(dir);
196
196
  print(o, () => o.text);
197
197
  return o.ok ? 0 : 1;
@@ -201,7 +201,7 @@ async function main(argv) {
201
201
  return runEdit(dir, args, print);
202
202
  }
203
203
  case "dev": {
204
- const { dev } = await import("./chunk-2JYLVSVV.mjs");
204
+ const { dev } = await import("./chunk-55JARHLA.mjs");
205
205
  await dev(dir, Number(flag(args, "port") ?? 4173), flag(args, "presets"));
206
206
  return await new Promise(() => {
207
207
  });
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@higgsfield/higgsedit",
3
- "version": "0.2.0",
3
+ "version": "1.0.0",
4
4
  "description": "Make videos in code: create, preview, edit and render TSX video projects from the command line",
5
5
  "keywords": [
6
6
  "video",
@@ -19,6 +19,9 @@
19
19
  "higgsedit": "./dist/higgsedit.mjs"
20
20
  },
21
21
  "exports": {
22
+ "./api": {
23
+ "types": "./dist/api.d.ts"
24
+ },
22
25
  "./jsx": {
23
26
  "types": "./dist/jsx/index.d.ts"
24
27
  },
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@higgsfield/video-editor-mcp",
3
- "version": "1.1.1-dev.0",
3
+ "version": "2.0.0",
4
4
  "description": "Higgsfield Video Editor as a local MCP server over stdio: edits TSX video projects on this machine with the higgsedit CLI and serves the editor panel.",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "type": "module",
7
7
  "bin": {
8
- "fnf-video-editor": "dist/cli.mjs",
8
+ "video-editor-mcp": "dist/cli.mjs",
9
9
  "fnf-video-editor-mcp": "dist/server.mjs"
10
10
  },
11
11
  "files": [
@@ -22,14 +22,14 @@
22
22
  "esbuild": "0.28.2",
23
23
  "playwright-core": "1.63.0",
24
24
  "solid-js": "1.9.16",
25
- "@higgsfield/higgsedit": "0.2.0"
25
+ "@higgsfield/higgsedit": "1.0.0"
26
26
  },
27
27
  "bundleDependencies": [
28
28
  "@higgsfield/higgsedit"
29
29
  ],
30
30
  "publishConfig": {
31
31
  "access": "public",
32
- "tag": "next"
32
+ "tag": "latest"
33
33
  },
34
34
  "keywords": [
35
35
  "mcp",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "higgsfield-video-editor-local",
3
- "version": "1.1.1-dev.0",
3
+ "version": "2.0.0",
4
4
  "description": "Edit and render video projects on your Mac with Higgsfield. Arrange clips, add text, audio and motion graphics, preview your timeline in the interactive editor, and render finished videos. Generate images and videos in the editor by connecting your Higgsfield account.",
5
5
  "author": {
6
6
  "name": "Higgsfield AI, Inc."