Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/studio/animation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ runtime expression, but it cannot always rewrite that source safely.

- **Unroll to edit** rewrites supported helper- or loop-generated motion as
explicit tweens that Studio can edit.
- **Computed value — edit it in the Code tab** means the value must be changed
- **Computed value. Edit it in the Code tab.**: the value must be changed
in source.
- When the intent is easier to state than the implementation, copy the element
context to your agent and describe the result you want preserved.
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"sync-schemas:check": "tsx scripts/sync-schemas.ts --check",
"sync:package-subpaths": "node scripts/package-subpaths.mjs --write",
"check:package-subpaths": "node scripts/package-subpaths.mjs",
"lint": "bun run check:docs-snippet-motion && bun run check:tracked-artifacts && bun run check:workspace-contracts && bun run check:gcp-cloud-run-dockerfile && bun run check:package-cycles && bun run check:package-subpaths && bun run check:cli-process-ownership && oxlint . && tsx scripts/lint-skills.ts && node scripts/check-skill-mirror.mjs",
"lint": "bun run check:docs-snippet-motion && bun run check:studio-copy-dashes && bun run check:tracked-artifacts && bun run check:workspace-contracts && bun run check:gcp-cloud-run-dockerfile && bun run check:package-cycles && bun run check:package-subpaths && bun run check:cli-process-ownership && oxlint . && tsx scripts/lint-skills.ts && node scripts/check-skill-mirror.mjs",
"check:gcp-cloud-run-dockerfile": "bun run --cwd packages/gcp-cloud-run test:dockerfile-workspaces",
"lint:skills": "tsx scripts/lint-skills.ts",
"check:skill-mirror": "node scripts/check-skill-mirror.mjs",
Expand All @@ -40,6 +40,7 @@
"check:workspace-contracts": "node scripts/check-workspace-contracts.mjs",
"check:package-cycles": "node scripts/check-package-cycles.mjs",
"check:cli-process-ownership": "node scripts/check-cli-process-ownership.mjs",
"check:studio-copy-dashes": "node scripts/check-studio-copy-dashes.mjs",
"format": "oxfmt .",
"test": "bun run test:unit",
"test:unit": "bun run --filter '*' test",
Expand All @@ -52,7 +53,7 @@
"player:perf": "bun run --filter @hyperframes/player perf",
"format:check": "oxfmt --check .",
"knip": "knip",
"test:scripts": "node --import tsx --test scripts/animejs-v4-guidance.test.mjs scripts/check-tracked-artifacts.test.mjs scripts/check-registry-set-delta.test.mjs scripts/check-no-main-deletions.test.mjs scripts/check-pr-captures.test.mjs scripts/check-comment-citations.test.mjs scripts/comments-workflow.test.mjs scripts/comment-ratchet.test.mjs scripts/check-docs-snippet-motion.test.mjs scripts/registry-target-paths.test.mjs scripts/check-workspace-contracts.test.mjs scripts/check-media-use-copy-parity.test.mjs scripts/check-svg-sanitize-parity.test.mjs scripts/check-media-use-svg-sanitize-generated.test.mjs scripts/check-package-cycles.test.mjs scripts/check-cli-process-ownership.test.mjs scripts/check-large-files.test.mjs scripts/prune-fallow-audit-caches.test.mjs scripts/package-subpaths.test.mjs scripts/validate-release-channel.test.mjs scripts/clawhub-sync.test.mjs scripts/publish-workflow.test.mjs scripts/pr-edit-concurrency.test.mjs scripts/merge-queue-workflows.test.mjs scripts/install-workspace-dependencies.test.mjs scripts/draft-changelog.test.ts scripts/set-version.test.ts scripts/release-prepare.test.ts scripts/cli-options.test.ts scripts/changelog-weekly.test.ts scripts/claude-plugin-compression.test.ts scripts/catalog-payload-assets.test.ts scripts/host-registry-assets.test.ts scripts/catalog-preview-temp.test.ts scripts/backfill-block-previews.test.ts scripts/catalog-hosted-files.test.ts scripts/player-cdn-pin.test.ts scripts/studio-runtime-smoke.test.mjs scripts/verify-packed-manifests.test.mjs scripts/lint-skills.test.mjs scripts/creator-editing-recipes.test.mjs packages/gcp-cloud-run/check-dockerfile-workspaces.test.mjs packages/core/scripts/writeGeneratedFile.test.ts scripts/catalog-publication.test.mjs scripts/ci/resolve-workflow-pr.test.mjs scripts/ci/base-file.test.mjs scripts/check-catalog-source-pr.test.mjs scripts/generate-registry-items.test.ts scripts/catalog-drift.test.ts scripts/catalog-fetch-mirror.test.ts scripts/catalog-script-inlining.test.ts scripts/catalog-detail.test.ts scripts/generate-catalog-pages.test.ts scripts/verify-catalog-payloads.test.ts scripts/registry-skill-files.test.ts scripts/creator-editing-capabilities.test.mjs scripts/generate-catalog-previews.test.ts scripts/registry-primitive-payloads.test.ts registry/components/pan-stations/pan-stations.test.mjs && vitest run scripts/catalog/ scripts/contrastRatchet.test.ts scripts/generate-catalog-payloads.test.ts",
"test:scripts": "node --import tsx --test scripts/animejs-v4-guidance.test.mjs scripts/check-tracked-artifacts.test.mjs scripts/check-registry-set-delta.test.mjs scripts/check-no-main-deletions.test.mjs scripts/check-pr-captures.test.mjs scripts/check-comment-citations.test.mjs scripts/comments-workflow.test.mjs scripts/comment-ratchet.test.mjs scripts/check-docs-snippet-motion.test.mjs scripts/registry-target-paths.test.mjs scripts/check-workspace-contracts.test.mjs scripts/check-media-use-copy-parity.test.mjs scripts/check-svg-sanitize-parity.test.mjs scripts/check-media-use-svg-sanitize-generated.test.mjs scripts/check-package-cycles.test.mjs scripts/check-cli-process-ownership.test.mjs scripts/check-studio-copy-dashes.test.mjs scripts/check-large-files.test.mjs scripts/prune-fallow-audit-caches.test.mjs scripts/package-subpaths.test.mjs scripts/validate-release-channel.test.mjs scripts/clawhub-sync.test.mjs scripts/publish-workflow.test.mjs scripts/pr-edit-concurrency.test.mjs scripts/merge-queue-workflows.test.mjs scripts/install-workspace-dependencies.test.mjs scripts/draft-changelog.test.ts scripts/set-version.test.ts scripts/release-prepare.test.ts scripts/cli-options.test.ts scripts/changelog-weekly.test.ts scripts/claude-plugin-compression.test.ts scripts/catalog-payload-assets.test.ts scripts/host-registry-assets.test.ts scripts/catalog-preview-temp.test.ts scripts/backfill-block-previews.test.ts scripts/catalog-hosted-files.test.ts scripts/player-cdn-pin.test.ts scripts/studio-runtime-smoke.test.mjs scripts/verify-packed-manifests.test.mjs scripts/lint-skills.test.mjs scripts/creator-editing-recipes.test.mjs packages/gcp-cloud-run/check-dockerfile-workspaces.test.mjs packages/core/scripts/writeGeneratedFile.test.ts scripts/catalog-publication.test.mjs scripts/ci/resolve-workflow-pr.test.mjs scripts/ci/base-file.test.mjs scripts/check-catalog-source-pr.test.mjs scripts/generate-registry-items.test.ts scripts/catalog-drift.test.ts scripts/catalog-fetch-mirror.test.ts scripts/catalog-script-inlining.test.ts scripts/catalog-detail.test.ts scripts/generate-catalog-pages.test.ts scripts/verify-catalog-payloads.test.ts scripts/registry-skill-files.test.ts scripts/creator-editing-capabilities.test.mjs scripts/generate-catalog-previews.test.ts scripts/registry-primitive-payloads.test.ts registry/components/pan-stations/pan-stations.test.mjs && vitest run scripts/catalog/ scripts/contrastRatchet.test.ts scripts/generate-catalog-payloads.test.ts",
"typecheck:scripts": "tsc --noEmit -p scripts/tsconfig.json",
"test:skills": "HYPERFRAMES_MEDIA_HOME_REQUIRED=1 node --import ./packages/cli/scripts/test-home.mjs --test 'skills/**/*.test.mjs' 'packages/cli/src/media-use/**/*.test.mjs'",
"generate:previews": "tsx scripts/generate-template-previews.ts",
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/utils/checkBrowser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ it("surfaces the runtime's web-audio-bypass console.info line as its own info fi
"info",
'[hyperframes] runtime_web_audio_bypass: "https://cdn.example.com/track.mp3" ' +
"(cross_origin_no_cors): Web Audio capture withheld; the track plays through native " +
"HTMLMediaElement output. Native playback cannot reproduce: fx-chain — proxy or download " +
"HTMLMediaElement output. Native playback cannot reproduce: fx-chain. Fix: proxy or download " +
"the asset to a same-origin URL to keep it.",
);
const authorInfo = fakeConsoleMessage("info", "debug runtime_web_audio_bypass lookalike");
Expand Down
14 changes: 7 additions & 7 deletions packages/core/src/audio/audioFxWorklets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const dbToLin = (db) => Math.pow(10, db / 20);
* Per channel matters: the followers advance once per sample, so a single shared
* follower stepped once per channel per sample. On stereo that ran a 20 ms attack
* as 10 ms, and gave the right channel a gain computed from an envelope that had
* already traversed the left — so the two channels ducked by different amounts
* already traversed the left, so the two channels ducked by different amounts
* from the same input and the image pumped.
*/
class EnvBank {
Expand Down Expand Up @@ -230,7 +230,7 @@ function readTap(ring, write, delaySamples) {
return ring[i0] * (1 - frac) + ring[i1] * frac;
}

/** Equal-power-ish crossfade, zero at a tap's reset point — hides the splice. */
/** Equal-power-ish crossfade, zero at a tap's reset point, which hides the splice. */
function xfade(phase) {
return Math.sin(Math.PI * phase);
}
Expand All @@ -242,7 +242,7 @@ function xfade(phase) {
* out, which hides the splice each tap makes when it wraps.
*
* write/phase are block-level state, advanced once per SAMPLE across all
* channels together (not once per channel) — advancing them inside the
* channels together (not once per channel). Advancing them inside the
* per-channel loop would move the tap 2x/4x too fast on a stereo/quad input.
*/
class HfPitchshift extends AudioWorkletProcessor {
Expand All @@ -255,13 +255,13 @@ class HfPitchshift extends AudioWorkletProcessor {
this.phase = 0;
// Samples written so far, capped at one grain. The taps read up to a grain
// behind the write head, so until this fills they would read the ring's
// zeros — the head of every clip came out attenuated or silent.
// zeros, so the head of every clip came out attenuated or silent.
this.filled = 0;
// How much of the wet (pitch-shifted) path is currently in the output, and
// where it is heading. Crossing between dry and wet is a ~50 ms jump in the
// signal, so it is RAMPED rather than switched: a hard swap either way is a
// click. Ramping in both directions is also what lets a node return to true
// bypass at semitones 0 — a one-way latch left preview stuck with the delay
// bypass at semitones 0. A one-way latch left preview stuck with the delay
// that the render, building a fresh node from the attribute, does not have.
this.wet = 0;
this.wetTarget = 0;
Expand Down Expand Up @@ -289,7 +289,7 @@ class HfPitchshift extends AudioWorkletProcessor {

// Nothing to shift, or mixed fully out. The grain delay is ~grain/2
// whatever the ratio, so at semitones=0 this degenerated into a pure 50 ms
// delay of the signal — while the copy for that exact setting reads
// delay of the signal, while the copy for that exact setting reads
// "Unchanged pitch".
this.wetTarget = semitones === 0 ? 0 : mix;

Expand Down Expand Up @@ -368,7 +368,7 @@ export function ensureAudioFxWorklets(ctx: BaseAudioContext): Promise<void> {
modulePromise = (async () => {
if (!ctx.audioWorklet) {
throw new Error(
"AudioWorklet is unavailable — the page needs a secure context (https, localhost or file://)",
"AudioWorklet is unavailable: the page needs a secure context (https, localhost or file://)",
);
}
// A data: URL rather than a blob:, because a blob inherits the page origin
Expand Down
10 changes: 5 additions & 5 deletions packages/core/src/audioFx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ const freq = (
automatable: true,
});

const qParam = (def = 0.707, hint = "Bandwidth — higher is narrower."): HfAudioFxNumberParam => ({
const qParam = (def = 0.707, hint = "Bandwidth: higher is narrower."): HfAudioFxNumberParam => ({
kind: "number",
key: "q",
label: "Q",
Expand Down Expand Up @@ -187,15 +187,15 @@ export const HF_AUDIO_FX: readonly HfAudioFxDef[] = [
id: "highpass",
label: "High-pass",
group: "filter",
description: "Remove low frequencies — the usual fix for rumble on a voice.",
description: "Remove low frequencies: the usual fix for rumble on a voice.",
params: [freq("frequency", "Cutoff", 300, 20, 20000), qParam(0.707), poles],
web: "biquad-highpass",
},
{
id: "lowpass",
label: "Low-pass",
group: "filter",
description: "Remove high frequencies — darkens or muffles a track.",
description: "Remove high frequencies, which darkens or muffles a track.",
params: [freq("frequency", "Cutoff", 8000, 100, 20000), qParam(0.707), poles],
web: "biquad-lowpass",
},
Expand Down Expand Up @@ -288,7 +288,7 @@ export const HF_AUDIO_FX: readonly HfAudioFxDef[] = [
id: "limiter",
label: "Limiter",
group: "dynamics",
description: "Hard ceiling — nothing gets past the limit.",
description: "Hard ceiling: nothing gets past the limit.",
params: [
{
kind: "number",
Expand Down Expand Up @@ -490,7 +490,7 @@ export const HF_AUDIO_FX: readonly HfAudioFxDef[] = [
max: 250,
step: 1,
default: 1,
hint: "Repeats each sample N times — a crude downsample.",
hint: "Repeats each sample N times, a crude downsample.",
},
{
kind: "number",
Expand Down
10 changes: 5 additions & 5 deletions packages/core/src/audioFxCopy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export const EFFECT_COPY: Record<string, EffectCopy> = {
},
highpass: {
title: "Remove Rumble",
does: "Cuts the very bottom — traffic, footsteps, air conditioning, hands on the mic.",
does: "Cuts the very bottom: traffic, footsteps, air conditioning, hands on the mic.",
reachFor: "There's a low hum or thump under everything.",
primary: "frequency",
primaryEnds: { low: "Only the deepest", high: "Thins it out" },
Expand Down Expand Up @@ -94,7 +94,7 @@ export const EFFECT_COPY: Record<string, EffectCopy> = {
peaking: {
title: "Shape One Range",
does: "Lifts or lowers one part of the sound and leaves the rest alone.",
reachFor: "One quality is wrong — boomy, boxy, harsh — but the rest is fine.",
reachFor: "One quality is wrong (boomy, boxy, harsh) but the rest is fine.",
primary: "gain",
primaryEnds: { low: "Take it out", high: "Bring it forward" },
band: [20, 20000],
Expand Down Expand Up @@ -168,15 +168,15 @@ export const EFFECT_COPY: Record<string, EffectCopy> = {
},
gate: {
title: "Silence the Gaps",
does: "Mutes the pauses. Whatever sits underneath stays — this closes the gaps, it does not remove noise.",
does: "Mutes the pauses. Whatever sits underneath stays: this closes the gaps, it does not remove noise.",
reachFor: "You can hear the room in the gaps.",
primary: "strength",
primaryEnds: { low: "Only true silence", high: "Cuts quiet parts too" },
params: {
threshold: { label: "Quieter than this is a gap" },
range: {
label: "How far to duck the gaps",
hint: "Not all the way down, usually — total silence sounds broken.",
hint: "Not all the way down, usually. Total silence sounds broken.",
},
ratio: { label: "How hard" },
attack: { label: "How fast it opens" },
Expand Down Expand Up @@ -394,7 +394,7 @@ export const SUMMARY: Record<string, (p: P) => string> = {
? "Doing nothing yet"
: `${n(p.gain) > 0 ? "More" : "Less"} sparkle above ${hz(p.frequency)}`,
compressor: (p) =>
`Evening out — ${strength(Math.min(1, (n(p.ratio, 3) - 1) / 7), ["gentle", "moderate", "firm"])}`,
`Evening out, ${strength(Math.min(1, (n(p.ratio, 3) - 1) / 7), ["gentle", "moderate", "firm"])}`,
limiter: (p) => `Nothing louder than ${n(p.limit, -1)} dB`,
gate: (p) => `Closing gaps quieter than ${n(p.threshold, -45)} dB`,
saturate: (p) =>
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/audioFxEq.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ export function removeAudioEq(chain: HfAudioFxChain, eqId: string): HfAudioFxCha
*/
export function audioEqSummary(bands: readonly HfAudioEqBand[]): string {
const moved = bands.filter((b) => Math.abs(b.gain) >= 0.1);
if (moved.length === 0) return "Flat — nothing changed yet";
if (moved.length === 0) return "Flat: nothing changed yet";
return moved
.map((b) => `${b.name} ${b.gain > 0 ? "+" : "−"}${Math.abs(Number(b.gain.toFixed(1)))}`)
.join(", ");
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/audioFxJobs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export const HF_AUDIO_FX_JOBS: readonly HfAudioFxJob[] = [
{
id: "tame-boominess",
label: "Tame Boominess",
does: "Too much low-end body — it booms.",
does: "Too much low-end body, so it booms.",
type: "peaking",
params: { frequency: 200, gain: -4, q: 1.4 },
},
Expand All @@ -72,7 +72,7 @@ export const HF_AUDIO_FX_JOBS: readonly HfAudioFxJob[] = [
{
id: "add-clarity",
label: "Add Clarity",
does: "It is hard to make out — it sits back.",
does: "It is hard to make out because it sits back.",
type: "peaking",
params: { frequency: 3000, gain: 2.5, q: 1 },
},
Expand Down
Loading
Loading