hyperframes 0.8.58 → 0.8.60

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 (182) hide show
  1. package/dist/cli.js +4529 -3220
  2. package/dist/docs/data-attributes.md +2 -1
  3. package/dist/fontLocalizeCli.js +96 -16
  4. package/dist/hyperframe-runtime.js +25 -25
  5. package/dist/hyperframe.manifest.json +1 -1
  6. package/dist/hyperframe.runtime.iife.js +25 -25
  7. package/dist/hyperframes-player.global.js +3 -3
  8. package/dist/registry/localSemantic.js +548 -0
  9. package/dist/skills/hyperframes-cli/SKILL.md +2 -2
  10. package/dist/skills/media-use/SKILL.md +96 -0
  11. package/dist/skills/media-use/audio/assets/sfx/CREDITS.md +35 -0
  12. package/dist/skills/media-use/audio/assets/sfx/chime.mp3 +0 -0
  13. package/dist/skills/media-use/audio/assets/sfx/click-soft.mp3 +0 -0
  14. package/dist/skills/media-use/audio/assets/sfx/click.mp3 +0 -0
  15. package/dist/skills/media-use/audio/assets/sfx/error.mp3 +0 -0
  16. package/dist/skills/media-use/audio/assets/sfx/glitch-1.mp3 +0 -0
  17. package/dist/skills/media-use/audio/assets/sfx/glitch-2.mp3 +0 -0
  18. package/dist/skills/media-use/audio/assets/sfx/glitch-3.mp3 +0 -0
  19. package/dist/skills/media-use/audio/assets/sfx/impact-bass-1.mp3 +0 -0
  20. package/dist/skills/media-use/audio/assets/sfx/impact-bass-2.mp3 +0 -0
  21. package/dist/skills/media-use/audio/assets/sfx/key-press.mp3 +0 -0
  22. package/dist/skills/media-use/audio/assets/sfx/manifest.json +97 -0
  23. package/dist/skills/media-use/audio/assets/sfx/notification.mp3 +0 -0
  24. package/dist/skills/media-use/audio/assets/sfx/ping.mp3 +0 -0
  25. package/dist/skills/media-use/audio/assets/sfx/pop.mp3 +0 -0
  26. package/dist/skills/media-use/audio/assets/sfx/riser.mp3 +0 -0
  27. package/dist/skills/media-use/audio/assets/sfx/sparkle.mp3 +0 -0
  28. package/dist/skills/media-use/audio/assets/sfx/typing.mp3 +0 -0
  29. package/dist/skills/media-use/audio/assets/sfx/whoosh-cinematic.mp3 +0 -0
  30. package/dist/skills/media-use/audio/assets/sfx/whoosh-short.mp3 +0 -0
  31. package/dist/skills/media-use/audio/assets/sfx/whoosh.mp3 +0 -0
  32. package/dist/skills/media-use/audio/references/bgm.md +74 -0
  33. package/dist/skills/media-use/audio/references/captions/authoring.md +163 -0
  34. package/dist/skills/media-use/audio/references/captions/motion.md +87 -0
  35. package/dist/skills/media-use/audio/references/captions/transcript-handling.md +97 -0
  36. package/dist/skills/media-use/audio/references/remove-background.md +143 -0
  37. package/dist/skills/media-use/audio/references/requirements.md +29 -0
  38. package/dist/skills/media-use/audio/references/sfx.md +42 -0
  39. package/dist/skills/media-use/audio/references/transcribe.md +52 -0
  40. package/dist/skills/media-use/audio/references/tts-to-captions.md +26 -0
  41. package/dist/skills/media-use/audio/references/tts.md +165 -0
  42. package/dist/skills/media-use/audio/scripts/audio.mjs +295 -0
  43. package/dist/skills/media-use/audio/scripts/audio.test.mjs +49 -0
  44. package/dist/skills/media-use/audio/scripts/heygen-tts.mjs +121 -0
  45. package/dist/skills/media-use/audio/scripts/lib/audio-meta.mjs +39 -0
  46. package/dist/skills/media-use/audio/scripts/lib/audio-meta.test.mjs +136 -0
  47. package/dist/skills/media-use/audio/scripts/lib/bgm.mjs +257 -0
  48. package/dist/skills/media-use/audio/scripts/lib/bgm.test.mjs +30 -0
  49. package/dist/skills/media-use/audio/scripts/lib/concurrency.mjs +14 -0
  50. package/dist/skills/media-use/audio/scripts/lib/concurrency.test.mjs +41 -0
  51. package/dist/skills/media-use/audio/scripts/lib/heygen.mjs +156 -0
  52. package/dist/skills/media-use/audio/scripts/lib/heygen.test.mjs +103 -0
  53. package/dist/skills/media-use/audio/scripts/lib/python.mjs +63 -0
  54. package/dist/skills/media-use/audio/scripts/lib/python.test.mjs +68 -0
  55. package/dist/skills/media-use/audio/scripts/lib/sfx.mjs +143 -0
  56. package/dist/skills/media-use/audio/scripts/lib/sfx.test.mjs +69 -0
  57. package/dist/skills/media-use/audio/scripts/lib/tts.mjs +379 -0
  58. package/dist/skills/media-use/audio/scripts/lib/tts.spawn.test.mjs +158 -0
  59. package/dist/skills/media-use/audio/scripts/lib/tts.test.mjs +157 -0
  60. package/dist/skills/media-use/audio/scripts/lyria-recipe.py +136 -0
  61. package/dist/skills/media-use/audio/scripts/wait-bgm.mjs +171 -0
  62. package/dist/skills/media-use/audio/scripts/wait-bgm.test.mjs +65 -0
  63. package/dist/skills/media-use/luts/README.md +28 -0
  64. package/dist/skills/media-use/luts/index.json +57 -0
  65. package/dist/skills/media-use/references/audio.md +19 -0
  66. package/dist/skills/media-use/references/grading.md +160 -0
  67. package/dist/skills/media-use/references/media-treatment-recipes.md +929 -0
  68. package/dist/skills/media-use/references/media-treatments.md +202 -0
  69. package/dist/skills/media-use/references/memory.md +36 -0
  70. package/dist/skills/media-use/references/meta.md +61 -0
  71. package/dist/skills/media-use/references/operations.md +325 -0
  72. package/dist/skills/media-use/references/resolve.md +150 -0
  73. package/dist/skills/media-use/references/setup-providers.md +80 -0
  74. package/dist/skills/media-use/references/telemetry-dashboard.md +49 -0
  75. package/dist/skills/media-use/registry/localSemantic.js +548 -0
  76. package/dist/skills/media-use/scripts/audio-duck.mjs +113 -0
  77. package/dist/skills/media-use/scripts/compatibility.test.mjs +27 -0
  78. package/dist/skills/media-use/scripts/dither.mjs +328 -0
  79. package/dist/skills/media-use/scripts/dither.test.mjs +176 -0
  80. package/dist/skills/media-use/scripts/eval.mjs +369 -0
  81. package/dist/skills/media-use/scripts/lib/adopt.mjs +128 -0
  82. package/dist/skills/media-use/scripts/lib/adopt.test.mjs +95 -0
  83. package/dist/skills/media-use/scripts/lib/bgm-provider.mjs +20 -0
  84. package/dist/skills/media-use/scripts/lib/brand-provider.mjs +59 -0
  85. package/dist/skills/media-use/scripts/lib/bundled-sfx-provider.mjs +119 -0
  86. package/dist/skills/media-use/scripts/lib/bundled-sfx-provider.test.mjs +139 -0
  87. package/dist/skills/media-use/scripts/lib/cache.mjs +150 -0
  88. package/dist/skills/media-use/scripts/lib/candidates.mjs +91 -0
  89. package/dist/skills/media-use/scripts/lib/candidates.test.mjs +155 -0
  90. package/dist/skills/media-use/scripts/lib/codex-provider.mjs +161 -0
  91. package/dist/skills/media-use/scripts/lib/codex-provider.test.mjs +34 -0
  92. package/dist/skills/media-use/scripts/lib/coverage.test.mjs +132 -0
  93. package/dist/skills/media-use/scripts/lib/cube-build.mjs +181 -0
  94. package/dist/skills/media-use/scripts/lib/cube-build.test.mjs +80 -0
  95. package/dist/skills/media-use/scripts/lib/cube-validate.mjs +198 -0
  96. package/dist/skills/media-use/scripts/lib/cube-validate.test.mjs +125 -0
  97. package/dist/skills/media-use/scripts/lib/cutlist.mjs +184 -0
  98. package/dist/skills/media-use/scripts/lib/cutlist.test.mjs +162 -0
  99. package/dist/skills/media-use/scripts/lib/duck.mjs +95 -0
  100. package/dist/skills/media-use/scripts/lib/duck.test.mjs +153 -0
  101. package/dist/skills/media-use/scripts/lib/error-diffusion.mjs +230 -0
  102. package/dist/skills/media-use/scripts/lib/error-diffusion.test.mjs +102 -0
  103. package/dist/skills/media-use/scripts/lib/freeze.mjs +62 -0
  104. package/dist/skills/media-use/scripts/lib/freeze.test.mjs +46 -0
  105. package/dist/skills/media-use/scripts/lib/grade-analyzer.mjs +265 -0
  106. package/dist/skills/media-use/scripts/lib/grade-analyzer.test.mjs +285 -0
  107. package/dist/skills/media-use/scripts/lib/heygen-cli.mjs +191 -0
  108. package/dist/skills/media-use/scripts/lib/heygen-cli.test.mjs +301 -0
  109. package/dist/skills/media-use/scripts/lib/heygen-search.mjs +45 -0
  110. package/dist/skills/media-use/scripts/lib/heygen-search.test.mjs +49 -0
  111. package/dist/skills/media-use/scripts/lib/heygen-video-provider.mjs +138 -0
  112. package/dist/skills/media-use/scripts/lib/heygen-video-provider.test.mjs +435 -0
  113. package/dist/skills/media-use/scripts/lib/image-provider.mjs +44 -0
  114. package/dist/skills/media-use/scripts/lib/index-gen.mjs +63 -0
  115. package/dist/skills/media-use/scripts/lib/local-media-search.mjs +32 -0
  116. package/dist/skills/media-use/scripts/lib/local-models.mjs +318 -0
  117. package/dist/skills/media-use/scripts/lib/local-models.test.mjs +220 -0
  118. package/dist/skills/media-use/scripts/lib/local-run.mjs +78 -0
  119. package/dist/skills/media-use/scripts/lib/local-run.test.mjs +121 -0
  120. package/dist/skills/media-use/scripts/lib/logo-provider.mjs +223 -0
  121. package/dist/skills/media-use/scripts/lib/logo-provider.test.mjs +154 -0
  122. package/dist/skills/media-use/scripts/lib/ltx-video-provider.mjs +94 -0
  123. package/dist/skills/media-use/scripts/lib/ltx-video-provider.test.mjs +316 -0
  124. package/dist/skills/media-use/scripts/lib/lut-preset-provider.mjs +271 -0
  125. package/dist/skills/media-use/scripts/lib/lut-preset-provider.test.mjs +199 -0
  126. package/dist/skills/media-use/scripts/lib/manifest.mjs +229 -0
  127. package/dist/skills/media-use/scripts/lib/manifest.test.mjs +388 -0
  128. package/dist/skills/media-use/scripts/lib/match.mjs +47 -0
  129. package/dist/skills/media-use/scripts/lib/media-fetch.mjs +71 -0
  130. package/dist/skills/media-use/scripts/lib/media-fetch.test.mjs +169 -0
  131. package/dist/skills/media-use/scripts/lib/media-search.d.mts +9 -0
  132. package/dist/skills/media-use/scripts/lib/media-search.mjs +107 -0
  133. package/dist/skills/media-use/scripts/lib/mflux-provider.mjs +128 -0
  134. package/dist/skills/media-use/scripts/lib/mflux-provider.test.mjs +174 -0
  135. package/dist/skills/media-use/scripts/lib/misses.mjs +49 -0
  136. package/dist/skills/media-use/scripts/lib/misses.test.mjs +78 -0
  137. package/dist/skills/media-use/scripts/lib/npx-sync.mjs +31 -0
  138. package/dist/skills/media-use/scripts/lib/npx-sync.test.mjs +50 -0
  139. package/dist/skills/media-use/scripts/lib/parakeet-words.mjs +27 -0
  140. package/dist/skills/media-use/scripts/lib/parakeet-words.test.mjs +44 -0
  141. package/dist/skills/media-use/scripts/lib/prefs-store.mjs +180 -0
  142. package/dist/skills/media-use/scripts/lib/prefs-store.test.mjs +189 -0
  143. package/dist/skills/media-use/scripts/lib/probe.mjs +39 -0
  144. package/dist/skills/media-use/scripts/lib/probe.test.mjs +31 -0
  145. package/dist/skills/media-use/scripts/lib/providers.mjs +5 -0
  146. package/dist/skills/media-use/scripts/lib/recipe-store.mjs +367 -0
  147. package/dist/skills/media-use/scripts/lib/recipe-store.test.mjs +367 -0
  148. package/dist/skills/media-use/scripts/lib/registry.mjs +218 -0
  149. package/dist/skills/media-use/scripts/lib/registry.test.mjs +262 -0
  150. package/dist/skills/media-use/scripts/lib/search.mjs +24 -0
  151. package/dist/skills/media-use/scripts/lib/search.test.mjs +32 -0
  152. package/dist/skills/media-use/scripts/lib/sfx-provider.mjs +23 -0
  153. package/dist/skills/media-use/scripts/lib/specs.mjs +132 -0
  154. package/dist/skills/media-use/scripts/lib/specs.test.mjs +157 -0
  155. package/dist/skills/media-use/scripts/lib/stats.mjs +117 -0
  156. package/dist/skills/media-use/scripts/lib/stats.test.mjs +165 -0
  157. package/dist/skills/media-use/scripts/lib/telemetry.mjs +193 -0
  158. package/dist/skills/media-use/scripts/lib/telemetry.test.mjs +373 -0
  159. package/dist/skills/media-use/scripts/lib/tts-local-provider.mjs +92 -0
  160. package/dist/skills/media-use/scripts/lib/tts-local-provider.test.mjs +72 -0
  161. package/dist/skills/media-use/scripts/lib/usage.mjs +57 -0
  162. package/dist/skills/media-use/scripts/lib/usage.test.mjs +54 -0
  163. package/dist/skills/media-use/scripts/lib/voice-provider.mjs +57 -0
  164. package/dist/skills/media-use/scripts/lib/voice-provider.test.mjs +46 -0
  165. package/dist/skills/media-use/scripts/lib/words.mjs +18 -0
  166. package/dist/skills/media-use/scripts/prefs.mjs +70 -0
  167. package/dist/skills/media-use/scripts/recipe.mjs +103 -0
  168. package/dist/skills/media-use/scripts/resolve.mjs +1287 -0
  169. package/dist/skills/media-use/scripts/transcribe.mjs +180 -0
  170. package/dist/skills/media-use/scripts/transcript-cut.mjs +239 -0
  171. package/dist/skills/registry/localSemantic.js +548 -0
  172. package/dist/studio/assets/{hyperframes-player-zGyOcwwh.js → hyperframes-player-Di7GyCOP.js} +3 -3
  173. package/dist/studio/assets/{index-DKJpHYYd.css → index-CBKb_0TI.css} +1 -1
  174. package/dist/studio/assets/{index-d8ferjRc.js → index-Dpq2lkOm.js} +190 -190
  175. package/dist/studio/assets/{index-ZJaRCDYV.js → index-Dx_pt9m4.js} +1 -1
  176. package/dist/studio/assets/{index-BcE2OSVA.js → index-jAjhQTrB.js} +1 -1
  177. package/dist/studio/index.d.ts +549 -13
  178. package/dist/studio/index.html +2 -2
  179. package/dist/studio/index.js +23133 -21941
  180. package/dist/studio/index.js.map +1 -1
  181. package/dist/studio/styles.css +1 -1
  182. package/package.json +1 -1
