Add game-scout extension#27267
Conversation
|
Congratulations on your new Raycast extension! 🚀 We're currently experiencing a high volume of incoming requests. As a result, the initial review may take up to 10-15 business days. Once the PR is approved and merged, the extension will be available on our Store. |
Greptile SummaryGame Scout is a new extension for tracking game prices, deals, and giveaways across multiple storefronts using IsThereAnyDeal, CheapShark, and GamerPower APIs. The implementation is feature-rich, but there is one clear behavioral defect in the Saved Games command that needs to be fixed before merging.
Confidence Score: 3/5Not safe to merge as-is — the bundle count bug in Saved Games causes a feature to be permanently non-functional. One confirmed P1 defect (bundle counts always 0 in saved-games) plus a Rules of Hooks violation that will be flagged by the linter lower the score from the P1 ceiling of 4. extensions/game-scout/src/saved-games.tsx (bundle count logic), extensions/game-scout/src/search-games.tsx (hooks ordering), extensions/game-scout/package.json (separator dropdown value) Important Files Changed
Prompt To Fix All With AIFix the following 4 code review issues. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 4
extensions/game-scout/src/saved-games.tsx:149-159
**Bundle counts always zero in Saved Games**
The `/games/overview/v2` endpoint returns an **array** of per-game objects (each with a numeric `bundles` field), not a top-level object with a `bundles` array. `oJson.bundles` is therefore always `undefined`, so `(oJson.bundles || []).filter(...)` always resolves to `[]` with length 0 — bundle counts are never populated and the bundle indicator never appears in the saved-games list.
A corrected version would look up each game's overview entry and read its numeric `bundles` field:
```ts
gameIds.forEach((id) => {
const entry = Array.isArray(oJson)
? oJson.find((g: any) => g.id === id)
: oJson?.[id];
bMap[id] = typeof entry?.bundles === "number" ? entry.bundles : 0;
});
```
### Issue 2 of 4
extensions/game-scout/src/search-games.tsx:49-80
**React hooks called after a conditional return**
`useState(false)` is called at line 49, then lines 53–72 conditionally return early before the remaining `useState`/`useEffect`/`useFetch` calls at lines 74–163. This violates the Rules of Hooks: hooks must be called in the same order on every render. The same pattern appears in `saved-games.tsx` (lines 50–66 return early before all hook definitions starting at line 69).
In practice this doesn't crash today because `API_KEY` and `COUNTRY` are module-level constants that never change between renders. However, the ESLint `react-hooks/rules-of-hooks` rule will flag this and future refactors could inadvertently break it.
### Issue 3 of 4
extensions/game-scout/package.json:1-5
**Missing `$schema` reference in package.json**
The `package.json` doesn't include the Raycast schema reference, which enables autocomplete, validation, and IntelliSense for extension fields in editors.
```suggestion
{
"$schema": "https://www.raycast.com/schemas/extension.json",
"name": "game-scout",
```
### Issue 4 of 4
extensions/game-scout/package.json:112-115
**Separator dropdown item produces empty country code, bypassing region validation in some commands**
Selecting the `──────────` separator item sets `preferences.country` to `""`. `search-games.tsx` catches this (checks `COUNTRY.length === 2`), but `saved-games.tsx` has no such guard — ITAD API calls would be made with `country=` (empty string), likely producing unexpected results or silent failures.
Consider removing the interactive separator item or mapping it to a valid default value.
Reviews (3): Last reviewed commit: "fix: multiple improvements and bug fixes" | Re-trigger Greptile |
|
All mentioned issues have been resolved and pushed. |
|
Hi, could a maintainer please approve the workflows so the CI checks can run? Thank you! |
…dle value engine, and UI polish
|
All Greptile issues from first review resolved:
Phase 1.5 additions:
|
|
Updated screenshots to strictly follow store guidelines. |
- Fix CACHE_TTL to use refreshFrequency preference - Remove unused imports and variables (lint fixes) - Fix Price Drops: deduplication, regular price format, separator
…afe, verdict fixes, truncation with ellipsis
- Improve bundle status logic - Fix price history chart preference not applying - Replace mature content icon with tag - Fix TypeScript preference types - Add null checks for prices and priceData
| const now = Date.now(); | ||
| const bMap: any = {}; | ||
| gameIds.forEach((id) => { | ||
| bMap[id] = (oJson.bundles || []).filter((b: any) => { | ||
| const isNotExpired = !b.expiry || new Date(b.expiry).getTime() > now; | ||
| return ( | ||
| isNotExpired && | ||
| b.tiers?.some((t: any) => t.games?.some((gm: any) => gm.id === id)) | ||
| ); | ||
| }).length; | ||
| }); |
There was a problem hiding this comment.
Bundle counts always zero in Saved Games
The /games/overview/v2 endpoint returns an array of per-game objects (each with a numeric bundles field), not a top-level object with a bundles array. oJson.bundles is therefore always undefined, so (oJson.bundles || []).filter(...) always resolves to [] with length 0 — bundle counts are never populated and the bundle indicator never appears in the saved-games list.
A corrected version would look up each game's overview entry and read its numeric bundles field:
gameIds.forEach((id) => {
const entry = Array.isArray(oJson)
? oJson.find((g: any) => g.id === id)
: oJson?.[id];
bMap[id] = typeof entry?.bundles === "number" ? entry.bundles : 0;
});Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/game-scout/src/saved-games.tsx
Line: 149-159
Comment:
**Bundle counts always zero in Saved Games**
The `/games/overview/v2` endpoint returns an **array** of per-game objects (each with a numeric `bundles` field), not a top-level object with a `bundles` array. `oJson.bundles` is therefore always `undefined`, so `(oJson.bundles || []).filter(...)` always resolves to `[]` with length 0 — bundle counts are never populated and the bundle indicator never appears in the saved-games list.
A corrected version would look up each game's overview entry and read its numeric `bundles` field:
```ts
gameIds.forEach((id) => {
const entry = Array.isArray(oJson)
? oJson.find((g: any) => g.id === id)
: oJson?.[id];
bMap[id] = typeof entry?.bundles === "number" ? entry.bundles : 0;
});
```
How can I resolve this? If you propose a fix, please make it concise.
Description
Game Scout is a comprehensive extension for gamers to search across multiple storefronts, track historical lows, discover free giveaways, and catch the best daily deals without leaving the launcher.
Key Features
Screencast
Checklist
npm run buildand tested this distribution build in Raycastassetsfolder are used by the extension itselfREADMEare placed outside of themetadatafolder