Remember cursor position in prompts #462

Merged
LunarTides merged 3 commits from cursor into main 2026-01-28 14:59:05 +00:00
LunarTides commented 2026-01-28 11:02:32 +00:00 (Migrated from github.com)

Not implemented for the class creator / packager

Closes #461

Summary by CodeRabbit

  • New Features

    • Expanded developer mode with "Start Packager", "Test Cards", "Crash Test", and "Generate Vanilla Cards".
    • New unified selection UI for interactive menus across the app.
  • Improvements

    • Selection prompts now remember cursor/default positions for smoother navigation.
    • Search persistence retained during deck creation for faster workflows.
    • Import/export and packager flows refined with clearer action labels and improved defaulting.
  • Chores

    • Updated prompt library version.

✏️ Tip: You can customize this high-level summary in your review settings.

Not implemented for the class creator / packager Closes #461 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Expanded developer mode with "Start Packager", "Test Cards", "Crash Test", and "Generate Vanilla Cards". * New unified selection UI for interactive menus across the app. * **Improvements** * Selection prompts now remember cursor/default positions for smoother navigation. * Search persistence retained during deck creation for faster workflows. * Import/export and packager flows refined with clearer action labels and improved defaulting. * **Chores** * Updated prompt library version. <sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub> <!-- end of auto-generated comment: release notes by coderabbit.ai -->
coderabbitai[bot] commented 2026-01-28 11:02:44 +00:00 (Migrated from github.com)
📝 Walkthrough

Walkthrough

Migrates interactive menus from inquirer select to game.prompt.customSelect across hub and tooling, adds persistent cursor state (selectValues) to retain selections, updates developer-mode options, and bumps @inquirer/prompts to ^8.2.0.

Changes

Cohort / File(s) Summary
Prompt System Core
src/functions/interact.ts
Added selectValues state to persist cursor positions; extended game.prompt.customSelect options with resetCursor?: boolean and default?: unknown; updated default/reset and post-selection storage logic.
Main Hub / Entry
hub.ts
Replaced select usage with game.prompt.customSelect; mapped option handling to label-based results; expanded developer mode with “Start Packager”, “Test Cards”, “Crash Test”, “Generate Vanilla Cards”; removed old select import.
Card/Class Creator
tools/cardcreator/class.ts
Switched interactive menu from inquirer select to customSelect; removed explicit Separator usage and reworked choice handling to label/default mapping.
Deck Creator
tools/deckcreator.ts
Added searchPrompt and lastPickedOption to preserve prior search/selection across prompts; wired defaults into selection flow.
Packager
tools/packager.ts
Migrated import/export/configure metadata flows to customSelect; renamed some prompts ("Choose a Pack" → “Import a Pack” / “Export a Pack”); added menu states (Refresh/New/Done) and updated license handling with default/other flow.
Project Manifest
package.json
Bumped @inquirer/prompts from ^8.0.2 to ^8.2.0.

Sequence Diagram(s)

sequenceDiagram
  participant User as "User"
  participant Hub as "hub.ts"
  participant Prompt as "game.prompt.customSelect"
  participant Interact as "src/functions/interact.ts (selectValues)"
  participant Tool as "tool (packager/cardcreator/deckcreator)"

  User->>Hub: invoke action (Play/Create/Dev)
  Hub->>Prompt: show customSelect(menu, default/reset)
  Prompt->>Interact: read default from selectValues
  Interact-->>Prompt: return default position
  Prompt->>User: render choices, receive selection
  Prompt->>Interact: store selection into selectValues
  Prompt->>Tool: return selected label/value
  Tool-->>Hub: perform selected task (create/import/test)
  Hub->>User: show next menu/result

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • LunarTides/Hearthstone.js#438: Implements the same migration to game.prompt.customSelect and touches hub.ts, interact.ts, and related prompt flows.

Poem

🐰 I hopped through prompts where cursors would flee,

Now I remember the place you left me! 🥕
From hub to packager, choices stay true,
A rabbit's small cheer for a smoother menu.

