Skip to content

Refactor configurator architecture and expand tests - #4

Merged
thannous merged 4 commits into
mainfrom
codex/refactor-architecture-tests
Jul 31, 2026
Merged

Refactor configurator architecture and expand tests#4
thannous merged 4 commits into
mainfrom
codex/refactor-architecture-tests

Conversation

@thannous

@thannous thannous commented Jul 31, 2026

Copy link
Copy Markdown
Owner

Summary

  • split the configurator into focused UI components, pure state helpers, presentation utilities, and an isolated profile workflow
  • centralize shared catalog and geometry data, remove duplicated work, add lookup indexes, and defer the profile export path
  • make CLI, HID, storage, and dependency boundaries easier to test through explicit injection points
  • expand maintainable coverage for the CLI, HID transport, profile generation, configurator state, rendering, architecture, localization, and Sites packaging

Why

The previous configurator concentrated too many responsibilities in one large component and several hardware-facing paths were difficult to exercise safely. This refactor makes behavior easier to understand, test, and evolve while reducing repeated computation and keeping hardware/profile mutations behind explicit boundaries.

Validation

  • npm run check
  • root: 100 tests passed; 71.98% line, 75.35% branch, 73.99% function coverage
  • prototype: 29 tests passed; 98.55% line, 92.43% branch, 97.62% function coverage
  • production Vite/Sites build completed successfully

Summary by CodeRabbit

  • New Features

    • Added an interactive configurator workspace with theme and language controls, device hotspots, mapping previews, and export actions.
    • Added joystick sector selection, custom key assignments, duplicate-assignment indicators, and profile import/export workflows.
    • Added profile review tools, conflict resolution, AppSense settings, validation, and downloadable reviewed profiles.
    • Added CLI help support and clearer English command-line messages.
  • Bug Fixes

    • Improved persistence, mapping validation, review invalidation, and handling of malformed or conflicting profiles.
    • Clarified that lighting failures do not affect shortcut operation.

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@thannous, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 29 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 7b0d33c9-7779-4379-a641-ced1e732100c

📥 Commits

Reviewing files that changed from the base of the PR and between 12f1b49 and ae77c23.

📒 Files selected for processing (28)
  • prototype/src/App.jsx
  • prototype/src/components/ConfiguratorWorkspace.jsx
  • prototype/src/components/JoystickDial.jsx
  • prototype/src/components/KeyAssignmentEditor.jsx
  • prototype/src/components/MappingDialog.jsx
  • prototype/src/components/ProfileReview.jsx
  • prototype/src/configurator-presenter.js
  • prototype/src/configurator-state.js
  • prototype/src/hooks/use-theme.js
  • prototype/src/i18n/de.js
  • prototype/src/i18n/en.js
  • prototype/src/i18n/es.js
  • prototype/src/i18n/fr.js
  • prototype/src/profile-panel-loader.js
  • prototype/src/profile-workflow.js
  • prototype/src/retryable-loader.js
  • prototype/src/styles.css
  • prototype/tests/app-render.test.mjs
  • prototype/tests/configurator-state.test.mjs
  • prototype/tests/presentation.test.mjs
  • prototype/tests/retryable-loader.test.mjs
  • scripts/configure.mjs
  • scripts/lib/hid-device.mjs
  • tests/cli.test.mjs
  • tests/hid-device.test.mjs
  • tests/hid-lighting.test.mjs
  • tests/input-layer.test.mjs
  • tests/thread-slots.test.mjs
📝 Walkthrough

Walkthrough

The PR modularizes the configurator and profile workflow, adds mapping and profile validation, introduces coverage commands and tests, updates shared profile geometry, improves CLI/HID handling, and translates tooling messages to English.

Changes

Configurator and profile workflow