@@ -0,0 +1,548 @@
1
+ import { createRequire as __hf_createRequire } from "node:module";
2
+ import { fileURLToPath as __hf_fileURLToPath } from "node:url";
3
+ import { dirname as __hf_dirname } from "node:path";
4
+ var require = __hf_createRequire(import.meta.url);
5
+ var __filename = __hf_fileURLToPath(import.meta.url);
6
+ var __dirname = __hf_dirname(__filename);
7
+
8
+ // src/registry/localSemantic.ts
9
+ import { existsSync as existsSync4, mkdirSync as mkdirSync4, readFileSync as readFileSync5, writeFileSync as writeFileSync3 } from "fs";
10
+ import { homedir as homedir4 } from "os";
11
+ import { join as join4 } from "path";
12
+
13
+ // src/registry/localEmbedder.ts
14
+ import { readFileSync as readFileSync4 } from "fs";
15
+
16
+ // src/utils/optionalPackages.ts
17
+ import { spawn } from "child_process";
18
+ import { randomUUID } from "crypto";
19
+ import {
20
+ existsSync,
21
+ mkdirSync,
22
+ readdirSync,
23
+ readFileSync,
24
+ renameSync,
25
+ rmSync,
26
+ writeFileSync
27
+ } from "fs";
28
+ import { createRequire } from "module";
29
+ import { homedir } from "os";
30
+ import { basename, dirname, join } from "path";
31
+
32
+ // src/utils/npxCommand.ts
33
+ function buildCmdShimCommand(name, args, platform) {
34
+ if (platform === "win32") {
35
+ return { command: "cmd.exe", args: ["/d", "/s", "/c", `${name}.cmd`, ...args] };
36
+ }
37
+ return { command: name, args: [...args] };
38
+ }
39
+ function buildNpmCommand(args, platform = process.platform) {
40
+ return buildCmdShimCommand("npm", args, platform);
41
+ }
42
+
43
+ // src/utils/optionalPackages.ts
44
+ var OPTIONAL_PACKAGES = {
45
+ "onnxruntime-node": "1.21.1",
46
+ "@google/genai": "1.52.0"
47
+ };
48
+ var CACHE_DIR = join(homedir(), ".cache", "hyperframes", "optional");
49
+ function optionalPackageDir(name, cacheDir = CACHE_DIR) {
50
+ return join(cacheDir, `${name.replace("/", "__")}@${OPTIONAL_PACKAGES[name]}`);
51
+ }
52
+ async function loadOptionalPackage(name, feature, deps = defaultDeps) {
53
+ const dir = optionalPackageDir(name, deps.cacheDir);
54
+ const installed = deps.loadInstalled(dir, name);
55
+ if (installed !== null) return installed;
56
+ const version = OPTIONAL_PACKAGES[name];
57
+ deps.log(`installing ${name} for ${feature}, once`);
58
+ try {
59
+ await deps.install(dir, name, version);
60
+ } catch (err) {
61
+ const output = err.message.trim();
62
+ const advice = NETWORK_FAILURE.test(output) ? "Check your network connection, then retry" : "Retry";
63
+ throw new Error(
64
+ `${feature} needs ${name}, and installing it failed (${output.split("\n")[0]}). ${advice}, or install it yourself: npm install ${name}@${version} --prefix "${dir}"`
65
+ );
66
+ }
67
+ const loaded = deps.loadInstalled(dir, name);
68
+ if (loaded === null) {
69
+ throw new Error(`${name}@${version} installed into ${dir} but could not be loaded.`);
70
+ }
71
+ return loaded;
72
+ }
73
+ var NETWORK_FAILURE = /ENOTFOUND|ETIMEDOUT|EAI_AGAIN|ECONNRESET|ECONNREFUSED|network/i;
74
+ function manifestPath(dir, name) {
75
+ return join(dir, "node_modules", name, "package.json");
76
+ }
77
+ function isInstalled(dir, name) {
78
+ return existsSync(manifestPath(dir, name));
79
+ }
80
+ function loadInstalled(dir, name) {
81
+ if (!isInstalled(dir, name)) return null;
82
+ return createRequire(join(dir, "package.json"))(name);
83
+ }
84
+ function runNpm(args) {
85
+ const npm = buildNpmCommand(args);
86
+ const child = spawn(npm.command, npm.args, { stdio: ["ignore", "pipe", "pipe"] });
87
+ return new Promise((resolve, reject) => {
88
+ let output = "";
89
+ child.stdout.on("data", (chunk) => output += chunk);
90
+ child.stderr.on("data", (chunk) => output += chunk);
91
+ child.on("error", reject);
92
+ child.on(
93
+ "close",
94
+ (code) => code === 0 ? resolve() : reject(new Error(output || `npm exited with code ${code}`))
95
+ );
96
+ });
97
+ }
98
+ function isProcessAlive(pid) {
99
+ try {
100
+ process.kill(pid, 0);
101
+ return true;
102
+ } catch (err) {
103
+ return err.code !== "ESRCH";
104
+ }
105
+ }
106
+ function sweepStaleStaging(dir) {
107
+ const prefix = `${basename(dir)}.tmp-`;
108
+ const parent = dirname(dir);
109
+ if (!existsSync(parent)) return;
110
+ for (const entry of readdirSync(parent)) {
111
+ if (!entry.startsWith(prefix)) continue;
112
+ const pid = /^(\d+)(?:-|$)/.exec(entry.slice(prefix.length))?.[1];
113
+ if (pid === void 0 || isProcessAlive(Number(pid))) continue;
114
+ const stale = join(parent, entry);
115
+ try {
116
+ rmSync(stale, { recursive: true, force: true });
117
+ } catch (err) {
118
+ console.error(`could not remove stale install dir ${stale}: ${err.message}`);
119
+ }
120
+ }
121
+ }
122
+ async function install(dir, name, version, run = runNpm) {
123
+ sweepStaleStaging(dir);
124
+ const staging = `${dir}.tmp-${process.pid}-${randomUUID().slice(0, 8)}`;
125
+ mkdirSync(staging, { recursive: true });
126
+ writeFileSync(join(staging, "package.json"), "{}");
127
+ try {
128
+ await run([
129
+ "install",
130
+ `${name}@${version}`,
131
+ "--prefix",
132
+ staging,
133
+ "--no-audit",
134
+ "--no-fund",
135
+ "--loglevel=error",
136
+ // A first-use install is interactive, not a CI resolve: fail fast and name the
137
+ // manual command instead of sitting through npm's default multi-minute backoff.
138
+ "--fetch-retries=0",
139
+ "--fetch-timeout=20000"
140
+ ]);
141
+ if (isInstalled(dir, name)) return;
142
+ rmSync(dir, { recursive: true, force: true });
143
+ renameSync(staging, dir);
144
+ } catch (err) {
145
+ if (!isInstalled(dir, name)) throw err;
146
+ } finally {
147
+ rmSync(staging, { recursive: true, force: true });
148
+ }
149
+ }
150
+ var defaultDeps = {
151
+ cacheDir: CACHE_DIR,
152
+ loadInstalled,
153
+ install,
154
+ log: (line) => console.error(line)
155
+ };
156
+
157
+ // src/registry/localModel.ts
158
+ import { createHash } from "crypto";
159
+ import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync3, unlinkSync as unlinkSync2 } from "fs";
160
+ import { homedir as homedir3 } from "os";
161
+ import { join as join3 } from "path";
162
+
163
+ // src/utils/download.ts
164
+ import { randomUUID as randomUUID2 } from "crypto";
165
+ import { createWriteStream, renameSync as renameSync2, unlinkSync } from "fs";
166
+ import { get as httpsGet } from "https";
167
+ import { Transform } from "stream";
168
+ import { pipeline } from "stream/promises";
169
+
170
+ // src/telemetry/config.ts
171
+ import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, renameSync as renameSync3, rmSync as rmSync2, writeFileSync as writeFileSync2 } from "fs";
172
+ import { join as join2 } from "path";
173
+ import { homedir as homedir2 } from "os";
174
+ import { randomUUID as randomUUID3 } from "crypto";
175
+ var CONFIG_DIR = join2(homedir2(), ".hyperframes");
176
+ var CONFIG_FILE = join2(CONFIG_DIR, "config.json");
177
+ var STATE_FILE = join2(CONFIG_DIR, "install-state.json");
178
+ var LEGACY_STATE_FILE = join2(homedir2(), ".local", "state", "hyperframes", "install-state.json");
179
+
180
+ // src/registry/localModel.ts
181
+ var LOCAL_MODEL_ID = "bge-small-en-v1.5";
182
+ var LOCAL_MODEL_DIMENSIONS = 384;
183
+ var QUERY_INSTRUCTION = "Represent this sentence for searching relevant passages: ";
184
+ var MODELS_DIR = join3(homedir3(), ".hyperframes", "models");
185
+ var MODEL_REPO = "Xenova/bge-small-en-v1.5";
186
+ var LOCAL_MODEL_REVISION = "ea104dacec62c0de699686887e3f920caeb4f3e3";
187
+ var LOCAL_MODEL_ARTIFACTS = [
188
+ {
189
+ url: `https://huggingface.co/${MODEL_REPO}/resolve/${LOCAL_MODEL_REVISION}/onnx/model_quantized.onnx`,
190
+ dest: () => localModelPath(),
191
+ bytes: 34014426,
192
+ sha256: "6c9c6101a956d62dfb5e7190c538226c0c5bb9cb27b651234b6df063ee7dbfe4"
193
+ },
194
+ {
195
+ url: `https://huggingface.co/${MODEL_REPO}/resolve/${LOCAL_MODEL_REVISION}/tokenizer.json`,
196
+ dest: () => localTokenizerPath(),
197
+ bytes: 711396,
198
+ sha256: "d241a60d5e8f04cc1b2b3e9ef7a4921b27bf526d9f6050ab90f9267a1f9e5c66"
199
+ }
200
+ ];
201
+ function localModelPath() {
202
+ return join3(MODELS_DIR, `${LOCAL_MODEL_ID}.onnx`);
203
+ }
204
+ function localTokenizerPath() {
205
+ return join3(MODELS_DIR, `${LOCAL_MODEL_ID}.tokenizer.json`);
206
+ }
207
+ function modelFileIsValid(file) {
208
+ const path = file.dest();
209
+ if (!existsSync3(path)) return false;
210
+ try {
211
+ return createHash("sha256").update(readFileSync3(path)).digest("hex") === file.sha256;
212
+ } catch {
213
+ return false;
214
+ }
215
+ }
216
+ function isLocalModelReady() {
217
+ return LOCAL_MODEL_ARTIFACTS.every(modelFileIsValid);
218
+ }
219
+
220
+ // src/registry/wordpiece.ts
221
+ function configFromTokenizerJson(raw) {
222
+ const parsed = JSON.parse(raw);
223
+ const model = parsed.model;
224
+ if (!model?.vocab) throw new Error("tokenizer.json has no WordPiece vocab");
225
+ return {
226
+ vocab: model.vocab,
227
+ unkToken: model.unk_token ?? "[UNK]",
228
+ continuingSubwordPrefix: model.continuing_subword_prefix ?? "##",
229
+ maxInputCharsPerWord: model.max_input_chars_per_word ?? 100,
230
+ clsToken: "[CLS]",
231
+ sepToken: "[SEP]"
232
+ };
233
+ }
234
+ function normalize(text) {
235
+ let out = "";
236
+ for (const char of text) {
237
+ const code = char.codePointAt(0);
238
+ if (code === 0 || code === 65533) continue;
239
+ if (isControl(char, code)) continue;
240
+ if (isWhitespace(char, code)) {
241
+ out += " ";
242
+ continue;
243
+ }
244
+ out += isChinese(code) ? ` ${char} ` : char;
245
+ }
246
+ return out.toLowerCase().normalize("NFD").replace(new RegExp("\\p{Mn}", "gu"), "");
247
+ }
248
+ function preTokenize(normalized) {
249
+ const words = [];
250
+ for (const chunk of normalized.split(/\s+/)) {
251
+ if (!chunk) continue;
252
+ let current = "";
253
+ for (const char of chunk) {
254
+ if (isPunctuation(char)) {
255
+ if (current) words.push(current);
256
+ words.push(char);
257
+ current = "";
258
+ } else {
259
+ current += char;
260
+ }
261
+ }
262
+ if (current) words.push(current);
263
+ }
264
+ return words;
265
+ }
266
+ function wordPiece(word, config) {
267
+ if ([...word].length > config.maxInputCharsPerWord) return [config.unkToken];
268
+ const pieces = [];
269
+ let start = 0;
270
+ while (start < word.length) {
271
+ let end = word.length;
272
+ let match = null;
273
+ while (start < end) {
274
+ const candidate = start === 0 ? word.slice(start, end) : config.continuingSubwordPrefix + word.slice(start, end);
275
+ if (candidate in config.vocab) {
276
+ match = candidate;
277
+ break;
278
+ }
279
+ end -= 1;
280
+ }
281
+ if (match === null) return [config.unkToken];
282
+ pieces.push(match);
283
+ start = end;
284
+ }
285
+ return pieces;
286
+ }
287
+ function encode(text, config) {
288
+ const tokens = [config.clsToken];
289
+ for (const word of preTokenize(normalize(text))) tokens.push(...wordPiece(word, config));
290
+ tokens.push(config.sepToken);
291
+ const unk = config.vocab[config.unkToken];
292
+ const ids = tokens.map((token) => config.vocab[token] ?? unk);
293
+ return {
294
+ ids,
295
+ attentionMask: ids.map(() => 1),
296
+ tokenTypeIds: ids.map(() => 0)
297
+ };
298
+ }
299
+ function isControl(char, code) {
300
+ if (char === " " || char === "\n" || char === "\r") return false;
301
+ return code < 32 || code === 127 || new RegExp("\\p{Cc}|\\p{Cf}", "u").test(char);
302
+ }
303
+ function isWhitespace(char, code) {
304
+ return char === " " || char === " " || char === "\n" || char === "\r" || code === 11 || code === 12 || new RegExp("\\p{Zs}", "u").test(char);
305
+ }
306
+ function isPunctuation(char) {
307
+ const code = char.codePointAt(0);
308
+ const asciiSymbol = code >= 33 && code <= 47 || code >= 58 && code <= 64 || code >= 91 && code <= 96 || code >= 123 && code <= 126;
309
+ return asciiSymbol || new RegExp("\\p{P}", "u").test(char);
310
+ }
311
+ function isChinese(code) {
312
+ return code >= 19968 && code <= 40959 || code >= 13312 && code <= 19903 || code >= 131072 && code <= 173791 || code >= 173824 && code <= 177983 || code >= 177984 && code <= 178207 || code >= 178208 && code <= 183983 || code >= 63744 && code <= 64255 || code >= 194560 && code <= 195103;
313
+ }
314
+
315
+ // src/registry/localEmbedder.ts
316
+ var MAX_TOKENS = 512;
317
+ var FEATURE = "on-device search";
318
+ async function loadLocalEmbedder() {
319
+ const ort = await loadOptionalPackage("onnxruntime-node", FEATURE);
320
+ const config = configFromTokenizerJson(readFileSync4(localTokenizerPath(), "utf-8"));
321
+ const session = await ort.InferenceSession.create(localModelPath());
322
+ return {
323
+ async embed(texts, options) {
324
+ if (texts.length === 0) return [];
325
+ const prefix = options?.isQuery ? QUERY_INSTRUCTION : "";
326
+ const encodings = texts.map((text) => truncate(encode(prefix + text, config)));
327
+ const width = Math.max(...encodings.map((e) => e.ids.length));
328
+ const batch = encodings.length;
329
+ const ids = new BigInt64Array(batch * width);
330
+ const mask = new BigInt64Array(batch * width);
331
+ const types = new BigInt64Array(batch * width);
332
+ encodings.forEach((encoding, row) => {
333
+ encoding.ids.forEach((id, column) => {
334
+ const at = row * width + column;
335
+ ids[at] = BigInt(id);
336
+ mask[at] = 1n;
337
+ types[at] = 0n;
338
+ });
339
+ });
340
+ const dims = [batch, width];
341
+ const output = await session.run({
342
+ input_ids: new ort.Tensor("int64", ids, dims),
343
+ attention_mask: new ort.Tensor("int64", mask, dims),
344
+ token_type_ids: new ort.Tensor("int64", types, dims)
345
+ });
346
+ const hidden = output["last_hidden_state"];
347
+ if (!hidden) throw new Error("model returned no last_hidden_state");
348
+ const data = hidden.data;
349
+ const hiddenSize = hidden.dims[2];
350
+ if (hiddenSize !== LOCAL_MODEL_DIMENSIONS) {
351
+ throw new Error(
352
+ `model produced ${hiddenSize} dimensions, expected ${LOCAL_MODEL_DIMENSIONS}`
353
+ );
354
+ }
355
+ return encodings.map((_, row) => {
356
+ const start = row * width * hiddenSize;
357
+ return normalize2(Array.from(data.subarray(start, start + hiddenSize)));
358
+ });
359
+ }
360
+ };
361
+ }
362
+ function truncate(encoding) {
363
+ if (encoding.ids.length <= MAX_TOKENS) return encoding;
364
+ const ids = [
365
+ ...encoding.ids.slice(0, MAX_TOKENS - 1),
366
+ encoding.ids[encoding.ids.length - 1]
367
+ ];
368
+ return { ids, attentionMask: ids.map(() => 1), tokenTypeIds: ids.map(() => 0) };
369
+ }
370
+ function normalize2(vector) {
371
+ const norm = Math.sqrt(vector.reduce((sum, value) => sum + value * value, 0));
372
+ return norm === 0 ? vector : vector.map((value) => value / norm);
373
+ }
374
+ function cosine(a, b) {
375
+ let sum = 0;
376
+ for (let i = 0; i < a.length; i += 1) sum += a[i] * b[i];
377
+ return sum;
378
+ }
379
+
380
+ // src/registry/localSemantic.ts
381
+ function isMediaVectorRow(value) {
382
+ if (!value || typeof value !== "object") return false;
383
+ const row = value;
384
+ return typeof row.id === "string" && typeof row.kind === "string" && typeof row.title === "string" && typeof row.description === "string" && Array.isArray(row.tags) && row.tags.every((tag) => typeof tag === "string") && typeof row.file === "string" && (row.duration === void 0 || typeof row.duration === "number" && Number.isFinite(row.duration) && row.duration >= 0) && (row.dimensions === void 0 || typeof row.dimensions === "object" && row.dimensions !== null && Number.isInteger(row.dimensions.width) && Number.isInteger(row.dimensions.height) && row.dimensions.width > 0 && row.dimensions.height > 0);
385
+ }
386
+ var CATALOG_ARTIFACT_TIMEOUT_MS = 3e4;
387
+ function localVectorDirectory() {
388
+ return process.env["HYPERFRAMES_CATALOG_ARTIFACT_DIR"] ?? join4(homedir4(), ".hyperframes", "catalog");
389
+ }
390
+ function vectorPairAgrees(fetched, artifactBasename) {
391
+ const meta = fetched.find(([file]) => file === `${artifactBasename}.json`)?.[1];
392
+ const bin = fetched.find(([file]) => file === `${artifactBasename}.bin`)?.[1];
393
+ if (!meta || !bin) return false;
394
+ try {
395
+ const parsed = JSON.parse(meta.toString("utf-8"));
396
+ if (parsed.dimensions !== LOCAL_MODEL_DIMENSIONS) return false;
397
+ if (artifactBasename === "media-vectors" && (!parsed.rows || parsed.rows.length !== (parsed.names?.length ?? -1) || parsed.rows.some(
398
+ (row, index) => !isMediaVectorRow(row) || row.id !== parsed.names?.[index]
399
+ ))) {
400
+ return false;
401
+ }
402
+ return bin.byteLength === (parsed.names?.length ?? -1) * LOCAL_MODEL_DIMENSIONS * 4;
403
+ } catch {
404
+ return false;
405
+ }
406
+ }
407
+ function vectorRevisionAgrees(fetched, expectedRevision, artifactBasename = "local-vectors") {
408
+ if (expectedRevision === void 0) return true;
409
+ const meta = fetched.find(([file]) => file === `${artifactBasename}.json`)?.[1];
410
+ if (!meta) return false;
411
+ try {
412
+ const parsed = JSON.parse(meta.toString("utf-8"));
413
+ return parsed.revision === expectedRevision;
414
+ } catch {
415
+ return false;
416
+ }
417
+ }
418
+ async function fetchLocalVectors(registryBaseUrl, options = {}) {
419
+ const directory = options.directory ?? localVectorDirectory();
420
+ const artifactBasename = options.artifactBasename ?? "local-vectors";
421
+ const base = registryBaseUrl.replace(/\/+$/, "");
422
+ try {
423
+ mkdirSync4(directory, { recursive: true, mode: 448 });
424
+ const fetched = [];
425
+ for (const file of [`${artifactBasename}.json`, `${artifactBasename}.bin`]) {
426
+ const response = await fetch(`${base}/catalog-artifact/${file}`, {
427
+ signal: AbortSignal.timeout(CATALOG_ARTIFACT_TIMEOUT_MS)
428
+ });
429
+ if (!response.ok) return false;
430
+ fetched.push([file, Buffer.from(await response.arrayBuffer())]);
431
+ }
432
+ if (!vectorPairAgrees(fetched, artifactBasename) || !vectorRevisionAgrees(fetched, options.expectedRevision, artifactBasename)) {
433
+ return false;
434
+ }
435
+ for (const [file, bytes] of fetched) {
436
+ writeFileSync3(join4(directory, file), bytes, { mode: 384 });
437
+ }
438
+ return artifactBasename === "media-vectors" ? hasMediaVectors(directory) : hasLocalVectors(directory);
439
+ } catch {
440
+ return false;
441
+ }
442
+ }
443
+ function hasLocalVectors(directory = localVectorDirectory()) {
444
+ return existsSync4(join4(directory, "local-vectors.bin")) && existsSync4(join4(directory, "local-vectors.json"));
445
+ }
446
+ function hasMediaVectors(directory = localVectorDirectory()) {
447
+ return existsSync4(join4(directory, "media-vectors.bin")) && existsSync4(join4(directory, "media-vectors.json"));
448
+ }
449
+ function loadLocalVectors(directory = localVectorDirectory()) {
450
+ const meta = JSON.parse(
451
+ readFileSync5(join4(directory, "local-vectors.json"), "utf-8")
452
+ );
453
+ const buffer = readFileSync5(join4(directory, "local-vectors.bin"));
454
+ const vectors = new Float32Array(buffer.buffer, buffer.byteOffset, buffer.byteLength / 4);
455
+ const expected = meta.names.length * meta.dimensions;
456
+ if (vectors.length !== expected) {
457
+ throw new Error(`local vectors hold ${vectors.length} floats, expected ${expected}`);
458
+ }
459
+ if (meta.dimensions !== LOCAL_MODEL_DIMENSIONS) {
460
+ throw new Error(
461
+ `local vectors are ${meta.dimensions}-dimension, model produces ${LOCAL_MODEL_DIMENSIONS}`
462
+ );
463
+ }
464
+ return { names: meta.names, dimensions: meta.dimensions, vectors };
465
+ }
466
+ function loadMediaVectors(directory = localVectorDirectory()) {
467
+ const meta = JSON.parse(
468
+ readFileSync5(join4(directory, "media-vectors.json"), "utf-8")
469
+ );
470
+ const buffer = readFileSync5(join4(directory, "media-vectors.bin"));
471
+ const vectors = new Float32Array(buffer.buffer, buffer.byteOffset, buffer.byteLength / 4);
472
+ const rows = meta.rows ?? [];
473
+ if (rows.length !== meta.names.length) {
474
+ throw new Error(`media vectors hold ${rows.length} rows, expected ${meta.names.length}`);
475
+ }
476
+ if (rows.some((row, index) => !isMediaVectorRow(row) || row.id !== meta.names[index])) {
477
+ throw new Error("media vector row order does not match media vector names");
478
+ }
479
+ if (vectors.length !== rows.length * meta.dimensions) {
480
+ throw new Error(
481
+ `media vectors hold ${vectors.length} floats, expected ${rows.length * meta.dimensions}`
482
+ );
483
+ }
484
+ if (meta.dimensions !== LOCAL_MODEL_DIMENSIONS) {
485
+ throw new Error(
486
+ `media vectors are ${meta.dimensions}-dimension, model produces ${LOCAL_MODEL_DIMENSIONS}`
487
+ );
488
+ }
489
+ return { names: meta.names, dimensions: meta.dimensions, vectors, rows };
490
+ }
491
+ function localVectorNames(directory = localVectorDirectory()) {
492
+ if (!hasLocalVectors(directory)) return [];
493
+ try {
494
+ const meta = JSON.parse(readFileSync5(join4(directory, "local-vectors.json"), "utf-8"));
495
+ return meta.names ?? [];
496
+ } catch {
497
+ return [];
498
+ }
499
+ }
500
+ function cachedLocalVectorRevision(directory = localVectorDirectory()) {
501
+ if (!hasLocalVectors(directory)) return void 0;
502
+ try {
503
+ const meta = JSON.parse(readFileSync5(join4(directory, "local-vectors.json"), "utf-8"));
504
+ return typeof meta.revision === "string" ? meta.revision : void 0;
505
+ } catch {
506
+ return void 0;
507
+ }
508
+ }
509
+ async function localSemanticRanking(query, directory = localVectorDirectory()) {
510
+ if (!isLocalModelReady() || !hasLocalVectors(directory)) return null;
511
+ const set = loadLocalVectors(directory);
512
+ const embedder = await loadLocalEmbedder();
513
+ const [queryVector] = await embedder.embed([query], { isQuery: true });
514
+ if (!queryVector) return null;
515
+ const scored = set.names.map((name, row) => {
516
+ const start = row * set.dimensions;
517
+ return {
518
+ name,
519
+ score: cosine(queryVector, Array.from(set.vectors.subarray(start, start + set.dimensions)))
520
+ };
521
+ });
522
+ scored.sort((a, b) => b.score - a.score || b.name.localeCompare(a.name));
523
+ return scored;
524
+ }
525
+ async function mediaSemanticRanking(query, directory = localVectorDirectory()) {
526
+ if (!isLocalModelReady() || !hasMediaVectors(directory)) return null;
527
+ const set = loadMediaVectors(directory);
528
+ const embedder = await loadLocalEmbedder();
529
+ const [queryVector] = await embedder.embed([query], { isQuery: true });
530
+ if (!queryVector) return null;
531
+ return set.rows.map((row, index) => ({
532
+ row,
533
+ score: cosine(
534
+ queryVector,
535
+ Array.from(set.vectors.subarray(index * set.dimensions, (index + 1) * set.dimensions))
536
+ )
537
+ })).sort((a, b) => b.score - a.score || b.row.id.localeCompare(a.row.id));
538
+ }
539
+ export {
540
+ cachedLocalVectorRevision,
541
+ fetchLocalVectors,
542
+ hasLocalVectors,
543
+ isMediaVectorRow,
544
+ localSemanticRanking,
545
+ localVectorNames,
546
+ mediaSemanticRanking,
547
+ vectorPairAgrees
548
+ };