Skip to content

feat(studio): hosts can ask which action holds a key combination - #6979

Merged
miguel-heygen merged 3 commits into
mainfrom
dkeys/studio-key-clash-api
Nov 2, 2026
Merged

miguel-heygen merged 3 commits into
mainfrom
dkeys/studio-key-clash-api

Conversation

@miguel-heygen

@miguel-heygen miguel-heygen commented Nov 2, 2026 •

Copy link
Copy Markdown
Collaborator

What

Hosts that remap Studio's shortcuts can now ask which Studio action already holds a key combination, and parse, format and match combinations the same way Studio does. Exported from the package entry: studioKeyClash(action, text, keys?), parseCombo, formatCombo, matchCombo and the Combo type.

Why

A host's Settings screen has to refuse or offer a swap when a person picks a key another action holds. Without this the host copies Studio's clash rules, including the pairs that share a key on purpose, and the two drift.

How

studioKeyClash returns the other action on the same modifiers and key, or null. It skips pairs Studio shares by design (for example stop and add keyframe on K), so it agrees with the check setStudioKeys already runs. Nothing else changes.

Test plan

  • studioCombo.test.ts: a combo held by another action is named, Shift changes the answer, a shared pair is allowed, a combo freed by the passed map is not a clash.
  • Documentation updated: not applicable.
  • Comments follow CONTRIBUTING.md.

What I measured

On a Linux box: studioCombo.test.ts and studioShortcuts.test.tsx pass (18 tests); oxfmt --check ., oxlint, fallow audit --base origin/main and tsc --noEmit are clean.

What I did NOT exercise

No host uses it in this PR.

No visible change

No UI code changed; the helper only answers a question.

@heygengenesis heygengenesis Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: REQUEST CHANGES · 1 blocker · 0 important · 1 nit · head 78f6037d

The code looks right: studioKeyClash uses the same comboClashKey and sharedByDesign rules as findClash, so it agrees with setStudioKeys. The only blocker is the PR body.

  • blocker — required check Studio and player captures fails: the PR touches packages/studio, and the body has no ## Before/## After. The change is 19 counted lines and has no .tsx/.css, so the check accepts a ## No visible change heading instead. Turning the body's "No visual change: no UI code changed" line into that heading should clear it. Because the merge loop only waits for approval, I'm not approving while a required check is red.
  • nit — studioShortcuts.ts:125: parseCombo(keys[other])! throws a TypeError inside comboClashKey when a host passes a keys map with a value that doesn't parse, such as a stored "". findClash never sees this because resolve() validates first. Skipping or treating unparseable entries as "no clash" would make the exported helper safe for raw host maps.

@github-actions

github-actions Bot commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Edit accuracy: accurate 271 (base branch 271), smooth 121 of those

The gate passes.
Smoothness is reported in the artifact, not gated. A case fails only if it fails 2 of 3 runs.

Quarantined, measured but not gated (0)

Unstable (1)

  • seqplainkeys-none-center-r0-root-z100: tracking 0.06, pressJump 0, drop 0, reload 0, render 0.03, renderKey -, undo true, teleport true / tracking 0.06, pressJump 0, drop 0, reload 0, render 0.03, renderKey -, undo true, teleport true / tracking 0.06, pressJump 0, drop 0, reload 0, render 0.03, renderKey -, undo true, teleport true

@heygengenesis heygengenesis Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: REQUEST CHANGES · 1 blocker · 0 open from before · 78f6037d → 6a5717c9

✅ The unparseable-entry nit is fixed, and the new test case covers it.

  • blocker — required check Studio and player captures is still red: the ## No visible change heading is there now, but the new guard line takes the diff to 20 counted lines under packages/studio. The check only accepts that heading under 20 ("the limit is under 20"). To clear it, cut one counted line, for example by folding the null check and the comparison into a single expression, or add ## Before/## After captures.

@miguel-heygen
miguel-heygen force-pushed the dkeys/studio-key-clash-api branch from 6a5717c to 21647c3 Compare November 2, 2026 07:05

@heygengenesis heygengenesis Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: APPROVE · 0 blocker · 1 resolved · 6a5717c9 → 21647c3d

✅ The required check Studio and player captures passes now. The rebase left the two earlier commits unchanged (git range-diff). The rewrite of studioKeyClash still returns null for text that doesn't parse and skips map entries that don't parse, so behavior is the same. Required CI was still running at review time.

@miguel-heygen
miguel-heygen added this pull request to the merge queue Nov 2, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Nov 2, 2026
@miguel-heygen
miguel-heygen added this pull request to the merge queue Nov 2, 2026
Merged via the queue into main with commit 5fca435 Nov 2, 2026
78 checks passed
@miguel-heygen
miguel-heygen deleted the dkeys/studio-key-clash-api branch November 2, 2026 07:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant