feat: enable AIPG_DEBUGGING_PORT in packaged builds + rewire --start-page flag#241
Conversation
Drop the `!app.isPackaged` guard so the existing env-var-gated Chrome DevTools Protocol port works in packaged builds too. The env var itself remains opt-in (off by default), so this extends an existing dev capability into a distribution channel without changing the default security posture. Use case: an external controller process (e.g. an automation runner) needs a stable, packaged build to attach CDP and observe / steer the renderer in production-shaped environments. Signed-off-by: kyleriemensnider <kyle.riemensnider@gmail.com>
The getInitialPage IPC handler still returned the legacy AipgPage vocabulary (`create | enhance | answer | learn-more`), which no longer matches the renderer's ModeType (`chat | imageGen | imageEdit | video`). The renderer never consumed the IPC result, so the --start-page CLI flag was effectively dead in v3.x. Changes: - main process: validate the parsed --start-page= value against ModeType and return 'chat' as the safe fallback. - env.d.ts: switch getInitialPage's return type to Promise<ModeType> and drop the now-unused AipgPage alias. - renderer entry: top-level await getInitialPage() alongside the existing getDemoModeSettings() call, then route the result through promptStore.setCurrentMode() so the mode change also picks up the last-used preset for that category. Verification: launching with --start-page=imageGen lands the renderer on Image Gen; --start-page=chat lands on Chat; missing or invalid values fall back to Chat without crashing. Signed-off-by: kyleriemensnider <kyle.riemensnider@gmail.com>
|
Warning Review limit reached
More reviews will be available in 45 minutes and 17 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughThe PR refactors initial page mode selection from deprecated AipgPage type to restricted ModeType values (chat, imageGen, imageEdit, video). Electron's IPC handler validates --start-page arguments, renderer startup concurrently initializes demo settings and fetches the validated mode, and remote debugging is simplified to enable based on environment variable alone. ChangesInitial Page Mode Selection and Debugging Configuration
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
WebUI/src/main.ts (1)
6-6: ⚡ Quick winUse the
@alias for this new store import.This new relative import is outside the WebUI import convention and will be more brittle under moves/renames.
Suggested change
-import { usePromptStore } from './assets/js/store/promptArea' +import { usePromptStore } from '`@/assets/js/store/promptArea`'As per coding guidelines,
WebUI/**/*.{ts,tsx,js,vue}:Use path alias @ → ./src and electron → ./electron in imports.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@WebUI/src/main.ts` at line 6, The import in main.ts is using a brittle relative path for the new store; replace the relative import of usePromptStore with the project path alias form (usePromptStore from '`@/assets/js/store/promptArea`') so it follows the WebUI import convention and remains stable under file moves/renames; update the import statement that currently references './assets/js/store/promptArea' to use the '@' alias and keep the same exported symbol usePromptStore.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@WebUI/electron/main.ts`:
- Around line 1010-1014: The getInitialPage IPC handler currently returns only a
ModeType and conflates three cases (no flag, invalid flag, explicit
--start-page=chat); change ipcMain.handle('getInitialPage') to return a
structured object (e.g., { success: boolean, mode?: ModeType, requested?:
boolean, error?: string }) that preserves whether the flag was provided and
whether it was valid; validate the parsed startPageArg, set requested = true
when the flag exists, set mode to the validated ModeType or leave undefined and
return success: false with an error message for invalid values, and update the
renderer and type definitions (ModeType contract in env.d.ts/main.ts) to consume
this new response and follow the { success, error? } IPC pattern.
In `@WebUI/src/main.ts`:
- Around line 8-11: Wrap the parallel IPC startup calls to
window.electronAPI.getDemoModeSettings() and window.electronAPI.getInitialPage()
(the const [settings, initialPage] = await Promise.all([...]) line) in a
try/catch so rejections won't abort module evaluation; on error console.error()
the caught error and assign safe fallback values for settings and initialPage
(e.g., defaults that allow the renderer to mount) before continuing so startup
remains recoverable.
---
Nitpick comments:
In `@WebUI/src/main.ts`:
- Line 6: The import in main.ts is using a brittle relative path for the new
store; replace the relative import of usePromptStore with the project path alias
form (usePromptStore from '`@/assets/js/store/promptArea`') so it follows the
WebUI import convention and remains stable under file moves/renames; update the
import statement that currently references './assets/js/store/promptArea' to use
the '@' alias and keep the same exported symbol usePromptStore.
🪄 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: defaults
Review profile: CHILL
Plan: Pro
Run ID: 1473c55e-d3b4-47c8-8dbd-e3c94f5ed52f
📒 Files selected for processing (3)
WebUI/electron/main.tsWebUI/src/env.d.tsWebUI/src/main.ts
| ipcMain.handle('getInitialPage', (): ModeType => { | ||
| const validModes: ModeType[] = ['chat', 'imageGen', 'imageEdit', 'video'] | ||
| const startPageArg = process.argv.find((arg) => arg.startsWith('--start-page=')) | ||
| return startPageArg ? startPageArg.split('=')[1] : 'create' | ||
| const parsed = startPageArg?.split('=')[1] | ||
| return validModes.includes(parsed as ModeType) ? (parsed as ModeType) : 'chat' |
There was a problem hiding this comment.
Preserve whether --start-page was actually requested.
This handler folds “no flag”, “invalid flag”, and explicit --start-page=chat into the same 'chat' value. The renderer now skips applying 'chat', so a persisted non-chat mode can survive even when the user explicitly asked for chat. Return a structured result that distinguishes those cases instead of a bare ModeType.
Suggested direction
- ipcMain.handle('getInitialPage', (): ModeType => {
- const validModes: ModeType[] = ['chat', 'imageGen', 'imageEdit', 'video']
- const startPageArg = process.argv.find((arg) => arg.startsWith('--start-page='))
- const parsed = startPageArg?.split('=')[1]
- return validModes.includes(parsed as ModeType) ? (parsed as ModeType) : 'chat'
- })
+ ipcMain.handle('getInitialPage', () => {
+ const validModes = new Set<ModeType>(['chat', 'imageGen', 'imageEdit', 'video'])
+ const startPageArg = process.argv.find((arg) => arg.startsWith('--start-page='))
+ const parsed = startPageArg?.split('=')[1]
+
+ if (!startPageArg) {
+ return { success: true, page: null }
+ }
+
+ if (parsed && validModes.has(parsed as ModeType)) {
+ return { success: true, page: parsed as ModeType }
+ }
+
+ return { success: false, page: 'chat', error: 'Invalid --start-page value' }
+ })WebUI/src/env.d.ts and WebUI/src/main.ts would need the matching contract update.
As per coding guidelines, WebUI/electron/main.ts: IPC handlers must return { success: boolean, error?: string } pattern for error propagation.
📝 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.
| ipcMain.handle('getInitialPage', (): ModeType => { | |
| const validModes: ModeType[] = ['chat', 'imageGen', 'imageEdit', 'video'] | |
| const startPageArg = process.argv.find((arg) => arg.startsWith('--start-page=')) | |
| return startPageArg ? startPageArg.split('=')[1] : 'create' | |
| const parsed = startPageArg?.split('=')[1] | |
| return validModes.includes(parsed as ModeType) ? (parsed as ModeType) : 'chat' | |
| ipcMain.handle('getInitialPage', () => { | |
| const validModes = new Set<ModeType>(['chat', 'imageGen', 'imageEdit', 'video']) | |
| const startPageArg = process.argv.find((arg) => arg.startsWith('--start-page=')) | |
| const parsed = startPageArg?.split('=')[1] | |
| if (!startPageArg) { | |
| return { success: true, page: null } | |
| } | |
| if (parsed && validModes.has(parsed as ModeType)) { | |
| return { success: true, page: parsed as ModeType } | |
| } | |
| return { success: false, page: 'chat', error: 'Invalid --start-page value' } | |
| }) |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@WebUI/electron/main.ts` around lines 1010 - 1014, The getInitialPage IPC
handler currently returns only a ModeType and conflates three cases (no flag,
invalid flag, explicit --start-page=chat); change
ipcMain.handle('getInitialPage') to return a structured object (e.g., { success:
boolean, mode?: ModeType, requested?: boolean, error?: string }) that preserves
whether the flag was provided and whether it was valid; validate the parsed
startPageArg, set requested = true when the flag exists, set mode to the
validated ModeType or leave undefined and return success: false with an error
message for invalid values, and update the renderer and type definitions
(ModeType contract in env.d.ts/main.ts) to consume this new response and follow
the { success, error? } IPC pattern.
| const [settings, initialPage] = await Promise.all([ | ||
| window.electronAPI.getDemoModeSettings(), | ||
| window.electronAPI.getInitialPage(), | ||
| ]) |
There was a problem hiding this comment.
Catch startup IPC failures and fall back to safe defaults.
If either IPC call rejects here, top-level module evaluation aborts and the renderer never mounts. This needs a try/catch with logging and fallback values so startup stays recoverable.
Suggested change
-const [settings, initialPage] = await Promise.all([
- window.electronAPI.getDemoModeSettings(),
- window.electronAPI.getInitialPage(),
-])
+let settings: DemoModeSettings = {
+ isDemoModeEnabled: false,
+ demoModeResetInSeconds: null,
+}
+let initialPage: ModeType | null = null
+
+try {
+ ;[settings, initialPage] = await Promise.all([
+ window.electronAPI.getDemoModeSettings(),
+ window.electronAPI.getInitialPage(),
+ ])
+} catch (error) {
+ console.error('Failed to load startup state', error)
+}As per coding guidelines, Wrap async operations in try/catch blocks and Log errors with console.error().
📝 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.
| const [settings, initialPage] = await Promise.all([ | |
| window.electronAPI.getDemoModeSettings(), | |
| window.electronAPI.getInitialPage(), | |
| ]) | |
| let settings: DemoModeSettings = { | |
| isDemoModeEnabled: false, | |
| demoModeResetInSeconds: null, | |
| } | |
| let initialPage: ModeType | null = null | |
| try { | |
| ;[settings, initialPage] = await Promise.all([ | |
| window.electronAPI.getDemoModeSettings(), | |
| window.electronAPI.getInitialPage(), | |
| ]) | |
| } catch (error) { | |
| console.error('Failed to load startup state', error) | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@WebUI/src/main.ts` around lines 8 - 11, Wrap the parallel IPC startup calls
to window.electronAPI.getDemoModeSettings() and
window.electronAPI.getInitialPage() (the const [settings, initialPage] = await
Promise.all([...]) line) in a try/catch so rejections won't abort module
evaluation; on error console.error() the caught error and assign safe fallback
values for settings and initialPage (e.g., defaults that allow the renderer to
mount) before continuing so startup remains recoverable.
…ge=chat Addresses CodeRabbit's review of 257bfec. The previous handler returned 'chat' for three distinct cases (no flag / invalid flag / explicit --start-page=chat). The renderer guard (`if (initialPage !== 'chat')`) then skipped applying the mode in all three. That was the intent for the "no flag" case — don't override the persisted mode for a normal user launch — but it also silently broke the explicit --start-page=chat case: after a previous imageGen session, launching with --start-page=chat would land on the persisted imageGen because chat was never applied. This change returns null when --start-page is absent, and the renderer applies whenever the value is non-null. Validated-mode and fallback paths are unchanged. - main process: return ModeType | null - env.d.ts: getInitialPage(): Promise<ModeType | null> - renderer entry: guard on null instead of comparing to 'chat' Signed-off-by: kyleriemensnider <kyle.riemensnider@gmail.com>
Summary
Two small patches for using AI Playground as a programmable demo target.
Coordinated with Markus via email on 2026-05-29.
feat(debug): enable AIPG_DEBUGGING_PORT in packaged buildsDrops the
!app.isPackagedguard around the existing env-var-gatedChrome DevTools Protocol port. The env var itself stays opt-in
(off by default), so packaged builds gain the existing dev capability
without changing the default security posture.
Use case: an external controller process (an automation runner)
needs a stable, packaged build to attach CDP and observe / steer the
renderer in production-shaped environments.
feat(launcher): rewire --start-page flag to land on requested modeThe
getInitialPageIPC handler was returning the legacyAipgPagevocabulary (
create | enhance | answer | learn-more), which no longermatches the renderer's
ModeType(chat | imageGen | imageEdit | video).The renderer never consumed the IPC result, so
--start-pagewaseffectively dead in v3.x.
--start-page=value againstModeType, return'chat'as the safe fallbackenv.d.ts: switchgetInitialPage's return type toPromise<ModeType>, drop the now-unusedAipgPagealiasawait getInitialPage()alongside theexisting
getDemoModeSettings()call, then route the result throughpromptStore.setCurrentMode()so the mode change also picks up thelast-used preset for that category
Test plan
npm run typecheckclean againsttng/devnpm run buildproduces a clean NSIS installer(
AI Playground-3.1.1-beta.exe, ~211MB)AIPG_DEBUGGING_PORT=9223exposes the DevTools port; confirmed via CDP
/json/version--start-page=imageGenlands the renderer on Image Gen;--start-page=chatlands on Chat — both verified visuallyagainst the installed
3.1.1-betabuildBoth commits are DCO sign-off compliant.
Summary by CodeRabbit
Release Notes
Bug Fixes
Improvements