Skip to content

fix: split env parsing into app/env.ts#151

Merged
mcansh merged 2 commits into
copilot/add-keyboard-buttons-and-cheat-functionalityfrom
copilot/debug-env-parsing-issue
Apr 23, 2026
Merged

fix: split env parsing into app/env.ts#151
mcansh merged 2 commits into
copilot/add-keyboard-buttons-and-cheat-functionalityfrom
copilot/debug-env-parsing-issue

Conversation

@mcansh
Copy link
Copy Markdown
Owner

@mcansh mcansh commented Apr 23, 2026

Summary by CodeRabbit

  • New Features

    • Secret cheat activation: Enter the c-h-e-a-t sequence within 2 seconds to reveal the word. Cheat state persists within the session.
  • Improvements

    • Keyboard buttons now interactive with improved accessibility labels for screen readers.

Agent-Logs-Url: https://github.com/mcansh/remix-wordle/sessions/841a4215-24bd-4908-9c77-51c5cfeab87e

Co-authored-by: mcansh <11698668+mcansh@users.noreply.github.com>
Copilot AI review requested due to automatic review settings April 23, 2026 00:41
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Apr 23, 2026

⚠️ No Changeset found

Latest commit: d05310f

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 23, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 3dcd8934-a532-44a2-ae5c-fa69f6740ff2

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

This PR adds client-side cheat activation via keyboard sequence detection (c-h-e-a-t within a 2-second window), refactors keyboard UI to semantic buttons with accessibility improvements, and reorganizes environment variable validation from constants.ts into a dedicated app/env.ts module. Session-based cheat state storage replaces URL parameter-based handling.

Changes

Cohort / File(s) Summary
Cheat Activation Feature
app/components/form.tsx, app/components/form.test.tsx
Adds keystroke buffering to detect the "cheat" sequence within a 2-second window; on match, enables cheat state, persists to sessionStorage via CHEAT_SESSION_KEY, and invokes handle.update() if provided. Tests mock timers and validate both successful and timeout scenarios.
Keyboard Component Accessibility
app/components/keyboard.tsx, app/components/keyboard.test.tsx
Converts keyboard letter cells from non-interactive <div> to semantic <button type="button"> elements with aria-label for accessibility. New test suite validates button rendering and accessible naming.
Environment Validation Refactoring
app/constants.ts, app/env.ts
Moves environment schema validation (SESSION_SECRET, DATABASE_URL, REDIS_URL, NODE_ENV) from constants.ts to new app/env.ts module. Adds CHEAT_SESSION_KEY constant ("wordle-cheat-enabled") to constants.
Session-Based Cheat State
app/controllers/home/controller.tsx
Replaces URL parameter-based cheat detection with session-based lookup using CHEAT_SESSION_KEY; stores cheat intent in session on form submission instead of query parameters.
Import Path Updates
app/utils/db.ts, app/utils/queue.ts, app/utils/session.ts
Updates env import source from #app/constants.ts to #app/env.ts across three utility modules; no logic changes.

Sequence Diagram

sequenceDiagram
    participant User
    participant FormComponent as Form Component
    participant SessionStorage
    participant Handle

    User->>FormComponent: Type keystroke
    FormComponent->>FormComponent: Buffer keystroke (2s window)
    alt Sequence matches "cheat"
        FormComponent->>FormComponent: Enable cheatEnabled state
        FormComponent->>SessionStorage: Set CHEAT_SESSION_KEY to "true"
        alt handle provided & cheat was previously false
            FormComponent->>Handle: Call handle.update()
        end
    else Sequence timeout or mismatch
        FormComponent->>FormComponent: Reset buffer, no action
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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 accurately describes the primary change: moving environment variable parsing logic from app/constants.ts to a new app/env.ts file.
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.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch copilot/debug-env-parsing-issue

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.

@railway-app
Copy link
Copy Markdown

railway-app Bot commented Apr 23, 2026

🚅 Deployed to the remix-wordle-pr-151 environment in remix-wordle

Service Status Web Updated (UTC)
remix-wordle 🕗 Deploying (View Logs) Web Apr 23, 2026 at 1:07 am

@railway-app railway-app Bot temporarily deployed to remix-wordle / remix-wordle-pr-151 April 23, 2026 00:41 Destroyed
Copy link
Copy Markdown
Contributor

@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: 6

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

Inline comments:
In `@app/components/form.test.tsx`:
- Line 3: Replace the direct vitest imports with the repo-approved test wrapper
by changing the import source for the test utilities (afterEach, beforeEach,
describe, it, expect, vi) to "vite-plus/test" so all Vitest APIs are imported
via the centralized wrapper; update the import statement that currently imports
from "vitest" to import the same symbols from "vite-plus/test".