🚥 Pre-merge checks | 3 | 2
Failed checks (2 warnings)
Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning While the PR focuses on cursor position memory, it also includes a significant migration from inquirer select to customSelect across multiple files (hub.ts, packager.ts, class.ts, deckcreator.ts), which extends beyond the stated scope of issue #461. Clarify whether the customSelect migration is a prerequisite for cursor position memory or a separate refactoring effort; consider separating concerns if they are independent changes.
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 (3 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 main objective of the PR: implementing cursor position memory in prompts across the codebase.
Linked Issues check Passed The PR successfully addresses issue #461 by introducing cursor position tracking via the selectValues mechanism in interact.ts and applying it throughout the modified prompts.

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

Finishing touches
  • 📝 Generate docstrings

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.

<!-- This is an auto-generated comment: summarize by coderabbit.ai --> <!-- walkthrough_start --> <details> <summary>📝 Walkthrough</summary> ## Walkthrough Migrates interactive menus from inquirer `select` to `game.prompt.customSelect` across hub and tooling, adds persistent cursor state (`selectValues`) to retain selections, updates developer-mode options, and bumps `@inquirer/prompts` to ^8.2.0. ## Changes | Cohort / File(s) | Summary | |---|---| | **Prompt System Core** <br> `src/functions/interact.ts` | Added `selectValues` state to persist cursor positions; extended `game.prompt.customSelect` options with `resetCursor?: boolean` and `default?: unknown`; updated default/reset and post-selection storage logic. | | **Main Hub / Entry** <br> `hub.ts` | Replaced `select` usage with `game.prompt.customSelect`; mapped option handling to label-based results; expanded developer mode with “Start Packager”, “Test Cards”, “Crash Test”, “Generate Vanilla Cards”; removed old select import. | | **Card/Class Creator** <br> `tools/cardcreator/class.ts` | Switched interactive menu from inquirer `select` to `customSelect`; removed explicit `Separator` usage and reworked choice handling to label/default mapping. | | **Deck Creator** <br> `tools/deckcreator.ts` | Added `searchPrompt` and `lastPickedOption` to preserve prior search/selection across prompts; wired defaults into selection flow. | | **Packager** <br> `tools/packager.ts` | Migrated import/export/configure metadata flows to `customSelect`; renamed some prompts ("Choose a Pack" → “Import a Pack” / “Export a Pack”); added menu states (Refresh/New/Done) and updated license handling with default/other flow. | | **Project Manifest** <br> `package.json` | Bumped `@inquirer/prompts` from `^8.0.2` to `^8.2.0`. | ## Sequence Diagram(s) ```mermaid sequenceDiagram participant User as "User" participant Hub as "hub.ts" participant Prompt as "game.prompt.customSelect" participant Interact as "src/functions/interact.ts (selectValues)" participant Tool as "tool (packager/cardcreator/deckcreator)" User->>Hub: invoke action (Play/Create/Dev) Hub->>Prompt: show customSelect(menu, default/reset) Prompt->>Interact: read default from selectValues Interact-->>Prompt: return default position Prompt->>User: render choices, receive selection Prompt->>Interact: store selection into selectValues Prompt->>Tool: return selected label/value Tool-->>Hub: perform selected task (create/import/test) Hub->>User: show next menu/result ``` ## Estimated code review effort 🎯 4 (Complex) | ⏱️ ~45 minutes ## Possibly related PRs - LunarTides/Hearthstone.js#438: Implements the same migration to `game.prompt.customSelect` and touches `hub.ts`, `interact.ts`, and related prompt flows. ## Poem > 🐰 I hopped through prompts where cursors would flee, > > Now I remember the place you left me! 🥕 > > From hub to packager, choices stay true, > > A rabbit's small cheer for a smoother menu. </details> <!-- walkthrough_end --> <!-- pre_merge_checks_walkthrough_start --> <details> <summary>🚥 Pre-merge checks | ✅ 3 | ❌ 2</summary> <details> <summary>❌ Failed checks (2 warnings)</summary> | Check name | Status | Explanation | Resolution | | :------------------------: | :--------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Out of Scope Changes check | ⚠️ Warning | While the PR focuses on cursor position memory, it also includes a significant migration from inquirer select to customSelect across multiple files (hub.ts, packager.ts, class.ts, deckcreator.ts), which extends beyond the stated scope of issue `#461`. | Clarify whether the customSelect migration is a prerequisite for cursor position memory or a separate refactoring effort; consider separating concerns if they are independent changes. | | 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. | </details> <details> <summary>✅ Passed checks (3 passed)</summary> | Check name | Status | Explanation | | :-----------------: | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | Description Check | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled. | | Title check | ✅ Passed | The title accurately describes the main objective of the PR: implementing cursor position memory in prompts across the codebase. | | Linked Issues check | ✅ Passed | The PR successfully addresses issue `#461` by introducing cursor position tracking via the selectValues mechanism in interact.ts and applying it throughout the modified prompts. | </details> <sub>✏️ Tip: You can configure your own custom pre-merge checks in the settings.</sub> </details> <!-- pre_merge_checks_walkthrough_end --> <!-- finishing_touch_checkbox_start --> <details> <summary>✨ Finishing touches</summary> - [ ] <!-- {"checkboxId": "7962f53c-55bc-4827-bfbf-6a18da830691"} --> 📝 Generate docstrings </details> <!-- finishing_touch_checkbox_end --> <!-- tips_start --> --- Thanks for using [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=LunarTides/Hearthstone.js&utm_content=462)! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. <details> <summary>❤️ Share</summary> - [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai) - [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai) - [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai) - [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code) </details> <sub>Comment `@coderabbitai help` to get the list of available commands and usage tips.</sub> <!-- tips_end --> <!-- internal state start --> <!-- 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 --> <!-- internal state end -->
coderabbitai[bot] (Migrated from github.com) reviewed 2026-01-28 13:53:48 +00:00
coderabbitai[bot] (Migrated from github.com) left a comment

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@src/functions/interact.ts`:
- Around line 167-183: The code stores whole choice objects (like a Separator)
into selectValues[message], which later gets passed as the default to select()
and fails because select expects a choice value string. Update the logic around
selectValues to always store the choice value string: when handling
Back/Done/Cancel, find the first selectable choice from choices or otherChoices
(skip Separator/objects without a value) and set selectValues[message] to that
choice.value (or its equivalent string); when storing the user's answer keep the
string value. Also validate the computed default before passing it to select()
by checking that it exists in the current choices' value list and fall back to
undefined if it does not.

In `@tools/packager.ts`:
- Around line 505-545: The license menu passes metadata.license directly as the
default to game.prompt.customSelect which breaks when metadata.license contains
a custom string; before calling customSelect, compute a defaultLicense that maps
to "other" if metadata.license is not one of the known options
("Proprietary","GPL-2.0","GPL-3.0","AGPL-3.0","MIT","Apache-2.0","other") and
pass that defaultLicense instead so custom licenses reopen with the "Other"
choice selected.
**Actionable comments posted: 2** <details> <summary>🤖 Fix all issues with AI agents</summary> ``` In `@src/functions/interact.ts`: - Around line 167-183: The code stores whole choice objects (like a Separator) into selectValues[message], which later gets passed as the default to select() and fails because select expects a choice value string. Update the logic around selectValues to always store the choice value string: when handling Back/Done/Cancel, find the first selectable choice from choices or otherChoices (skip Separator/objects without a value) and set selectValues[message] to that choice.value (or its equivalent string); when storing the user's answer keep the string value. Also validate the computed default before passing it to select() by checking that it exists in the current choices' value list and fall back to undefined if it does not. In `@tools/packager.ts`: - Around line 505-545: The license menu passes metadata.license directly as the default to game.prompt.customSelect which breaks when metadata.license contains a custom string; before calling customSelect, compute a defaultLicense that maps to "other" if metadata.license is not one of the known options ("Proprietary","GPL-2.0","GPL-3.0","AGPL-3.0","MIT","Apache-2.0","other") and pass that defaultLicense instead so custom licenses reopen with the "Other" choice selected. ``` </details> <!-- This is an auto-generated comment by CodeRabbit for review status -->
coderabbitai[bot] (Migrated from github.com) commented 2026-01-28 13:53:47 +00:00

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

cat -n src/functions/interact.ts | sed -n '160,190p'

Repository: LunarTides/Hearthstone.js

Length of output: 968


🏁 Script executed:

rg "Separator" src/functions/interact.ts -B 2 -A 2

Repository: LunarTides/Hearthstone.js

Length of output: 1655


🏁 Script executed:

rg "selectValues\[" src/functions/interact.ts -B 1 -A 1

Repository: LunarTides/Hearthstone.js

Length of output: 369


🏁 Script executed:

head -50 src/functions/interact.ts

Repository: LunarTides/Hearthstone.js

Length of output: 1330


🏁 Script executed:

rg "const selectValues" src/functions/interact.ts -B 5 -A 5

Repository: LunarTides/Hearthstone.js

Length of output: 326


🏁 Script executed:

rg "selectValues\[message\]" src/functions/interact.ts

Repository: LunarTides/Hearthstone.js

Length of output: 225


🏁 Script executed:

# Check if there are any type definitions for selectValues
rg "selectValues" src/functions/interact.ts | head -20

Repository: LunarTides/Hearthstone.js

Length of output: 271


🏁 Script executed:

# Check how selectValues is initialized and used throughout the file
rg "selectValues" src/functions/interact.ts -n

Repository: LunarTides/Hearthstone.js

Length of output: 286


🏁 Script executed:

# Look for other select() calls to see if they also use selectValues as default
rg "default:" src/functions/interact.ts -B 2 -A 1

Repository: LunarTides/Hearthstone.js

Length of output: 656


🏁 Script executed:

# Check the type of choices and what gets pushed into it
rg "choices\.push" src/functions/interact.ts -B 1 -A 1 | head -40

Repository: LunarTides/Hearthstone.js

Length of output: 833


🏁 Script executed:

# Let's look at the function signature and parameters around line 167
sed -n '100,185p' src/functions/interact.ts

Repository: LunarTides/Hearthstone.js

Length of output: 1733


🏁 Script executed:

# Check if there are any tests or error reports related to this
find . -type f -name "*.test.*" -o -name "*.spec.*" | head -10

Repository: LunarTides/Hearthstone.js

Length of output: 380


🏁 Script executed:

# Check package.json to see the `@inquirer/prompts` version
cat package.json | grep -A 5 "@inquirer"

Repository: LunarTides/Hearthstone.js

Length of output: 256


🏁 Script executed:

cat test/src/functions/interact.test.ts

Repository: LunarTides/Hearthstone.js

Length of output: 1600


🏁 Script executed:

# Let's verify the `@inquirer/prompts` documentation by checking how select() handles defaults
# First, check if there's any documentation or comments in the codebase about this
rg "select\(" src/functions/interact.ts -B 3 -A 8

Repository: LunarTides/Hearthstone.js

Length of output: 294


🏁 Script executed:

# Check what happens when resetCursor is true vs false
rg "resetCursor" src/functions/interact.ts -B 2 -A 2

Repository: LunarTides/Hearthstone.js

Length of output: 435


Store choice values, not choice objects, for cursor restoration.

When Back/Done/Cancel is selected, selectValues[message] is set to choices[0] which may be a Separator object with no value property. That stored value is later passed as default to select(), but select() expects a string value matching one of the choice values. A Separator won't match and cursor restoration fails. Extract and store only the first selectable choice's value, and validate defaults against available choice values.

🛠️ Proposed fix
+		const selectableChoices = choices.filter(
+			(choice) => !(choice instanceof Separator),
+		);
+		const choiceValues = selectableChoices.map((choice: any) =>
+			typeof choice === "string" ? choice : choice.value,
+		);
+		const remembered =
+			options?.default ??
+			(options?.resetCursor ? undefined : selectValues[message]);
+		const defaultValue = choiceValues.includes(remembered)
+			? remembered
+			: undefined;
+		const answer = await select({
+			message,
+			choices,
+			default: defaultValue,
+			loop: false,
+			pageSize: 15,
+		});
-		const answer = await select({
-			message,
-			choices,
-			default:
-				options?.default ??
-				(options?.resetCursor ? undefined : selectValues[message]),
-			loop: false,
-			pageSize: 15,
-		});

-		if (["back", "done", "cancel"].includes(answer.toLowerCase())) {
-			// Go back to the first option. The next time.
-			selectValues[message] = choices[0] ?? otherChoices[0];
-		} else {
-			// Remember the cursor position.
-			selectValues[message] = answer;
-		}
+		if (["back", "done", "cancel"].includes(answer.toLowerCase())) {
+			// Go back to the first option next time.
+			selectValues[message] = choiceValues[0];
+		} else {
+			// Remember the cursor position.
+			selectValues[message] = answer;
+		}
🤖 Prompt for AI Agents
In `@src/functions/interact.ts` around lines 167 - 183, The code stores whole
choice objects (like a Separator) into selectValues[message], which later gets
passed as the default to select() and fails because select expects a choice
value string. Update the logic around selectValues to always store the choice
value string: when handling Back/Done/Cancel, find the first selectable choice
from choices or otherChoices (skip Separator/objects without a value) and set
selectValues[message] to that choice.value (or its equivalent string); when
storing the user's answer keep the string value. Also validate the computed
default before passing it to select() by checking that it exists in the current
choices' value list and fall back to undefined if it does not.
_⚠️ Potential issue_ | _🟡 Minor_ <details> <summary>🧩 Analysis chain</summary> 🏁 Script executed: ```shell cat -n src/functions/interact.ts | sed -n '160,190p' ``` Repository: LunarTides/Hearthstone.js Length of output: 968 --- 🏁 Script executed: ```shell rg "Separator" src/functions/interact.ts -B 2 -A 2 ``` Repository: LunarTides/Hearthstone.js Length of output: 1655 --- 🏁 Script executed: ```shell rg "selectValues\[" src/functions/interact.ts -B 1 -A 1 ``` Repository: LunarTides/Hearthstone.js Length of output: 369 --- 🏁 Script executed: ```shell head -50 src/functions/interact.ts ``` Repository: LunarTides/Hearthstone.js Length of output: 1330 --- 🏁 Script executed: ```shell rg "const selectValues" src/functions/interact.ts -B 5 -A 5 ``` Repository: LunarTides/Hearthstone.js Length of output: 326 --- 🏁 Script executed: ```shell rg "selectValues\[message\]" src/functions/interact.ts ``` Repository: LunarTides/Hearthstone.js Length of output: 225 --- 🏁 Script executed: ```shell # Check if there are any type definitions for selectValues rg "selectValues" src/functions/interact.ts | head -20 ``` Repository: LunarTides/Hearthstone.js Length of output: 271 --- 🏁 Script executed: ```shell # Check how selectValues is initialized and used throughout the file rg "selectValues" src/functions/interact.ts -n ``` Repository: LunarTides/Hearthstone.js Length of output: 286 --- 🏁 Script executed: ```shell # Look for other select() calls to see if they also use selectValues as default rg "default:" src/functions/interact.ts -B 2 -A 1 ``` Repository: LunarTides/Hearthstone.js Length of output: 656 --- 🏁 Script executed: ```shell # Check the type of choices and what gets pushed into it rg "choices\.push" src/functions/interact.ts -B 1 -A 1 | head -40 ``` Repository: LunarTides/Hearthstone.js Length of output: 833 --- 🏁 Script executed: ```shell # Let's look at the function signature and parameters around line 167 sed -n '100,185p' src/functions/interact.ts ``` Repository: LunarTides/Hearthstone.js Length of output: 1733 --- 🏁 Script executed: ```shell # Check if there are any tests or error reports related to this find . -type f -name "*.test.*" -o -name "*.spec.*" | head -10 ``` Repository: LunarTides/Hearthstone.js Length of output: 380 --- 🏁 Script executed: ```shell # Check package.json to see the `@inquirer/prompts` version cat package.json | grep -A 5 "@inquirer" ``` Repository: LunarTides/Hearthstone.js Length of output: 256 --- 🏁 Script executed: ```shell cat test/src/functions/interact.test.ts ``` Repository: LunarTides/Hearthstone.js Length of output: 1600 --- 🏁 Script executed: ```shell # Let's verify the `@inquirer/prompts` documentation by checking how select() handles defaults # First, check if there's any documentation or comments in the codebase about this rg "select\(" src/functions/interact.ts -B 3 -A 8 ``` Repository: LunarTides/Hearthstone.js Length of output: 294 --- 🏁 Script executed: ```shell # Check what happens when resetCursor is true vs false rg "resetCursor" src/functions/interact.ts -B 2 -A 2 ``` Repository: LunarTides/Hearthstone.js Length of output: 435 --- </details> **Store choice values, not choice objects, for cursor restoration.** When Back/Done/Cancel is selected, `selectValues[message]` is set to `choices[0]` which may be a `Separator` object with no `value` property. That stored value is later passed as `default` to `select()`, but `select()` expects a string value matching one of the choice values. A Separator won't match and cursor restoration fails. Extract and store only the first selectable choice's *value*, and validate defaults against available choice values. <details> <summary>🛠️ Proposed fix</summary> ```diff + const selectableChoices = choices.filter( + (choice) => !(choice instanceof Separator), + ); + const choiceValues = selectableChoices.map((choice: any) => + typeof choice === "string" ? choice : choice.value, + ); + const remembered = + options?.default ?? + (options?.resetCursor ? undefined : selectValues[message]); + const defaultValue = choiceValues.includes(remembered) + ? remembered + : undefined; + const answer = await select({ + message, + choices, + default: defaultValue, + loop: false, + pageSize: 15, + }); - const answer = await select({ - message, - choices, - default: - options?.default ?? - (options?.resetCursor ? undefined : selectValues[message]), - loop: false, - pageSize: 15, - }); - if (["back", "done", "cancel"].includes(answer.toLowerCase())) { - // Go back to the first option. The next time. - selectValues[message] = choices[0] ?? otherChoices[0]; - } else { - // Remember the cursor position. - selectValues[message] = answer; - } + if (["back", "done", "cancel"].includes(answer.toLowerCase())) { + // Go back to the first option next time. + selectValues[message] = choiceValues[0]; + } else { + // Remember the cursor position. + selectValues[message] = answer; + } ``` </details> <details> <summary>🤖 Prompt for AI Agents</summary> ``` In `@src/functions/interact.ts` around lines 167 - 183, The code stores whole choice objects (like a Separator) into selectValues[message], which later gets passed as the default to select() and fails because select expects a choice value string. Update the logic around selectValues to always store the choice value string: when handling Back/Done/Cancel, find the first selectable choice from choices or otherChoices (skip Separator/objects without a value) and set selectValues[message] to that choice.value (or its equivalent string); when storing the user's answer keep the string value. Also validate the computed default before passing it to select() by checking that it exists in the current choices' value list and fall back to undefined if it does not. ``` </details> <!-- fingerprinting:phantom:medusa:eagle --> <!-- This is an auto-generated comment by CodeRabbit -->
@ -501,46 +502,56 @@ async function configureMetadata(metadata: Metadata) {
coderabbitai[bot] (Migrated from github.com) commented 2026-01-28 13:53:47 +00:00

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, let's check the file and see the actual code at those lines
cd /repo && head -550 tools/packager.ts | tail -50

Repository: LunarTides/Hearthstone.js

Length of output: 124


🏁 Script executed:

pwd && ls -la

Repository: LunarTides/Hearthstone.js

Length of output: 1757


🏁 Script executed:

# Check the packager.ts file and view the specific lines
wc -l tools/packager.ts

Repository: LunarTides/Hearthstone.js

Length of output: 90


🏁 Script executed:

# View the specific lines mentioned in the review
sed -n '480,560p' tools/packager.ts

Repository: LunarTides/Hearthstone.js

Length of output: 1943


🏁 Script executed:

# Let's find the customSelect implementation to understand how it handles defaults
find . -type f -name "*.ts" -o -name "*.js" | xargs grep -l "customSelect" | head -10

Repository: LunarTides/Hearthstone.js

Length of output: 1193


🏁 Script executed:

# Let's check the hub.ts file since it seems to contain customSelect
grep -n "customSelect" hub.ts | head -20

Repository: LunarTides/Hearthstone.js

Length of output: 244


🏁 Script executed:

# Let's find where game.prompt is defined - likely in Hearthstone.js library
grep -r "prompt.*customSelect" --include="*.ts" --include="*.js" | head -5

Repository: LunarTides/Hearthstone.js

Length of output: 378


🏁 Script executed:

# Let's search for where metadata is loaded/initialized to understand what values metadata.license can have
grep -n "metadata" tools/packager.ts | grep -E "load|read|init|license" | head -20

Repository: LunarTides/Hearthstone.js

Length of output: 253


🏁 Script executed:

# Let's look at where metadata is loaded and initialized
sed -n '1,100p' tools/packager.ts | grep -A5 -B5 "metadata"

Repository: LunarTides/Hearthstone.js

Length of output: 709


🏁 Script executed:

# Search for where metadata is loaded from file
grep -n "metadata\|readTextFile\|JSON.parse" tools/packager.ts | head -30

Repository: LunarTides/Hearthstone.js

Length of output: 1627


🏁 Script executed:

# Let's see the full metadata initialization to understand the default license value
sed -n '312,338p' tools/packager.ts

Repository: LunarTides/Hearthstone.js

Length of output: 696


🏁 Script executed:

# Let's check if there's a way to see the customSelect implementation or its behavior
# First, check if it's from an external library by looking at imports
grep -n "import\|from" hub.ts | grep -i prompt

Repository: LunarTides/Hearthstone.js

Length of output: 126


🏁 Script executed:

# Let's check the `@inquirer/prompts` documentation and see if there are any test cases
# First, let's look for any test files related to packager
find . -type f -name "*.test.ts" -o -name "*.spec.ts" | xargs grep -l "packager\|customSelect" 2>/dev/null

Repository: LunarTides/Hearthstone.js

Length of output: 106


🏁 Script executed:

# Let's examine this test file
cat ./test/src/functions/interact.test.ts

Repository: LunarTides/Hearthstone.js

Length of output: 1600


🏁 Script executed:

# Let's find the actual interact.ts file that implements customSelect
find . -type f -name "interact.ts" | grep -v test

Repository: LunarTides/Hearthstone.js

Length of output: 96


🏁 Script executed:

# Let's look at the customSelect implementation
grep -n "customSelect" src/functions/interact.ts -A 30 | head -50

Repository: LunarTides/Hearthstone.js

Length of output: 1430


Map custom license values to "other" option when reopening packs.

When a user selects "other" and enters a custom license, that value is stored in metadata.license. If the pack is reopened and the license menu is accessed again, the custom string is passed as default to customSelect. Since it won't match any predefined option, this creates an invalid default selection. Map unknown values to "other" before calling customSelect so custom licenses default to the appropriate choice.

🛠️ Proposed fix
-		const license = await game.prompt.customSelect(
+		const knownLicenses = new Set([
+			"Proprietary",
+			"GPL-2.0",
+			"GPL-3.0",
+			"AGPL-3.0",
+			"MIT",
+			"Apache-2.0",
+		]);
+		const licenseDefault = knownLicenses.has(metadata.license)
+			? metadata.license
+			: "other";
+		const license = await game.prompt.customSelect(
 			"Set the license of the pack.",
 			[],
 			{
 				hideBack: true,
-				default: metadata.license,
+				default: licenseDefault,
 				arrayTransform: undefined,
 			},
🤖 Prompt for AI Agents
In `@tools/packager.ts` around lines 505 - 545, The license menu passes
metadata.license directly as the default to game.prompt.customSelect which
breaks when metadata.license contains a custom string; before calling
customSelect, compute a defaultLicense that maps to "other" if metadata.license
is not one of the known options
("Proprietary","GPL-2.0","GPL-3.0","AGPL-3.0","MIT","Apache-2.0","other") and
pass that defaultLicense instead so custom licenses reopen with the "Other"
choice selected.

Addressed in commit caae3b4

_⚠️ Potential issue_ | _🟡 Minor_ <details> <summary>🧩 Analysis chain</summary> 🏁 Script executed: ```shell # First, let's check the file and see the actual code at those lines cd /repo && head -550 tools/packager.ts | tail -50 ``` Repository: LunarTides/Hearthstone.js Length of output: 124 --- 🏁 Script executed: ```shell pwd && ls -la ``` Repository: LunarTides/Hearthstone.js Length of output: 1757 --- 🏁 Script executed: ```shell # Check the packager.ts file and view the specific lines wc -l tools/packager.ts ``` Repository: LunarTides/Hearthstone.js Length of output: 90 --- 🏁 Script executed: ```shell # View the specific lines mentioned in the review sed -n '480,560p' tools/packager.ts ``` Repository: LunarTides/Hearthstone.js Length of output: 1943 --- 🏁 Script executed: ```shell # Let's find the customSelect implementation to understand how it handles defaults find . -type f -name "*.ts" -o -name "*.js" | xargs grep -l "customSelect" | head -10 ``` Repository: LunarTides/Hearthstone.js Length of output: 1193 --- 🏁 Script executed: ```shell # Let's check the hub.ts file since it seems to contain customSelect grep -n "customSelect" hub.ts | head -20 ``` Repository: LunarTides/Hearthstone.js Length of output: 244 --- 🏁 Script executed: ```shell # Let's find where game.prompt is defined - likely in Hearthstone.js library grep -r "prompt.*customSelect" --include="*.ts" --include="*.js" | head -5 ``` Repository: LunarTides/Hearthstone.js Length of output: 378 --- 🏁 Script executed: ```shell # Let's search for where metadata is loaded/initialized to understand what values metadata.license can have grep -n "metadata" tools/packager.ts | grep -E "load|read|init|license" | head -20 ``` Repository: LunarTides/Hearthstone.js Length of output: 253 --- 🏁 Script executed: ```shell # Let's look at where metadata is loaded and initialized sed -n '1,100p' tools/packager.ts | grep -A5 -B5 "metadata" ``` Repository: LunarTides/Hearthstone.js Length of output: 709 --- 🏁 Script executed: ```shell # Search for where metadata is loaded from file grep -n "metadata\|readTextFile\|JSON.parse" tools/packager.ts | head -30 ``` Repository: LunarTides/Hearthstone.js Length of output: 1627 --- 🏁 Script executed: ```shell # Let's see the full metadata initialization to understand the default license value sed -n '312,338p' tools/packager.ts ``` Repository: LunarTides/Hearthstone.js Length of output: 696 --- 🏁 Script executed: ```shell # Let's check if there's a way to see the customSelect implementation or its behavior # First, check if it's from an external library by looking at imports grep -n "import\|from" hub.ts | grep -i prompt ``` Repository: LunarTides/Hearthstone.js Length of output: 126 --- 🏁 Script executed: ```shell # Let's check the `@inquirer/prompts` documentation and see if there are any test cases # First, let's look for any test files related to packager find . -type f -name "*.test.ts" -o -name "*.spec.ts" | xargs grep -l "packager\|customSelect" 2>/dev/null ``` Repository: LunarTides/Hearthstone.js Length of output: 106 --- 🏁 Script executed: ```shell # Let's examine this test file cat ./test/src/functions/interact.test.ts ``` Repository: LunarTides/Hearthstone.js Length of output: 1600 --- 🏁 Script executed: ```shell # Let's find the actual interact.ts file that implements customSelect find . -type f -name "interact.ts" | grep -v test ``` Repository: LunarTides/Hearthstone.js Length of output: 96 --- 🏁 Script executed: ```shell # Let's look at the customSelect implementation grep -n "customSelect" src/functions/interact.ts -A 30 | head -50 ``` Repository: LunarTides/Hearthstone.js Length of output: 1430 --- </details> **Map custom license values to "other" option when reopening packs.** When a user selects "other" and enters a custom license, that value is stored in `metadata.license`. If the pack is reopened and the license menu is accessed again, the custom string is passed as `default` to `customSelect`. Since it won't match any predefined option, this creates an invalid default selection. Map unknown values to `"other"` before calling `customSelect` so custom licenses default to the appropriate choice. <details> <summary>🛠️ Proposed fix</summary> ```diff - const license = await game.prompt.customSelect( + const knownLicenses = new Set([ + "Proprietary", + "GPL-2.0", + "GPL-3.0", + "AGPL-3.0", + "MIT", + "Apache-2.0", + ]); + const licenseDefault = knownLicenses.has(metadata.license) + ? metadata.license + : "other"; + const license = await game.prompt.customSelect( "Set the license of the pack.", [], { hideBack: true, - default: metadata.license, + default: licenseDefault, arrayTransform: undefined, }, ``` </details> <details> <summary>🤖 Prompt for AI Agents</summary> ``` In `@tools/packager.ts` around lines 505 - 545, The license menu passes metadata.license directly as the default to game.prompt.customSelect which breaks when metadata.license contains a custom string; before calling customSelect, compute a defaultLicense that maps to "other" if metadata.license is not one of the known options ("Proprietary","GPL-2.0","GPL-3.0","AGPL-3.0","MIT","Apache-2.0","other") and pass that defaultLicense instead so custom licenses reopen with the "Other" choice selected. ``` </details> <!-- fingerprinting:phantom:medusa:eagle --> <!-- This is an auto-generated comment by CodeRabbit --> ✅ Addressed in commit caae3b4
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
LunarTides/Hearthstone.js!462
No description provided.