Skip to content

Support multi-character paste for headless input_otp and remove maxlength on slots#11

Open
bbopen wants to merge 2 commits intomainfrom
codex/locate-major-bug-and-audit-tests
Open

Support multi-character paste for headless input_otp and remove maxlength on slots#11
bbopen wants to merge 2 commits intomainfrom
codex/locate-major-bug-and-audit-tests

Conversation

@bbopen
Copy link
Owner

@bbopen bbopen commented Mar 6, 2026

Motivation

  • Enable slot-level on_input handlers to apply multi-character updates (paste) across subsequent OTP slots instead of only replacing the single slot.
  • Remove the hard maxlength="1" attribute from rendered slot inputs so browser-level truncation doesn't interfere with controlled multi-character handling.

Description

  • Add replace_slots_from_index/3 and input_otp_apply_slot_input/3 to compute resulting slot string when an input contains multiple graphemes and fan pasted values across following slots.
  • Replace the previous single-grapheme extraction logic in slot on_input handlers with a call to input_otp_apply_slot_input(chars, index, input) so both single-character and multi-character inputs are handled correctly.
  • Remove the maxlength="1" attribute from input_otp_slot required attributes so controlled logic can accept and distribute multi-character input.
  • Delete the now-unused helper first_grapheme_or_empty.
  • Update tests in test/input_otp_test.gleam to assert the new paste behavior and that maxlength is not present.

Testing

  • Ran the Gleam test suite via gleam test, and the updated input_otp tests covering headless mutators, rendering, and multi-character paste behavior passed.

Codex Task

@coderabbitai
Copy link

coderabbitai bot commented Mar 6, 2026

📝 Walkthrough

Walkthrough

Refactors OTP input to support multi-character pastes distributed across slots via a new public input_otp_apply_slot_input; removes per-slot grapheme helper and maxlength attribute; adds tests for paste behavior; and introduces a retry helper used in CI/workflow for Gleam dependency downloads.

Changes

Cohort / File(s) Summary
OTP Input Implementation
src/weft_lustre_ui/headless/input_otp.gleam
Added public input_otp_apply_slot_input to apply single- or multi-character input across slots; added internal replace_slots_from_index; refactored on_input handlers to use new flow; removed first_grapheme_or_empty and the maxlength attribute from slot rendering.
Tests
test/input_otp_test.gleam
Added test asserting multi-slot paste distribution (input_otp_apply_slot_input) and updated headless rendering test to assert maxlength="1" is not present.
CI / Scripts
.github/workflows/test.yml, scripts/check.sh, scripts/ci/retry.sh
Replaced direct gleam deps download with a retry wrapper invocation in workflow and check script; added scripts/ci/retry.sh which runs a command with configurable attempts and sleep between retries.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐇 I nibble keys and spread the paste,
Across each slot in tidy haste,
No maxlength to hold me tight,
Tests cheer on the new delight,
CI retries keep builds in sight.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main changes: supporting multi-character paste for OTP input and removing the maxlength attribute from slots.
Description check ✅ Passed The description provides clear context on motivation, implementation details, and testing, directly relating to the changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch codex/locate-major-bug-and-audit-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 and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@scripts/ci/retry.sh`:
- Around line 27-38: The retry loop in retry.sh currently always exits 1 on
exhaustion, losing the wrapped command’s real exit code; modify the loop to
capture the wrapped command’s exit status (e.g., save "$?" into a variable like
last_rc each time the command fails) and after the loop ends use exit $last_rc
instead of exit 1 so callers see the original command’s failure code; keep the
existing success path (exit 0) and sleep behavior using the existing variables
(command, attempt, attempts, sleep_seconds).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: f14aaf74-92ab-4ab0-b7e5-21a441bc3d52

📥 Commits

Reviewing files that changed from the base of the PR and between be2fc8e and 0b9fce9.

📒 Files selected for processing (3)
  • .github/workflows/test.yml
  • scripts/check.sh
  • scripts/ci/retry.sh
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: claude-review
🔇 Additional comments (3)
scripts/ci/retry.sh (1)

5-23: Good guardrails on the retry contract.

The arity and integer validation here will fail fast on misconfigured CI calls instead of producing harder-to-debug shell errors later.

.github/workflows/test.yml (1)

63-65: Nice CI hardening at the network boundary.

Retrying gleam deps download here should reduce transient Hex/download failures without broadening retries to the rest of the job.

scripts/check.sh (1)

9-9: Good resilience improvement for the shared check path.

Wrapping dependency download here hardens the most failure-prone external call before the rest of the checks execute.

Comment on lines +27 to +38
for attempt in $(seq 1 "$attempts"); do
echo "Attempt ${attempt}/${attempts}: ${command[*]}" >&2
if "${command[@]}"; then
exit 0
fi

if [ "$attempt" -lt "$attempts" ]; then
sleep "$sleep_seconds"
fi
done

exit 1
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Preserve the wrapped command’s final exit code.

After the last failed attempt this always exits 1, so the original failure mode is lost. That makes CI diagnostics worse and prevents callers from distinguishing retry exhaustion from command-specific failures.

💡 Proposed fix
+status=0
 for attempt in $(seq 1 "$attempts"); do
   echo "Attempt ${attempt}/${attempts}: ${command[*]}" >&2
   if "${command[@]}"; then
     exit 0
+  else
+    status=$?
   fi
 
   if [ "$attempt" -lt "$attempts" ]; then
     sleep "$sleep_seconds"
   fi
 done
 
-exit 1
+exit "$status"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
for attempt in $(seq 1 "$attempts"); do
echo "Attempt ${attempt}/${attempts}: ${command[*]}" >&2
if "${command[@]}"; then
exit 0
fi
if [ "$attempt" -lt "$attempts" ]; then
sleep "$sleep_seconds"
fi
done
exit 1
status=0
for attempt in $(seq 1 "$attempts"); do
echo "Attempt ${attempt}/${attempts}: ${command[*]}" >&2
if "${command[@]}"; then
exit 0
else
status=$?
fi
if [ "$attempt" -lt "$attempts" ]; then
sleep "$sleep_seconds"
fi
done
exit "$status"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/ci/retry.sh` around lines 27 - 38, The retry loop in retry.sh
currently always exits 1 on exhaustion, losing the wrapped command’s real exit
code; modify the loop to capture the wrapped command’s exit status (e.g., save
"$?" into a variable like last_rc each time the command fails) and after the
loop ends use exit $last_rc instead of exit 1 so callers see the original
command’s failure code; keep the existing success path (exit 0) and sleep
behavior using the existing variables (command, attempt, attempts,
sleep_seconds).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant