Add firebase-remote-config-admin extension#27125
Add firebase-remote-config-admin extension#27125danilorequena wants to merge 2 commits intoraycast:mainfrom
Conversation
- Add .claude/ to gitignore - Initial release of Firebase - Remote Config extension
|
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 SummaryThis PR adds a new
Confidence Score: 4/5Not safe to merge until the resolveProjectsForTool fallback and missing metadata folder are addressed. Two P1 findings block merge: the resolveProjectsForTool silent fallback can cause unintended mass writes in AI tool context, and the missing metadata/ folder blocks Raycast store submission. The manual Preferences type is a rule violation worth fixing. Remaining findings are P2 style/type issues. extensions/firebase-remote-config-admin/src/storage.ts (resolveProjectsForTool fallback), extensions/firebase-remote-config-admin/src/types.ts (manual Preferences interface), and the missing metadata/ folder. Important Files Changed
|
| import { LocalStorage, getPreferenceValues } from "@raycast/api"; | ||
| import { randomUUID } from "node:crypto"; | ||
|
|
||
| import type { | ||
| Preferences, |
There was a problem hiding this comment.
Manual
Preferences type will diverge from auto-generated types
Preferences is manually defined in types.ts and passed to getPreferenceValues<Preferences>() here. Raycast auto-generates this interface in raycast-env.d.ts from package.json at build time. Using a hand-crafted version means any future change to the preferences schema in package.json won't be reflected here, causing silent type drift and potential runtime mismatches.
Remove the Preferences interface from types.ts and update storage.ts to use the auto-generated type:
| import { LocalStorage, getPreferenceValues } from "@raycast/api"; | |
| import { randomUUID } from "node:crypto"; | |
| import type { | |
| Preferences, | |
| import { LocalStorage, getPreferenceValues } from "@raycast/api"; | |
| import { randomUUID } from "node:crypto"; | |
| import type { | |
| ProjectConfig, | |
| ProjectGroup, | |
| SelectableProjectScope, | |
| } from "./types"; |
And update getPreferences:
export function getPreferences() {
return getPreferenceValues<Preferences>();
}Preferences will be resolved from raycast-env.d.ts.
Rule Used: What: Don't manually define Preferences for `get... (source)
Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/firebase-remote-config-admin/src/storage.ts
Line: 1-5
Comment:
**Manual `Preferences` type will diverge from auto-generated types**
`Preferences` is manually defined in `types.ts` and passed to `getPreferenceValues<Preferences>()` here. Raycast auto-generates this interface in `raycast-env.d.ts` from `package.json` at build time. Using a hand-crafted version means any future change to the preferences schema in `package.json` won't be reflected here, causing silent type drift and potential runtime mismatches.
Remove the `Preferences` interface from `types.ts` and update `storage.ts` to use the auto-generated type:
```suggestion
import { LocalStorage, getPreferenceValues } from "@raycast/api";
import { randomUUID } from "node:crypto";
import type {
ProjectConfig,
ProjectGroup,
SelectableProjectScope,
} from "./types";
```
And update `getPreferences`:
```typescript
export function getPreferences() {
return getPreferenceValues<Preferences>();
}
```
`Preferences` will be resolved from `raycast-env.d.ts`.
**Rule Used:** What: Don't manually define `Preferences` for `get... ([source](https://app.greptile.com/review/custom-context?memory=d93fc9fb-a45d-4479-a6a4-b1b4af98ebc8))
How can I resolve this? If you propose a fix, please make it concise.| const raycastConfig = require("@raycast/eslint-config"); | ||
|
|
||
| module.exports = raycastConfig.flat(Infinity); |
There was a problem hiding this comment.
ESLint config should use
defineConfig from eslint/config
The current config calls .flat(Infinity) directly instead of the recommended defineConfig wrapper. ESLint v9's official pattern uses defineConfig to handle nested config arrays from presets like @raycast/eslint-config.
| const raycastConfig = require("@raycast/eslint-config"); | |
| module.exports = raycastConfig.flat(Infinity); | |
| const { defineConfig } = require("eslint/config"); | |
| const raycastConfig = require("@raycast/eslint-config"); | |
| module.exports = defineConfig([...raycastConfig]); |
Rule Used: What: Enforce importing defineConfig from `"esli... (source)
Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/firebase-remote-config-admin/eslint.config.js
Line: 1-3
Comment:
**ESLint config should use `defineConfig` from `eslint/config`**
The current config calls `.flat(Infinity)` directly instead of the recommended `defineConfig` wrapper. ESLint v9's official pattern uses `defineConfig` to handle nested config arrays from presets like `@raycast/eslint-config`.
```suggestion
const { defineConfig } = require("eslint/config");
const raycastConfig = require("@raycast/eslint-config");
module.exports = defineConfig([...raycastConfig]);
```
**Rule Used:** What: Enforce importing `defineConfig` from `"esli... ([source](https://app.greptile.com/review/custom-context?memory=645a7150-4078-490e-a70c-d6aad94e0cf5))
How can I resolve this? If you propose a fix, please make it concise.| <List | ||
| isLoading={isPublishing} | ||
| isShowingDetail | ||
| navigationTitle="Bulk Preview" | ||
| searchBarPlaceholder="Review project-level preview results" | ||
| > | ||
| {prepared.map((result) => ( | ||
| <List.Item | ||
| key={result.project.id} | ||
| title={result.project.displayName} | ||
| subtitle={ |
There was a problem hiding this comment.
Form description is static and won't reflect the user's selected operation
usesParameter and usesCondition are evaluated against initial?.operationType, which is the prop passed at mount time — not the value currently selected in the operationType dropdown. When the user switches operations, the description text stays frozen at the initial value. This should track the live form state (e.g., via a useState for the selected operation type).
Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/firebase-remote-config-admin/src/bulk-operation-form.tsx
Line: 415-425
Comment:
**Form description is static and won't reflect the user's selected operation**
`usesParameter` and `usesCondition` are evaluated against `initial?.operationType`, which is the prop passed at mount time — not the value currently selected in the `operationType` dropdown. When the user switches operations, the description text stays frozen at the initial value. This should track the live form state (e.g., via a `useState` for the selected operation type).
How can I resolve this? If you propose a fix, please make it concise.| } | ||
|
|
||
| function normalizeTemplate( | ||
| template: RemoteConfigTemplate, | ||
| ): RemoteConfigTemplate { | ||
| const nextTemplate = cloneTemplate(template); | ||
| nextTemplate.parameters = Object.fromEntries( |
There was a problem hiding this comment.
Return type drops
useInAppDefault from RemoteConfigValue
The return type is declared as Record<string, { value: string }>, losing the useInAppDefault optional field present in RemoteConfigValue. At runtime the property is preserved because Object.entries / Object.fromEntries pass through all own properties, but the TypeScript type strips it, masking this field downstream in the type checker.
| } | |
| function normalizeTemplate( | |
| template: RemoteConfigTemplate, | |
| ): RemoteConfigTemplate { | |
| const nextTemplate = cloneTemplate(template); | |
| nextTemplate.parameters = Object.fromEntries( | |
| function sortConditionalValues( | |
| values: Record<string, { value: string; useInAppDefault?: boolean }>, | |
| ): Record<string, { value: string; useInAppDefault?: boolean }> { |
Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/firebase-remote-config-admin/src/bulk-engine.ts
Line: 30-36
Comment:
**Return type drops `useInAppDefault` from `RemoteConfigValue`**
The return type is declared as `Record<string, { value: string }>`, losing the `useInAppDefault` optional field present in `RemoteConfigValue`. At runtime the property is preserved because `Object.entries` / `Object.fromEntries` pass through all own properties, but the TypeScript type strips it, masking this field downstream in the type checker.
```suggestion
function sortConditionalValues(
values: Record<string, { value: string; useInAppDefault?: boolean }>,
): Record<string, { value: string; useInAppDefault?: boolean }> {
```
How can I resolve this? If you propose a fix, please make it concise.
Description
Screencast
Checklist
npm run buildand tested this distribution build in Raycastassetsfolder are used by the extension itselfREADMEare placed outside of themetadatafolder