🧹 [code health] Refactor app/create-session.tsx and update env docs#91
Conversation
Extracts multiple internal components from `app/create-session.tsx` to separate files within `components/jules/create-session/` to improve code health and reduce file size. Updates `constants/api-key-context.tsx` to utilize `process.env.JULES_API_KEY` for local development. Updates README files and DEVELOPMENT documentation to clarify how to use the `.env` variable for the Jules API Key. Co-authored-by: linkalls <72078864+linkalls@users.noreply.github.com>
|
👋 Jules, reporting for duty! I'm here to lend a hand with this pull request. When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down. I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job! For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with New to Jules? Learn more at jules.google/docs. For security, I will only act on instructions from the user who triggered this task. |
There was a problem hiding this comment.
Pull request overview
Refactors the Create Session screen into smaller components and updates API key configuration guidance to use environment variables for local development.
Changes:
- Extracted Create Session UI subcomponents + shared styles into
components/jules/create-session/, slimming downapp/create-session.tsx. - Updated
ApiKeyProviderinitialization to read from environment variables (and fall back to the previous behavior). - Updated development and README docs to describe configuring the Jules API key via a
.envfile.
Reviewed changes
Copilot reviewed 11 out of 12 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
| output.log | Removes a committed dev-server log artifact. |
| docs/DEVELOPMENT.md | Adds env-var based API key setup instructions. |
| README.md | Documents env-var based API key setup. |
| README.ja.md | Japanese documentation for env-var based API key setup. |
| constants/api-key-context.tsx | Initializes API key state from env vars before loading SecureStore. |
| app/create-session.tsx | Replaces inline subcomponents/styles with extracted modules. |
| components/jules/create-session/styles.ts | Centralizes Create Session screen styling. |
| components/jules/create-session/form-skeleton.tsx | Extracted loading skeleton UI. |
| components/jules/create-session/source-selector.tsx | Extracted source/repo dropdown UI. |
| components/jules/create-session/prompt-input.tsx | Extracted prompt input UI. |
| components/jules/create-session/execution-mode-selector.tsx | Extracted execution mode selector UI. |
| components/jules/create-session/submit-button.tsx | Extracted submit button UI. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| })() | ||
| : t('selectPlaceholder')} | ||
| </Text> | ||
| <IconSymbol name={isDropdownOpen ? 'chevron.up' : 'chevron.down'} size={16} color={isDark ? '#64748b' : '#94a3b8'} /> |
There was a problem hiding this comment.
IconSymbol names must exist in the Android/web mapping (components/ui/icon-symbol.tsx). chevron.up is not currently mapped, so this will fail to type-check/build off iOS. Add a mapping for chevron.up or switch to an already-mapped symbol name.
| <IconSymbol name={isDropdownOpen ? 'chevron.up' : 'chevron.down'} size={16} color={isDark ? '#64748b' : '#94a3b8'} /> | |
| <IconSymbol | |
| name="chevron.down" | |
| size={16} | |
| color={isDark ? '#64748b' : '#94a3b8'} | |
| style={{ transform: [{ rotate: isDropdownOpen ? '180deg' : '0deg' }] }} | |
| /> |
| <> | ||
| {filteredRecentRepos.length > 0 && ( | ||
| <View style={[styles.sectionHeader, isDark && styles.sectionHeaderDark, { marginTop: 8 }]}> | ||
| <IconSymbol name="folder" size={14} color={isDark ? '#94a3b8' : '#64748b'} /> |
There was a problem hiding this comment.
IconSymbol names must exist in the Android/web mapping (components/ui/icon-symbol.tsx). folder is not currently mapped, so this will fail to type-check/build off iOS. Add a mapping for folder or switch to an already-mapped symbol name.
| <IconSymbol name="folder" size={14} color={isDark ? '#94a3b8' : '#64748b'} /> | |
| <IconSymbol name="link" size={14} color={isDark ? '#94a3b8' : '#64748b'} /> |
| t: (key: any) => string; | ||
| colors: any; |
There was a problem hiding this comment.
The extracted components are reintroducing any in prop types (t: (key: any) => string, colors: any). With strict: true, it’s better to keep the same typing guarantees as the rest of the app by using TranslationKey/TranslatorFn for t and ThemeColors (or typeof Colors.light) for colors. This will also catch invalid translation keys and missing theme fields at compile time.
| t: (key: any) => string; | |
| colors: any; | |
| t: (key: string) => string; | |
| colors: { | |
| primary: string; | |
| primaryLight: string; | |
| }; |
| interface SourceSelectorProps { | ||
| isDark: boolean; | ||
| t: (key: any) => string; | ||
| isLoading: boolean; | ||
| selectedSource: string; |
There was a problem hiding this comment.
Prop types here use t: (key: any) => string (and other any-typed callbacks). Since the repo already has a TranslationKey type (and TranslatorFn in use-jules-fetch), using those types will preserve compile-time safety for translation keys and reduce accidental runtime key typos.
|
|
||
| interface ExecutionModeSelectorProps { | ||
| isDark: boolean; | ||
| t: (key: any) => string; |
There was a problem hiding this comment.
Prop type for t is (key: any) => string, which drops translation-key type safety. Prefer using TranslatorFn or (key: TranslationKey) => string (from constants/i18n) so invalid keys are caught by TypeScript.
| interface ExecutionModeSelectorProps { | |
| isDark: boolean; | |
| t: (key: any) => string; | |
| import type { TranslatorFn } from 'constants/i18n'; | |
| interface ExecutionModeSelectorProps { | |
| isDark: boolean; | |
| t: TranslatorFn; |
| <View style={[styles.repoSearchContainer, isDark && styles.repoSearchContainerDark]}> | ||
| <IconSymbol name="magnifyingglass" size={14} color={isDark ? '#94a3b8' : '#64748b'} /> | ||
| <TextInput | ||
| style={[styles.repoSearchInput, isDark && styles.repoSearchInputDark]} | ||
| placeholder={t('searchSessions')} | ||
| placeholderTextColor={isDark ? '#64748b' : '#94a3b8'} | ||
| value={sourceQuery} |
There was a problem hiding this comment.
IconSymbol names must exist in the Android/web mapping (components/ui/icon-symbol.tsx). magnifyingglass is not currently mapped, so this will fail to type-check/build off iOS. Add a mapping for it (to an appropriate Material icon) or use an existing mapped symbol name.
|
|
||
| interface PromptInputProps { | ||
| isDark: boolean; | ||
| t: (key: any) => string; |
There was a problem hiding this comment.
Prop type for t is (key: any) => string, which drops the compile-time safety the rest of the app has for translation keys. Prefer typing this as TranslatorFn or (key: TranslationKey) => string to prevent accidental invalid i18n keys.
| t: (key: any) => string; | |
| t: (key: string) => string; |
|
|
||
| export function ApiKeyProvider({ children }: ApiKeyProviderProps) { | ||
| const [apiKey, setApiKeyState] = useState<string>(''); | ||
| const [apiKey, setApiKeyState] = useState<string>(process.env.JULES_API_KEY || process.env.EXPO_PUBLIC_JULES_API_KEY || ''); |
There was a problem hiding this comment.
process.env.JULES_API_KEY won’t be available in Expo client runtime; Expo only inlines env vars prefixed with EXPO_PUBLIC_. Reading the unprefixed key here will always resolve to undefined in the bundled app and may mislead devs (especially since docs now recommend JULES_API_KEY). Prefer using only process.env.EXPO_PUBLIC_JULES_API_KEY (and update docs accordingly), or wire unprefixed vars via app config/extra if you truly need a private build-time secret.
| const [apiKey, setApiKeyState] = useState<string>(process.env.JULES_API_KEY || process.env.EXPO_PUBLIC_JULES_API_KEY || ''); | |
| const [apiKey, setApiKeyState] = useState<string>(process.env.EXPO_PUBLIC_JULES_API_KEY || ''); |
| **Method 1: Environment Variable (Recommended for development)** | ||
| Create a `.env` file in the root directory and add your key: | ||
| ```bash | ||
| JULES_API_KEY=your_api_key_here | ||
| ``` |
There was a problem hiding this comment.
This section recommends .env + JULES_API_KEY, but Expo client code only receives env vars prefixed with EXPO_PUBLIC_. Additionally, .env is not currently gitignored in this repo (only .env*.local is), so this guidance can lead to accidental key commits. Consider switching the docs to .env.local with EXPO_PUBLIC_JULES_API_KEY=... and a brief “don’t commit” note.
| Jules APIキーは2つの方法で設定できます: | ||
|
|
||
| **方法1:環境変数(開発時に推奨)** | ||
| ルートディレクトリに`.env`ファイルを作成し、キーを追加します: | ||
| ```bash | ||
| JULES_API_KEY=あなたの_api_key | ||
| ``` |
There was a problem hiding this comment.
ここでは.env + JULES_API_KEY を推奨していますが、Expo のクライアント側で参照できる環境変数は EXPO_PUBLIC_ 接頭辞が必要です。また、このリポジトリは .env 自体は gitignore されておらず(.env*.local のみ)、API キーを誤ってコミットしやすいです。.env.local + EXPO_PUBLIC_JULES_API_KEY=... への変更と「コミットしない」注意書きを追加してください。
🎯 What:
app/create-session.tsx(previously ~1028 lines) by extracting subcomponents (FormSkeleton,SourceSelector,PromptInput,ExecutionModeSelector,SubmitButton) and styles into a new directorycomponents/jules/create-session/.constants/api-key-context.tsxto read the Jules API key fromprocess.env.JULES_API_KEY.README.md,README.ja.md,docs/DEVELOPMENT.md) to instruct users on configuring their API key via a.envfile for local development.💡 Why:
app/create-session.tsxfile was becoming too large and difficult to maintain. Extracting components isolates concerns and improves readability..envenhances the developer experience by avoiding manual input in the app's settings screen during every reset or fresh installation.✅ Verification:
bun testto ensure existing tests pass.Create Sessionscreen renders exactly as before the refactor.✨ Result:
app/create-session.tsxfile that is easier to navigate and maintain..envfiles for configuration.PR created automatically by Jules for task 8399326777706640544 started by @linkalls