In `@app/components/form.tsx`:
- Around line 104-111: cheatEnabled is local and setting it won't re-render the
component unless handle.update() is always invoked; make the handle prop
required on GuessForm, update Page to pass its handle (rename _handle to handle)
into <GuessForm>, and remove the conditional so that handle.update() is called
unconditionally when enabling cheat (still write CHEAT_SESSION_KEY to
sessionStorage); also update GuessForm's prop types/signature to require handle
so the hidden input name="cheat" is rendered after activation.

In `@app/components/keyboard.test.tsx`:
- Line 3: Replace the direct import from "vitest" in keyboard.test.tsx with the
project test wrapper: update the import statement that currently references the
symbols describe, expect, it from "vitest" to instead import those same symbols
from "vite-plus/test" so the file uses the project's test utilities (locate the
import line at the top of the file and swap the module source).

In `@app/components/keyboard.tsx`:
- Around line 18-26: The keyboard buttons in app/components/keyboard.tsx render
as focusable <button>s but have no action; either make them
non-interactive/presentational or wire them to the same input handler: update
the element rendering inside the keyboard map (the element using letter.letter
and data-state) to either render a non-focusable element (e.g., span/div with
role="presentation" and no tabIndex) if you want passive display, or attach the
existing letter-entry handler (e.g., call insertLetter or onKeyPress equivalent)
to onClick and onKeyDown on the button, ensure it calls the same function used
for physical keyboard input, and keep accessible labels (aria-label) and
appropriate keyboard handling (Enter/Space) so the component remains accessible
and functional.

In `@app/controllers/home/controller.tsx`:
- Around line 68-70: Current logic only sets CHEAT_SESSION_KEY via
session.set(CHEAT_SESSION_KEY, true) when data.value.cheat is truthy, so the
server session never clears the flag when the client removes it; add server-side
handling to clear the flag as well: in the same request handler (the function
containing session.set and references to data.value.cheat) detect when
data.value.cheat is falsey and remove the key (e.g., session.delete or
session.unset/CHEAT_SESSION_KEY removal API) or explicitly set it to false, then
persist the session (commit/save) so the server-side session mirrors the client;
alternatively, add a dedicated server endpoint (e.g., /clear-cheat) that deletes
CHEAT_SESSION_KEY from the session and commits the session so the revealed
answer is no longer stored server-side.

In `@app/utils/db.ts`:
- Line 7: Replace the direct process.env usage with the validated value from
your env module: import the validated env export from app/env.ts and pass
env.DATABASE_URL into the PrismaPg constructor (replace the current
connectionString: process.env.DATABASE_URL). Update the file where adapter is
created (the PrismaPg instantiation) to reference env.DATABASE_URL so Prisma
uses the typed/validated config.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 8813aba2-c928-46e0-8dda-5288a8dad446

📥 Commits

Reviewing files that changed from the base of the PR and between 6d7206c and 62cd5e4.

📒 Files selected for processing (10)
  • app/components/form.test.tsx
  • app/components/form.tsx
  • app/components/keyboard.test.tsx
  • app/components/keyboard.tsx
  • app/constants.ts
  • app/controllers/home/controller.tsx
  • app/env.ts
  • app/utils/db.ts
  • app/utils/queue.ts
  • app/utils/session.ts

import { render, screen } from "@mcansh/remix-testing-library"
import { describe, it, expect, vi } from "vitest"
import { fireEvent, render, screen } from "@mcansh/remix-testing-library"
import { afterEach, beforeEach, describe, it, expect, vi } from "vitest"
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.