Layer / File(s) Summary
Configurator state, UI, and profile workflow
prototype/src/App.jsx, prototype/src/components/*, prototype/src/configurator-*, prototype/src/profile-*, prototype/src/styles.css
The configurator is split into dedicated catalog, workspace, mapping, joystick, and profile components. Mapping persistence, conflict handling, review invalidation, lazy profile export, and profile-session transitions are centralized.
Configurator and profile validation
prototype/tests/*, package.json, prototype/package.json, .gitignore
Coverage scripts, thresholds, ignored coverage output, SSR tests, architecture tests, mapping tests, locale/theme tests, and profile-session tests are added.

Profile generation and shared mapping logic

Layer / File(s) Summary
Shared profile decoding and geometry
shared/input-profile.mjs, shared/thread-status-palette.mjs
Action lookup indexes and reusable radial joystick geometry are added. Wheel-mode validation uses own-property checks.
Profile generation and geometry tests
tests/helpers/input-profile-fixture.mjs, tests/input-profile.test.mjs
Tests reuse a shared profile fixture and cover invalid wheel assignments and radial geometry validation.

CLI, HID, and thread-status tooling

Layer / File(s) Summary
CLI, dependency, HID, and status behavior
scripts/*, scripts/lib/*, thread-status/bin/emit.mjs
CLI help support, injectable GUI dependency handling, HID queue timing and cleanup changes, and English comments and messages are added.
CLI, GUI dependency, HID, and thread-status tests
tests/cli.test.mjs, tests/gui-dependencies.test.mjs, tests/hid-*.test.mjs, tests/input-layer.test.mjs, tests/thread-slots.test.mjs
Integration tests cover command execution, dependency installation, HID sessions, validation diagnostics, lighting errors, and thread-status roster behavior.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant App
  participant ConfiguratorWorkspace
  participant MappingDialog
  participant ProfileExportPanel
  participant profile-workflow
  App->>ConfiguratorWorkspace: render mapping workspace
  ConfiguratorWorkspace->>MappingDialog: open mapping or export dialog
  MappingDialog->>ProfileExportPanel: load export panel
  ProfileExportPanel->>profile-workflow: prepare and review profile
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 29.93% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the primary changes: a configurator architecture refactor and expanded test coverage.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/refactor-architecture-tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 12f1b49bed

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tests/cli.test.mjs

Copy link
Copy Markdown
Owner Author

@codex review

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 7

🧹 Nitpick comments (8)
tests/input-layer.test.mjs (1)

247-254: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Guard the control lookups so fixture drift fails with a clear message.

Lines 249, 253 and 254 assign to the result of .find(...) without a check. If a control id in profiles/claude-shortcuts/mapping.json is renamed or removed, the test throws TypeError: Cannot set properties of undefined instead of reporting the missing control. Line 247 has the same coupling through positional access.

♻️ Proposed refactor
+      mutate({ manifest, mapping }) {
+        const control = (id) => {
+          const found = mapping.controls.find((candidate) => candidate.id === id);
+          assert.ok(found, `fixture must define control ${id}`);
+          return found;
+        };
         mapping.formatVersion = "2.0.0";
         mapping.presetId = `${manifest.id}-other`;
         mapping.layer.rgb.hex = "orange";
         mapping.layer.name = "Other";
         mapping.controls[1].id = mapping.controls[0].id;
         mapping.controls = mapping.controls.filter((control) => control.id !== "command-row-right");
-        mapping.controls.find((control) => control.id === "command-row-center-right").action = {
-          type: "shortcut",
-          keys: ["Meta", "X"],
-        };
-        mapping.controls.find((control) => control.id === "encoder-rotate").action = {};
-        mapping.controls.find((control) => control.id === "joystick").action = {};
+        control("command-row-center-right").action = { type: "shortcut", keys: ["Meta", "X"] };
+        control("encoder-rotate").action = {};
+        control("joystick").action = {};
         mapping.unusedControls = [];
       },
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/input-layer.test.mjs` around lines 247 - 254, Update the fixture setup
around the positional control access and the .find calls to validate that each
expected control exists before reading or assigning its properties. Add clear
assertions or guard failures naming the missing control IDs, including the
control currently accessed through mapping.controls[1] and the controls used by
command-row-center-right, encoder-rotate, and joystick, while preserving the
existing mutations.
tests/hid-device.test.mjs (1)

94-95: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Optional: derive the sleep from the exported spacing constant.

The 65 ms value duplicates the CALL_SPACING_MS value in scripts/lib/hid-device.mjs. Export that constant and use it here, so the intent stays clear if the firmware spacing changes.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/hid-device.test.mjs` around lines 94 - 95, Export the CALL_SPACING_MS
constant from the HID device module and update the test’s delay before the
handle.writes assertion to derive from that exported constant instead of the
duplicated 65 ms literal. Preserve the existing timing behavior and assertion.
prototype/src/components/ConfiguratorWorkspace.jsx (1)

146-147: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Add type="button" to the remaining buttons.

These buttons omit type, so the default is submit. No form wraps this markup today, so behavior is correct. Topbar already sets type="button" at line 47. Set it here too for consistency and to prevent a submit regression if a form is added later.

Also applies to: 205-205, 212-212, 222-223

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@prototype/src/components/ConfiguratorWorkspace.jsx` around lines 146 - 147,
Update the button elements in ConfiguratorWorkspace, including the one keyed by
control.id and the additional buttons at the referenced locations, to explicitly
set type="button"; match the existing Topbar convention and preserve their
current click behavior.
prototype/src/profile-workflow.js (1)

33-46: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Complete the optional chain on subtle.

crypto.subtle is undefined in an insecure context. crypto?.subtle.digest then throws a TypeError that the catch block converts to "". The outcome is the same empty hash, but the intent is clearer with crypto?.subtle?.digest. The empty string also reaches the review UI as a valid value; consider returning null so callers can distinguish "no hash available" from a computed digest.

♻️ Proposed refactor
-    const digest = await crypto?.subtle.digest(
+    const digest = await crypto?.subtle?.digest(
       "SHA-256",
       new TextEncoder().encode(text),
     );
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@prototype/src/profile-workflow.js` around lines 33 - 46, Update sha256Hex to
use optional chaining on subtle before invoking digest, preserving the existing
empty-string fallback. Do not change the return contract to null unless the
surrounding callers and review UI are explicitly updated to handle that distinct
unavailable-hash value.
prototype/src/configurator-presenter.js (1)

13-37: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use own-property lookup for catalog entries.

ACTIONS[entry] resolves inherited names such as toString and constructor. The ?? fallbacks currently absorb the result, so behavior is correct today. An own-property check makes the intent explicit and keeps the fallback path predictable if the shape changes.

♻️ Proposed refactor
+function actionFor(entry) {
+  return typeof entry === "string" && Object.hasOwn(ACTIONS, entry) ? ACTIONS[entry] : undefined;
+}
+
 export function entryExportLabel(entry) {
   if (isCustomJoystick(entry)) return `${entry.directions} DIR`;
   if (isCustom(entry)) return formatCustomKeys(entry.keys);
-  return ACTIONS[entry]?.exportLabel ?? ACTIONS.none.exportLabel;
+  return actionFor(entry)?.exportLabel ?? ACTIONS.none.exportLabel;
 }

Apply the same helper in entryIcon and entryShortcut.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@prototype/src/configurator-presenter.js` around lines 13 - 37, Add a shared
own-property lookup helper for ACTIONS catalog entries, then use it in
entryExportLabel, entryIcon, and entryShortcut instead of direct ACTIONS[entry]
access. Preserve each function’s existing fallback behavior while ensuring
inherited keys such as toString and constructor use the fallback path.
prototype/src/hooks/use-theme.js (1)

16-42: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Export an injectable saveTheme and drop the unreachable fallback.

detectTheme accepts an injected storage, but line 34 writes to window.localStorage directly. The write path is therefore not testable, unlike saveLocale in prototype/src/i18n/index.js and saveStoredState in prototype/src/configurator-state.js. At line 18 the ?? THEME_ORDER[0] branch is unreachable because indexOf returns -1 for unknown themes and (-1 + 1) % 3 is 0.

♻️ Proposed refactor
 export function nextTheme(theme) {
   const index = THEME_ORDER.indexOf(theme);
-  return THEME_ORDER[(index + 1) % THEME_ORDER.length] ?? THEME_ORDER[0];
+  return THEME_ORDER[(index + 1) % THEME_ORDER.length];
 }
+
+export function saveTheme(theme, storage) {
+  try {
+    const target = storage ?? globalThis.window?.localStorage;
+    target?.setItem(THEME_STORAGE_KEY, theme);
+  } catch {
+    // Private browsing: the preference just will not persist.
+  }
+}
@@
     apply();
-    try {
-      window.localStorage.setItem(THEME_STORAGE_KEY, theme);
-    } catch {
-      // Private browsing: the preference just will not persist.
-    }
+    saveTheme(theme);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@prototype/src/hooks/use-theme.js` around lines 16 - 42, Update nextTheme to
return the indexed theme directly without the unreachable nullish fallback, and
export an injectable saveTheme function that accepts a theme and storage
dependency and persists using that storage. Replace the direct
window.localStorage write in useTheme with saveTheme, passing
window.localStorage while preserving the existing private-browsing error
handling.
prototype/src/styles.css (1)

412-472: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Translate the remaining French comments for consistency.

This diff rewrites almost every other comment in the file to English (for example the comments at lines 63-65, 241-255, and 526-534). Two comment blocks added in this same change stay in French: the .keycap-action-asset comments at line 414 and lines 418-421, and the icon-sizing comments at lines 458-461. Translate them so the file uses one documentation language consistently.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@prototype/src/styles.css` around lines 412 - 472, Translate the remaining
French comments in the .keycap-action-asset and icon-sizing sections to English,
including the comments describing hotspot centering, disc coverage, and Claude
icon sizing; leave the CSS rules and behavior unchanged.
prototype/tests/app-render.test.mjs (1)

3-5: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Import React, react-dom/server, and Vite via public entry points.

These imports reach into internal package files instead of the documented public API. This package serves as the entry point to the DOM and server renderers for React. react-dom/server is the intended import path, not react-dom/server.node.js. The same applies to vite, whose public entry point is the vite package itself, not vite/dist/node/index.js.

Internal paths are not part of the packages' stable contract and can move or disappear on minor/patch upgrades. A relative path into node_modules also assumes dependencies are not hoisted elsewhere (e.g., a workspace root), unlike a bare specifier.

♻️ Proposed fix
-import React from "../node_modules/react/index.js";
-import { renderToString } from "../node_modules/react-dom/server.node.js";
-import { createServer } from "../node_modules/vite/dist/node/index.js";
+import React from "react";
+import { renderToString } from "react-dom/server";
+import { createServer } from "vite";
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@prototype/tests/app-render.test.mjs` around lines 3 - 5, Update the imports
in the test to use the public bare package entry points: import React from
react, renderToString from react-dom/server, and createServer from vite. Remove
the relative node_modules paths and internal react-dom/server.node.js and
vite/dist/node/index.js references.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@prototype/src/App.jsx`:
- Around line 48-53: Update loadProfileWorkflow to clear profileWorkflowPromise
when the dynamic import rejects, allowing later calls to retry the fetch. Also
update the prefetch call sites using loadProfileWorkflow so their returned
promise has an attached rejection handler, preventing unhandled rejections.

In `@prototype/src/components/JoystickDial.jsx`:
- Around line 76-90: Move the closeTitle element from the SVG root into the
.joystick-dial-close path element so the tooltip applies only to the close zone.
Keep a single title instance and preserve the existing path geometry and glyph
rendering.

In `@prototype/src/components/KeyAssignmentEditor.jsx`:
- Around line 37-40: Update duplicateControlFor so duplicate detection proceeds
when either selectedControl.type is "key" or editingJoystickSlot is true;
continue returning null for the "none" entry and preserve the existing
duplicateKeyControls lookup.

In `@prototype/src/configurator-state.js`:
- Around line 213-223: Update parseOptionalNonNegativeInteger to validate that
the trimmed input uses only decimal digit characters before converting it,
rejecting hexadecimal, exponent, binary, and other non-decimal numeric forms
with the existing INVALID_APPSENSE_ID error. Preserve the optional empty-string
behavior and acceptance of non-negative decimal integers.

In `@prototype/src/profile-panel-loader.js`:
- Around line 1-6: Update prototype/src/profile-panel-loader.js lines 1-6 to
clear profilePanelPromise when the dynamic import used by loadProfileExportPanel
rejects, allowing subsequent calls to retry; update
prototype/src/components/MappingDialog.jsx lines 106-119 to wrap the
Suspense/ProfileExportPanel rendering in an error boundary that displays a retry
or fallback message instead of crashing the dialog.

In `@scripts/configure.mjs`:
- Line 24: Translate the remaining French messages to English: update the
startup log in scripts/configure.mjs at lines 24-24, translate the assertion
message in tests/thread-slots.test.mjs at lines 113-113, and rename the
enclosing test title in tests/hid-lighting.test.mjs at lines 92-93 to describe
that slotsToThreadEntries requires exactly six rows.

In `@tests/cli.test.mjs`:
- Around line 51-64: Update the repository validation test around the script
list in the “repository validation commands run successfully from the checkout”
test so it no longer unconditionally executes scripts/prepare-gui.mjs, which may
invoke ensureGuiDependencies and npm ci. Keep assertions focused on validation
scripts that do not install dependencies, or explicitly cover both existing and
missing prototype/node_modules outcomes without requiring network access.

---

Nitpick comments:
In `@prototype/src/components/ConfiguratorWorkspace.jsx`:
- Around line 146-147: Update the button elements in ConfiguratorWorkspace,
including the one keyed by control.id and the additional buttons at the
referenced locations, to explicitly set type="button"; match the existing Topbar
convention and preserve their current click behavior.

In `@prototype/src/configurator-presenter.js`:
- Around line 13-37: Add a shared own-property lookup helper for ACTIONS catalog
entries, then use it in entryExportLabel, entryIcon, and entryShortcut instead
of direct ACTIONS[entry] access. Preserve each function’s existing fallback
behavior while ensuring inherited keys such as toString and constructor use the
fallback path.

In `@prototype/src/hooks/use-theme.js`:
- Around line 16-42: Update nextTheme to return the indexed theme directly
without the unreachable nullish fallback, and export an injectable saveTheme
function that accepts a theme and storage dependency and persists using that
storage. Replace the direct window.localStorage write in useTheme with
saveTheme, passing window.localStorage while preserving the existing
private-browsing error handling.

In `@prototype/src/profile-workflow.js`:
- Around line 33-46: Update sha256Hex to use optional chaining on subtle before
invoking digest, preserving the existing empty-string fallback. Do not change
the return contract to null unless the surrounding callers and review UI are
explicitly updated to handle that distinct unavailable-hash value.

In `@prototype/src/styles.css`:
- Around line 412-472: Translate the remaining French comments in the
.keycap-action-asset and icon-sizing sections to English, including the comments
describing hotspot centering, disc coverage, and Claude icon sizing; leave the
CSS rules and behavior unchanged.

In `@prototype/tests/app-render.test.mjs`:
- Around line 3-5: Update the imports in the test to use the public bare package
entry points: import React from react, renderToString from react-dom/server, and
createServer from vite. Remove the relative node_modules paths and internal
react-dom/server.node.js and vite/dist/node/index.js references.

In `@tests/hid-device.test.mjs`:
- Around line 94-95: Export the CALL_SPACING_MS constant from the HID device
module and update the test’s delay before the handle.writes assertion to derive
from that exported constant instead of the duplicated 65 ms literal. Preserve
the existing timing behavior and assertion.

In `@tests/input-layer.test.mjs`:
- Around line 247-254: Update the fixture setup around the positional control
access and the .find calls to validate that each expected control exists before
reading or assigning its properties. Add clear assertions or guard failures
naming the missing control IDs, including the control currently accessed through
mapping.controls[1] and the controls used by command-row-center-right,
encoder-rotate, and joystick, while preserving the existing mutations.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b06e0540-c3d2-4da4-8832-6dda48dc1517

📥 Commits

Reviewing files that changed from the base of the PR and between 53641d0 and 12f1b49.

📒 Files selected for processing (54)
  • .gitignore
  • package.json
  • prototype/package.json
  • prototype/src/App.jsx
  • prototype/src/components/ConfiguratorWorkspace.jsx
  • prototype/src/components/JoystickDial.jsx
  • prototype/src/components/KeyAssignmentEditor.jsx
  • prototype/src/components/MappingDialog.jsx
  • prototype/src/components/ProfileExportPanel.jsx
  • prototype/src/components/ProfileLoader.jsx
  • prototype/src/components/ProfileReview.jsx
  • prototype/src/configurator-catalog.jsx
  • prototype/src/configurator-presenter.js
  • prototype/src/configurator-state.js
  • prototype/src/hooks/use-theme.js
  • prototype/src/i18n/de.js
  • prototype/src/i18n/en.js
  • prototype/src/i18n/es.js
  • prototype/src/i18n/fr.js
  • prototype/src/i18n/index.js
  • prototype/src/profile-panel-loader.js
  • prototype/src/profile-session.js
  • prototype/src/profile-workflow.js
  • prototype/src/styles.css
  • prototype/tests/app-render.test.mjs
  • prototype/tests/architecture.test.mjs
  • prototype/tests/configurator-state.test.mjs
  • prototype/tests/i18n.test.mjs
  • prototype/tests/presentation.test.mjs
  • prototype/tests/profile-session.test.mjs
  • scripts/build-input-profile.mjs
  • scripts/configure.mjs
  • scripts/enable-agent-keys.mjs
  • scripts/lib/gui-dependencies.mjs
  • scripts/lib/hid-device.mjs
  • scripts/lib/hid-frame.mjs
  • scripts/lib/hid-lighting.mjs
  • scripts/lib/thread-slots.mjs
  • scripts/lighting-probe.mjs
  • scripts/lighting.mjs
  • scripts/prepare-gui.mjs
  • scripts/thread-status.mjs
  • shared/input-profile.mjs
  • shared/thread-status-palette.mjs
  • tests/cli.test.mjs
  • tests/gui-dependencies.test.mjs
  • tests/helpers/input-profile-fixture.mjs
  • tests/hid-device.test.mjs
  • tests/hid-frame.test.mjs
  • tests/hid-lighting.test.mjs
  • tests/input-layer.test.mjs
  • tests/input-profile.test.mjs
  • tests/thread-slots.test.mjs
  • thread-status/bin/emit.mjs

Comment thread prototype/src/App.jsx Outdated
Comment thread prototype/src/components/JoystickDial.jsx
Comment thread prototype/src/components/KeyAssignmentEditor.jsx
Comment thread prototype/src/configurator-state.js
Comment thread prototype/src/profile-panel-loader.js Outdated
Comment thread scripts/configure.mjs Outdated
Comment thread tests/cli.test.mjs
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Chef's kiss.

Reviewed commit: 58315318de

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

thannous commented Jul 31, 2026

Copy link
Copy Markdown
Owner Author

Review fixes are now in 41e2dde: retryable lazy imports with an export-panel error boundary, strict decimal AppSense validation, joystick duplicate detection, network-free CLI tests, and the remaining maintainability cleanups. npm run check passes (99 root tests, 32 GUI tests, production build).

@codex review
@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

@thannous, I will review the updates in commit 41e2dde, including the reported fixes and regression coverage.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

@thannous, I will review the updates in commit 41e2dde and the current changes in PR #4.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 41e2dded14

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread prototype/src/components/KeyAssignmentEditor.jsx Outdated

Copy link
Copy Markdown
Owner Author

The remaining joystick-sector duplicate warning is fixed in ae77c23 and covered by a focused SSR regression test. The full npm run check suite passes (99 root tests, 33 GUI tests, production build).

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 👍

Reviewed commit: ae77c23076

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@thannous
thannous merged commit 3a08d41 into main Jul 31, 2026
2 checks passed
@thannous
thannous deleted the codex/refactor-architecture-tests branch August 6, 2026 10:34
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