hyperframes 0.8.81 → 0.8.82
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/dist/backgroundChecksWorker.js +890 -0
- package/dist/cli.js +2928 -1809
- package/dist/commands/layout-audit.browser.js +55 -25
- package/dist/fontLocalizeCli.js +417 -134
- package/dist/hyperframe-runtime.js +53 -53
- package/dist/hyperframe.manifest.json +1 -1
- package/dist/hyperframe.runtime.iife.js +53 -53
- package/dist/hyperframes-player.global.js +3 -3
- package/dist/registry/localSemantic.js +7 -3
- package/dist/renderSetupWorker.js +62 -32
- package/dist/sherpaWorker.js +179 -0
- package/dist/skills/hyperframes/SKILL.md +2 -0
- package/dist/skills/hyperframes/references/plugin-installation.md +43 -0
- package/dist/skills/hyperframes/references/skill-lifecycle.md +2 -0
- package/dist/skills/hyperframes/scripts/plugin-cli.mjs +88 -0
- package/dist/skills/hyperframes/scripts/plugin-cli.test.mjs +117 -0
- package/dist/skills/hyperframes-cli/SKILL.md +2 -0
- package/dist/skills/hyperframes-cli/references/upgrade-info-misc.md +1 -0
- package/dist/skills/media-use/SKILL.md +2 -0
- package/dist/skills/media-use/references/operations.md +7 -5
- package/dist/skills/media-use/references/setup-providers.md +9 -9
- package/dist/skills/media-use/registry/localSemantic.js +7 -3
- package/dist/skills/media-use/scripts/lib/ff-binaries.mjs +37 -0
- package/dist/skills/media-use/scripts/lib/probe.mjs +3 -1
- package/dist/skills/media-use/scripts/lib/probe.test.mjs +118 -1
- package/dist/skills/media-use/scripts/lib/tts-local-provider.mjs +5 -3
- package/dist/skills/media-use/scripts/resolve-plugin.test.mjs +62 -0
- package/dist/skills/media-use/scripts/resolve.mjs +45 -19
- package/dist/skills/media-use/scripts/transcribe.mjs +39 -25
- package/dist/skills/media-use/scripts/transcribe.test.mjs +112 -0
- package/dist/skills/registry/localSemantic.js +7 -3
- package/dist/studio/assets/{hyperframes-player-C68UawR3.js → hyperframes-player-zGIbZhLJ.js} +1 -1
- package/dist/studio/assets/{index-CMzPGv9P.js → index-BiLCTunu.js} +1 -1
- package/dist/studio/assets/{index-hNVM9Pd2.js → index-DSazIt7R.js} +189 -189
- package/dist/studio/assets/{index-CS5SImRT.js → index-DStmfnpZ.js} +1 -1
- package/dist/studio/index.d.ts +172 -7
- package/dist/studio/index.html +1 -1
- package/dist/studio/index.js +2414 -2172
- package/dist/studio/index.js.map +1 -1
- package/dist/templates/_shared/AGENTS.md +5 -1
- package/dist/templates/_shared/CLAUDE.md +5 -1
- package/package.json +1 -1
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { execFileSync, spawnSync } from "node:child_process";
|
|
3
|
+
import { chmodSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
4
|
+
import { tmpdir } from "node:os";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
import test from "node:test";
|
|
7
|
+
import { fileURLToPath } from "node:url";
|
|
8
|
+
|
|
9
|
+
// The stub stands in for `npx hyperframes transcribe <in> --dir <dir> ...`: it records its args,
|
|
10
|
+
// writes the CLI's flat array and prints the CLI's --json line naming `cliEngine`.
|
|
11
|
+
function runScript(engine, cliEngine) {
|
|
12
|
+
const root = mkdtempSync(join(tmpdir(), "media-use-transcribe-"));
|
|
13
|
+
try {
|
|
14
|
+
const bin = join(root, "bin");
|
|
15
|
+
mkdirSync(bin);
|
|
16
|
+
writeFileSync(
|
|
17
|
+
join(bin, "npx"),
|
|
18
|
+
`#!/bin/sh\necho "$@" > "${root}/args"\nwhile [ "$1" != "--dir" ]; do shift; done\n` +
|
|
19
|
+
`echo '[{"text":"a","start":0,"end":1},{"text":"b","start":1,"end":2}]' > "$2/transcript.json"\n` +
|
|
20
|
+
`echo '{"ok":true,"engine":"${cliEngine}"}'\n`,
|
|
21
|
+
);
|
|
22
|
+
chmodSync(join(bin, "npx"), 0o755);
|
|
23
|
+
const input = join(root, "in.wav");
|
|
24
|
+
writeFileSync(input, "");
|
|
25
|
+
const script = fileURLToPath(new URL("./transcribe.mjs", import.meta.url));
|
|
26
|
+
const env = { ...process.env, PATH: `${bin}:${process.env.PATH}`, HOME: root };
|
|
27
|
+
delete env.HYPERFRAMES_PARAKEET;
|
|
28
|
+
const out = execFileSync(
|
|
29
|
+
process.execPath,
|
|
30
|
+
[script, "--input", input, "--engine", engine, "--json"],
|
|
31
|
+
{
|
|
32
|
+
encoding: "utf8",
|
|
33
|
+
env: { ...env, HYPERFRAMES_MEDIA_HOME: join(root, "home"), HYPERFRAMES_NO_TELEMETRY: "1" },
|
|
34
|
+
},
|
|
35
|
+
);
|
|
36
|
+
return { result: JSON.parse(out.trim()), args: readFileSync(join(root, "args"), "utf8") };
|
|
37
|
+
} finally {
|
|
38
|
+
rmSync(root, { recursive: true, force: true });
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
test(
|
|
43
|
+
"--engine whisper makes the CLI run whisper and reports the flat transcript's word count",
|
|
44
|
+
{ skip: process.platform === "win32" },
|
|
45
|
+
() => {
|
|
46
|
+
const { result, args } = runScript("whisper", "whisper");
|
|
47
|
+
assert.match(args, /--engine whisper --json/);
|
|
48
|
+
assert.equal(result.words, 2);
|
|
49
|
+
assert.equal(result.engine, "whisper");
|
|
50
|
+
},
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
test(
|
|
54
|
+
"auto reports the engine the CLI says it ran, Parakeet included",
|
|
55
|
+
{ skip: process.platform === "win32" },
|
|
56
|
+
() => {
|
|
57
|
+
const { result, args } = runScript("auto", "parakeet");
|
|
58
|
+
assert.match(args, /--engine auto --json/);
|
|
59
|
+
assert.equal(result.engine, "parakeet");
|
|
60
|
+
},
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
test(
|
|
64
|
+
"--engine parakeet without parakeet-mlx asks the CLI for its Parakeet",
|
|
65
|
+
{ skip: process.platform === "win32" },
|
|
66
|
+
() => {
|
|
67
|
+
const { result, args } = runScript("parakeet", "parakeet");
|
|
68
|
+
assert.match(args, /--engine parakeet --json/);
|
|
69
|
+
assert.equal(result.engine, "parakeet");
|
|
70
|
+
},
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
test(
|
|
74
|
+
"a failed --engine parakeet run reports the reason the CLI printed on stdout",
|
|
75
|
+
{ skip: process.platform === "win32" },
|
|
76
|
+
() => {
|
|
77
|
+
const root = mkdtempSync(join(tmpdir(), "media-use-transcribe-"));
|
|
78
|
+
try {
|
|
79
|
+
const bin = join(root, "bin");
|
|
80
|
+
mkdirSync(bin);
|
|
81
|
+
const reason =
|
|
82
|
+
"Parakeet is not installed. Install it with: hyperframes models install parakeet";
|
|
83
|
+
writeFileSync(
|
|
84
|
+
join(bin, "npx"),
|
|
85
|
+
`#!/bin/sh\necho '{"ok":false,"error":"${reason}"}'\nexit 1\n`,
|
|
86
|
+
);
|
|
87
|
+
chmodSync(join(bin, "npx"), 0o755);
|
|
88
|
+
const input = join(root, "in.wav");
|
|
89
|
+
writeFileSync(input, "");
|
|
90
|
+
const script = fileURLToPath(new URL("./transcribe.mjs", import.meta.url));
|
|
91
|
+
const res = spawnSync(
|
|
92
|
+
process.execPath,
|
|
93
|
+
[script, "--input", input, "--engine", "parakeet", "--json"],
|
|
94
|
+
{
|
|
95
|
+
encoding: "utf8",
|
|
96
|
+
env: {
|
|
97
|
+
...process.env,
|
|
98
|
+
HYPERFRAMES_PARAKEET: "",
|
|
99
|
+
PATH: `${bin}:${process.env.PATH}`,
|
|
100
|
+
HOME: root,
|
|
101
|
+
HYPERFRAMES_MEDIA_HOME: join(root, "home"),
|
|
102
|
+
HYPERFRAMES_NO_TELEMETRY: "1",
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
);
|
|
106
|
+
assert.equal(res.status, 1);
|
|
107
|
+
assert.match(JSON.parse(res.stdout.trim()).error, /hyperframes models install parakeet/);
|
|
108
|
+
} finally {
|
|
109
|
+
rmSync(root, { recursive: true, force: true });
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
);
|
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
realpathSync,
|
|
25
25
|
renameSync,
|
|
26
26
|
rmSync,
|
|
27
|
+
statSync,
|
|
27
28
|
writeFileSync
|
|
28
29
|
} from "fs";
|
|
29
30
|
import { createRequire } from "module";
|
|
@@ -79,9 +80,9 @@ function pinnedCopyBesideCli(name, cliUrl) {
|
|
|
79
80
|
function loadBesideCli(name, cliUrl = import.meta.url) {
|
|
80
81
|
return pinnedCopyBesideCli(name, cliUrl) ? createRequire(cliUrl)(name) : null;
|
|
81
82
|
}
|
|
82
|
-
function runNpm(args) {
|
|
83
|
+
function runNpm(args, signal) {
|
|
83
84
|
const npm = buildNpmCommand(args);
|
|
84
|
-
const child = spawn(npm.command, npm.args, { stdio: ["ignore", "pipe", "pipe"] });
|
|
85
|
+
const child = spawn(npm.command, npm.args, { stdio: ["ignore", "pipe", "pipe"], signal });
|
|
85
86
|
return new Promise((resolve, reject) => {
|
|
86
87
|
let output = "";
|
|
87
88
|
child.stdout.on("data", (chunk) => output += chunk);
|
|
@@ -101,6 +102,7 @@ function isProcessAlive(pid) {
|
|
|
101
102
|
return err.code !== "ESRCH";
|
|
102
103
|
}
|
|
103
104
|
}
|
|
105
|
+
var STAGING_PID_TRUSTED_FOR_MS = 6 * 60 * 60 * 1e3;
|
|
104
106
|
function sweepStaleStaging(dir) {
|
|
105
107
|
const prefix = `${basename(dir)}.tmp-`;
|
|
106
108
|
const parent = dirname(dir);
|
|
@@ -108,8 +110,10 @@ function sweepStaleStaging(dir) {
|
|
|
108
110
|
for (const entry of readdirSync(parent)) {
|
|
109
111
|
if (!entry.startsWith(prefix)) continue;
|
|
110
112
|
const pid = /^(\d+)(?:-|$)/.exec(entry.slice(prefix.length))?.[1];
|
|
111
|
-
if (pid === void 0
|
|
113
|
+
if (pid === void 0) continue;
|
|
112
114
|
const stale = join(parent, entry);
|
|
115
|
+
const age = Date.now() - (statSync(stale, { throwIfNoEntry: false })?.mtimeMs ?? Date.now());
|
|
116
|
+
if (isProcessAlive(Number(pid)) && age < STAGING_PID_TRUSTED_FOR_MS) continue;
|
|
113
117
|
try {
|
|
114
118
|
rmSync(stale, { recursive: true, force: true });
|
|
115
119
|
} catch (err) {
|
package/dist/studio/assets/{hyperframes-player-C68UawR3.js → hyperframes-player-zGIbZhLJ.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var Se=Object.defineProperty;var Le=(r,i,e)=>i in r?Se(r,i,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[i]=e;var l=(r,i,e)=>Le(r,typeof i!="symbol"?i+"":i,e);import{r as pe,i as De,a as w,b as me,c as Me,d as xe,s as Pe,e as fe,F as _e}from"./index-
|
|
1
|
+
var Se=Object.defineProperty;var Le=(r,i,e)=>i in r?Se(r,i,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[i]=e;var l=(r,i,e)=>Le(r,typeof i!="symbol"?i+"":i,e);import{r as pe,i as De,a as w,b as me,c as Me,d as xe,s as Pe,e as fe,F as _e}from"./index-DSazIt7R.js";function ke(r){return r.hasRuntime||r.runtimeInjected?!1:!!(r.hasNestedCompositions||r.hasTimelines&&r.attempts>=5)}function $(r){return typeof r=="object"&&r!==null}function Ie(r){return $(r)&&typeof r.getDuration=="function"}function Oe(r){return $(r)&&typeof r.duration=="function"&&typeof r.time=="function"&&typeof r.seek=="function"&&typeof r.play=="function"&&typeof r.pause=="function"}function Ne(r){if(!/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/.test(r))throw new Error(`Invalid HyperFrames runtime version: ${r}`);return`https://cdn.jsdelivr.net/npm/@hyperframes/core@${r}/dist/hyperframe.runtime.iife.js`}const U=typeof __HYPERFRAMES_RUNTIME_CDN_URL__=="string"?__HYPERFRAMES_RUNTIME_CDN_URL__:Ne("0.0.0-dev");function V(r){if(r===null)return null;const i=Number.parseInt(r,10);return Number.isFinite(i)&&i>0?i:null}function Fe(r){const i=(r==null?void 0:r.querySelector("[data-composition-id][data-width][data-height]"))??(r==null?void 0:r.querySelector("[data-width][data-height]"));if(!i)return null;const e=V(i.getAttribute("data-width")),t=V(i.getAttribute("data-height"));return e!==null&&t!==null?{width:e,height:t}:null}class He{constructor(i,e){l(this,"_interval",null);l(this,"_runtimeInjected",!1);this._iframe=i,this._callbacks=e}get runtimeInjected(){return this._runtimeInjected}start(){this.stop(),this._runtimeInjected=!1;let i=0;this._interval=setInterval(()=>{var e;i++;try{const t=this._iframe.contentWindow;if(!t)return;const s=!!(t.__hf||t.__player),n=!!(t.__timelines&&Object.keys(t.__timelines).length>0),o=!!((e=this._iframe.contentDocument)!=null&&e.querySelector("[data-composition-src]"));if(ke({hasRuntime:s,hasTimelines:n,hasNestedCompositions:o,runtimeInjected:this._runtimeInjected,attempts:i})){this._injectRuntime();return}if(this._runtimeInjected&&!s)return;const d=this._resolvePlaybackDurationAdapter(t);if(d&&d.getDuration()>0){this.stop();const c=Fe(this._iframe.contentDocument);this._callbacks.onReady({duration:d.getDuration(),adapter:d,compositionSize:c});return}}catch{}i>=40&&(this.stop(),this._callbacks.onError("Composition timeline not found after 8s"))},200)}stop(){this._interval!==null&&(clearInterval(this._interval),this._interval=null)}resolveDirectTimelineAdapter(){try{const i=this._iframe.contentWindow;return i?this._resolveDirectTimelineAdapterFromWindow(i):null}catch{return null}}resolveDirectTimelineAdapterFromWindow(i){return this._resolveDirectTimelineAdapterFromWindow(i)}hasRuntimeBridge(i){return Reflect.get(i,"__hf")!==void 0||$(Reflect.get(i,"__player"))}_injectRuntime(){var i,e;this._runtimeInjected=!0;try{const t=this._iframe.contentDocument;if(!t)return;const s=t.createElement("script");s.src=U,(t.head||t.documentElement).appendChild(s),(e=(i=this._callbacks).onRuntimeInjected)==null||e.call(i)}catch{}}_resolveDirectTimelineAdapterFromWindow(i){var d,c;if(this.hasRuntimeBridge(i))return null;const e=Reflect.get(i,"__timelines");if(!$(e))return null;const t=Object.keys(e);if(t.length===0)return null;const s=(c=(d=this._iframe.contentDocument)==null?void 0:d.querySelector("[data-composition-id]"))==null?void 0:c.getAttribute("data-composition-id"),n=s&&s in e?s:t[t.length-1],o=e[n];return Oe(o)?o:null}_resolvePlaybackDurationAdapter(i){const e=Reflect.get(i,"__player");if(Ie(e))return{kind:"runtime",getDuration:()=>e.getDuration()};const t=this._resolveDirectTimelineAdapterFromWindow(i);return t?{kind:"direct-timeline",timeline:t,getDuration:()=>t.duration()}:null}}const Ue=`
|
|
2
2
|
:host {
|
|
3
3
|
display: block;
|
|
4
4
|
position: relative;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{g as P}from"./index-
|
|
1
|
+
import{g as P}from"./index-DSazIt7R.js";function j(c,d){for(var s=0;s<d.length;s++){const a=d[s];if(typeof a!="string"&&!Array.isArray(a)){for(const i in a)if(i!=="default"&&!(i in c)){const l=Object.getOwnPropertyDescriptor(a,i);l&&Object.defineProperty(c,i,l.get?l:{enumerable:!0,get:()=>a[i]})}}}return Object.freeze(Object.defineProperty(c,Symbol.toStringTag,{value:"Module"}))}var v={},w;function k(){if(w)return v;w=1,Object.defineProperty(v,"__esModule",{value:!0}),v.default=d;var c=window.OfflineAudioContext||window.webkitOfflineAudioContext;function d(e){var r=a(e);return r.start(0),[i,y,O(e.sampleRate),s].reduce(function(t,o){return o(t)},r.buffer.getChannelData(0))}function s(e){return e.sort(function(r,t){return t.count-r.count}).splice(0,5)[0].tempo}function a(e){var r=e.length,t=e.numberOfChannels,o=e.sampleRate,n=new c(t,r,o),u=n.createBufferSource();u.buffer=e;var f=n.createBiquadFilter();return f.type="lowpass",u.connect(f),f.connect(n.destination),u}function i(e){for(var r=[],t=.9,o=.3,n=15;r.length<n&&t>=o;)r=l(e,t),t-=.05;if(r.length<n)throw new Error("Could not find enough samples for a reliable detection.");return r}function l(e,r){for(var t=[],o=0,n=e.length;o<n;o+=1)e[o]>r&&(t.push(o),o+=1e4);return t}function y(e){var r=[];return e.forEach(function(t,o){for(var n=function(x){var g=e[o+x]-t,_=r.some(function(h){if(h.interval===g)return h.count+=1});_||r.push({interval:g,count:1})},u=0;u<10;u+=1)n(u)}),r}function O(e){return function(r){var t=[];return r.forEach(function(o){if(o.interval!==0){for(var n=60/(o.interval/e);n<90;)n*=2;for(;n>180;)n/=2;n=Math.round(n);var u=t.some(function(f){if(f.tempo===n)return f.count+=o.count});u||t.push({tempo:n,count:o.count})}}),t}}return v}var p,b;function q(){return b||(b=1,p=k().default),p}var m=q();const A=P(m),D=j({__proto__:null,default:A},[m]);export{D as i};
|