🛠️ Refactor suggestion | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
rg -nP 'from\s+["'\''](?:vite|vitest)["'\'']' -g '*.{js,jsx,ts,tsx}'

Repository: mcansh/remix-wordle

Length of output: 467


Import test utilities from vite-plus/test instead of vitest.

Line 3 imports directly from vitest, which violates the repository convention. Per coding guidelines, all **/*.{js,jsx,ts,tsx} files must import Vitest APIs from vite-plus/test.

Proposed fix
-import { afterEach, beforeEach, describe, it, expect, vi } from "vitest"
+import { afterEach, beforeEach, describe, it, expect, vi } from "vite-plus/test"
📝 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
import { afterEach, beforeEach, describe, it, expect, vi } from "vitest"
import { afterEach, beforeEach, describe, it, expect, vi } from "vite-plus/test"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/components/form.test.tsx` at line 3, Replace the direct vitest imports
with the repo-approved test wrapper by changing the import source for the test
utilities (afterEach, beforeEach, describe, it, expect, vi) to "vite-plus/test"
so all Vitest APIs are imported via the centralized wrapper; update the import
statement that currently imports from "vitest" to import the same symbols from
"vite-plus/test".

Comment thread app/components/form.tsx
Comment on lines +104 to +111
if (!cheatEnabled) {
cheatEnabled = true
if (typeof window !== "undefined") {
window.sessionStorage.setItem(CHEAT_SESSION_KEY, "true")
}
if (handle) {
await handle.update()
}
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.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
rg -nP -C3 '<GuessForm\b|GuessForm\s*\(' -g '*.{js,jsx,ts,tsx}'

Repository: mcansh/remix-wordle

Length of output: 5673


🏁 Script executed:

cat -n app/controllers/home/page.tsx | head -60

Repository: mcansh/remix-wordle

Length of output: 2709


🏁 Script executed:

sed -n '100,130p' app/components/form.tsx

Repository: mcansh/remix-wordle

Length of output: 702


🏁 Script executed:

rg -n "type Handle|interface Handle" -A5 --max-count=5

Repository: mcansh/remix-wordle

Length of output: 45


🏁 Script executed:

sed -n '1,100p' app/components/form.tsx

Repository: mcansh/remix-wordle

Length of output: 2659


🏁 Script executed:

rg "Handle" app/controllers/home/page.tsx -A2

Repository: mcansh/remix-wordle

Length of output: 255


🏁 Script executed:

rg "handle\.update|Handle.*update" -A2 -B2

Repository: mcansh/remix-wordle

Length of output: 1123


🏁 Script executed:

cat -n app/components/form.tsx | grep -A 5 "key=.*current-guess"

Repository: mcansh/remix-wordle

Length of output: 257


Cheat activation will not trigger a render without passing the handle.

cheatEnabled is closure-local state; setting it on line 106 alone does not trigger a re-render. The hidden input on line 117 depends on cheatEnabled being true, but the component will not re-render unless handle.update() is called. However, the production caller at app/controllers/home/page.tsx:48 renders <GuessForm> without passing the handle parameter, so handle.update() is never executed. The form will submit without name="cheat" even after the cheat code is typed.

The _handle parameter in Page (line 10 of home/page.tsx) is intentionally unused (underscore prefix convention), indicating this limitation was deliberate. To fix this, the handle must be passed from Page to GuessForm, the optional parameter must become required, and the conditional call to handle.update() must be unconditional.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/components/form.tsx` around lines 104 - 111, cheatEnabled is local and
setting it won't re-render the component unless handle.update() is always
invoked; make the handle prop required on GuessForm, update Page to pass its
handle (rename _handle to handle) into <GuessForm>, and remove the conditional
so that handle.update() is called unconditionally when enabling cheat (still
write CHEAT_SESSION_KEY to sessionStorage); also update GuessForm's prop
types/signature to require handle so the hidden input name="cheat" is rendered
after activation.

@@ -0,0 +1,31 @@
import "@testing-library/jest-dom/vitest"
import { render, screen } from "@mcansh/remix-testing-library"
import { describe, expect, it } from "vitest"
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.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# Check if the file exists and read the import statement
cat -n app/components/keyboard.test.tsx | head -10

Repository: mcansh/remix-wordle

Length of output: 457


🏁 Script executed:

# Check vite configuration and package.json to confirm vite-plus usage
head -30 vite.config.ts package.json 2>/dev/null || echo "Files not found at root"

Repository: mcansh/remix-wordle

Length of output: 1576


🏁 Script executed:

# Look for vite-plus configuration or any imports from vite-plus in the project
rg "from ['\"]vite-plus" --type ts --type tsx -A 2 | head -20

Repository: mcansh/remix-wordle

Length of output: 90


🏁 Script executed:

# Find other test files and check their imports
fd "\.test\.(ts|tsx|js|jsx)$" --exec head -10 {} \; | head -50

Repository: mcansh/remix-wordle

Length of output: 1713


🏁 Script executed:

# Search for vite-plus/test imports specifically
rg "from.*vite-plus/test" --type ts --type jsx -A 1

Repository: mcansh/remix-wordle

Length of output: 90


Use the project test wrapper instead of importing from vitest directly.

As per coding guidelines, **/*.{js,jsx,ts,tsx} must import test utilities from vite-plus/test instead of directly from vitest.

🧪 Proposed import fix
-import { describe, expect, it } from "vitest"
+import { describe, expect, it } from "vite-plus/test"
📝 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
import { describe, expect, it } from "vitest"
import { describe, expect, it } from "vite-plus/test"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/components/keyboard.test.tsx` at line 3, Replace the direct import from
"vitest" in keyboard.test.tsx with the project test wrapper: update the import
statement that currently references the symbols describe, expect, it from
"vitest" to instead import those same symbols from "vite-plus/test" so the file
uses the project's test utilities (locate the import line at the top of the file
and swap the module source).

Comment on lines +18 to +26
<button
type="button"
data-state={letter.state}
class={`flex size-10 items-center justify-center rounded text-center text-white uppercase data-[state=Blank]:bg-gray-400 data-[state=Match]:bg-green-500 data-[state=Miss]:bg-red-500 data-[state=Present]:bg-yellow-500`}
key={`keyboard-letter-${letter.letter}`}
aria-label={`keyboard letter ${letter.letter}`}
>
{letter.letter}
</div>
</button>
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.

⚠️ Potential issue | 🟡 Minor

Avoid rendering no-op buttons.

These controls are now focusable buttons, but they do not perform an action. Either wire them to the same letter-entry behavior as the physical keyboard or keep the keyboard cells non-interactive/presentational.

♿ Possible direction if these should be clickable
-									<button
+									<button
 										type="button"
+										onClick={() => onLetter(letter.letter)}
 										data-state={letter.state}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/components/keyboard.tsx` around lines 18 - 26, The keyboard buttons in
app/components/keyboard.tsx render as focusable <button>s but have no action;
either make them non-interactive/presentational or wire them to the same input
handler: update the element rendering inside the keyboard map (the element using
letter.letter and data-state) to either render a non-focusable element (e.g.,
span/div with role="presentation" and no tabIndex) if you want passive display,
or attach the existing letter-entry handler (e.g., call insertLetter or
onKeyPress equivalent) to onClick and onKeyDown on the button, ensure it calls
the same function used for physical keyboard input, and keep accessible labels
(aria-label) and appropriate keyboard handling (Enter/Space) so the component
remains accessible and functional.

Comment on lines +68 to +70
if (data.value.cheat) {
session.set(CHEAT_SESSION_KEY, true)
}
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.

⚠️ Potential issue | 🟠 Major

Add a server-side path to clear the cheat flag.

Once Line 69 sets CHEAT_SESSION_KEY, Line 88 reveals the word for the rest of the server session. If the client can clear/expire the cheat state, the server session should mirror that; otherwise the answer stays revealed even after the client-side flag is gone.

🎯 Possible fix if the form always submits the current cheat state
-			if (data.value.cheat) {
-				session.set(CHEAT_SESSION_KEY, true)
-			}
+			if (data.value.cheat) {
+				session.set(CHEAT_SESSION_KEY, true)
+			} else {
+				session.unset(CHEAT_SESSION_KEY)
+			}

Also applies to: 88-88

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/controllers/home/controller.tsx` around lines 68 - 70, Current logic only
sets CHEAT_SESSION_KEY via session.set(CHEAT_SESSION_KEY, true) when
data.value.cheat is truthy, so the server session never clears the flag when the
client removes it; add server-side handling to clear the flag as well: in the
same request handler (the function containing session.set and references to
data.value.cheat) detect when data.value.cheat is falsey and remove the key
(e.g., session.delete or session.unset/CHEAT_SESSION_KEY removal API) or
explicitly set it to false, then persist the session (commit/save) so the
server-side session mirrors the client; alternatively, add a dedicated server
endpoint (e.g., /clear-cheat) that deletes CHEAT_SESSION_KEY from the session
and commits the session so the revealed answer is no longer stored server-side.

Comment thread app/utils/db.ts Outdated
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR refactors environment-variable parsing into a dedicated app/env.ts module and updates server utilities to consume it, while also introducing a new “cheat” persistence mechanism (session + sessionStorage) and adjusting UI/test behavior around cheating and the on-screen keyboard.

Changes:

  • Move env schema/validation out of app/constants.ts into new app/env.ts, updating imports across server utilities.
  • Change cheat behavior from a query-param-based reveal to a session-based flag, and add client-side “type cheat quickly” detection with persistence in sessionStorage.
  • Update the keyboard UI to render letters as buttons and add/adjust component tests accordingly.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
app/utils/session.ts Updates env import to use the new app/env.ts.
app/utils/queue.ts Updates env import to use the new app/env.ts.
app/utils/db.ts Updates env import to use the new app/env.ts (but still uses process.env.DATABASE_URL for Prisma adapter).
app/env.ts New centralized env schema and parsing.
app/controllers/home/controller.tsx Switches cheat reveal from query param to session flag; adjusts redirect and reveal logic.
app/constants.ts Removes env parsing and adds CHEAT_SESSION_KEY constant (leaves REVEAL_WORD behind).
app/components/keyboard.tsx Renders keyboard letters as <button> with aria-label.
app/components/keyboard.test.tsx Adds coverage verifying keyboard letters render as buttons.
app/components/form.tsx Adds cheat-code key sequence detection + sessionStorage persistence and hidden input toggle.
app/components/form.test.tsx Adds tests for cheat sequence timing and sessionStorage behavior.
Comments suppressed due to low confidence (1)

app/utils/db.ts:8

  • Now that env parsing has been centralized, this module still uses process.env.DATABASE_URL when constructing the Prisma adapter. Using env.DATABASE_URL here keeps validation/typing consistent and avoids bypassing the schema (and any future transforms/defaults).
import { env } from "#app/env.ts"
import { PrismaClient } from "#app/generated/prisma/client.ts"

const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL })
export const db = new PrismaClient({ adapter })

Comment on lines +130 to +133
let cheatInput = await screen.findByDisplayValue("true")
expect(cheatInput).toHaveAttribute("name", "cheat")
expect(window.sessionStorage.getItem("wordle-cheat-enabled")).toBe("true")
})
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

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

This test hard-codes the sessionStorage key string ("wordle-cheat-enabled") instead of importing/using CHEAT_SESSION_KEY. Using the shared constant avoids test drift if the key changes.

Copilot uses AI. Check for mistakes.
Comment on lines +68 to +72
if (data.value.cheat) {
session.set(CHEAT_SESSION_KEY, true)
}

return redirect(routes.home.index.href())
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

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

The PR title indicates this is only an env parsing refactor, but this diff also changes cheat behavior (query param -> session/sessionStorage) and UI semantics (keyboard keys become buttons) with new tests. Please update the PR title/description to reflect the broader scope, or split these functional changes into a separate PR to keep review/rollback risk contained.

Copilot uses AI. Check for mistakes.
Comment thread app/constants.ts
export const WORD_LENGTH = 5
export const LETTER_INPUTS = [...Array(WORD_LENGTH).keys()]
export const TOTAL_GUESSES = 6
export const REVEAL_WORD = "cheat"
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

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

REVEAL_WORD appears to be unused after switching cheat handling away from the query param (no other references in the app). Keeping an unused constant (and another separate CHEAT_CODE string elsewhere) makes the cheat behavior harder to follow—consider removing REVEAL_WORD or reusing it as the single source of truth for the cheat token.

Suggested change
export const REVEAL_WORD = "cheat"

Copilot uses AI. Check for mistakes.
Comment on lines +18 to +26
<button
type="button"
data-state={letter.state}
class={`flex size-10 items-center justify-center rounded text-center text-white uppercase data-[state=Blank]:bg-gray-400 data-[state=Match]:bg-green-500 data-[state=Miss]:bg-red-500 data-[state=Present]:bg-yellow-500`}
key={`keyboard-letter-${letter.letter}`}
aria-label={`keyboard letter ${letter.letter}`}
>
{letter.letter}
</div>
</button>
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

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

The keyboard letters are now rendered as <button> elements, but they have no click/press handler, so users can tab to “buttons” that do nothing. If the keyboard is meant to be non-interactive status, consider switching back to a non-control element (or mark the buttons disabled); if it is meant to be interactive, wire up a press/click behavior.

Copilot uses AI. Check for mistakes.
@mcansh mcansh changed the base branch from main to copilot/add-keyboard-buttons-and-cheat-functionality April 23, 2026 00:50
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@railway-app railway-app Bot temporarily deployed to remix-wordle / remix-wordle-pr-151 April 23, 2026 01:06 Destroyed
@mcansh mcansh merged commit 267af85 into copilot/add-keyboard-buttons-and-cheat-functionality Apr 23, 2026
3 of 6 checks passed
mcansh added a commit that referenced this pull request Apr 23, 2026
* Split env parsing into app/env.ts

Agent-Logs-Url: https://github.com/mcansh/remix-wordle/sessions/841a4215-24bd-4908-9c77-51c5cfeab87e

Co-authored-by: mcansh <11698668+mcansh@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
(cherry picked from commit 267af85)
Copilot stopped work on behalf of mcansh due to an error April 23, 2026 01:41
@coderabbitai coderabbitai Bot mentioned this pull request Apr 23, 2026
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.

3 participants