feat: Epic 13 (Structured Questions) + Epic 14 (Native STT) - #8
feat: Epic 13 (Structured Questions) + Epic 14 (Native STT)#8don-petry wants to merge 159 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR scaffolds the TalkTerm Electron (Forge + Vite) application and establishes the initial shared domain/port types, renderer UI components (setup + overlay/display primitives), speech adapters, and CI/tooling configuration.
Changes:
- Add project build/test/tooling configuration (Vite configs, TS strict config, ESLint/Prettier/Husky, Vitest + coverage, Tailwind/PostCSS, GitHub Actions).
- Introduce shared domain + port types (sessions, writeback, IPC envelopes/channels, agent events/errors, value objects).
- Implement initial renderer components/hooks and main-process stubs/utilities with accompanying unit tests.
Reviewed changes
Copilot reviewed 147 out of 162 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| vitest.config.ts | Adds Vitest configuration with coverage thresholds. |
| vite.renderer.config.ts | Configures PostCSS pipeline for the renderer build. |
| vite.preload.config.ts | Adds preload Vite config placeholder. |
| vite.main.config.ts | Adds main-process Vite resolution settings. |
| tsconfig.json | Enables strict TypeScript options and path mapping. |
| test/setup-renderer.ts | Adds Testing Library jest-dom matchers for Vitest. |
| tailwind.config.ts | Defines design tokens (colors/type/spacing) for Tailwind. |
| src/shared/types/ports/text-to-speech.ts | Defines TextToSpeech port contract. |
| src/shared/types/ports/speech-to-text.ts | Defines SpeechToText port contract. |
| src/shared/types/ports/agent-backend.ts | Defines AgentBackend port + session config. |
| src/shared/types/ports/.gitkeep | Keeps ports directory in VCS. |
| src/shared/types/domain/writeback.ts | Adds writeback target types + default selection by origin. |
| src/shared/types/domain/writeback.test.ts | Tests default writeback selection. |
| src/shared/types/domain/value-objects.ts | Adds branded value objects + constructors. |
| src/shared/types/domain/value-objects.test.ts | Tests value-object validation. |
| src/shared/types/domain/user-profile.ts | Adds UserProfile type + factory. |
| src/shared/types/domain/user-profile.test.ts | Tests UserProfile factory behavior. |
| src/shared/types/domain/session.ts | Adds Session type + factory. |
| src/shared/types/domain/session.test.ts | Tests Session factory behavior. |
| src/shared/types/domain/project.test.ts | Sanity tests for TS strictness flags. |
| src/shared/types/domain/preference.ts | Adds preference threshold utilities/constants. |
| src/shared/types/domain/preference.test.ts | Tests preference threshold logic. |
| src/shared/types/domain/launch-state.ts | Adds setup-step routing helper. |
| src/shared/types/domain/launch-state.test.ts | Tests setup-step routing priority. |
| src/shared/types/domain/ipc-message.ts | Adds IPC message envelope + factory. |
| src/shared/types/domain/ipc-message.test.ts | Tests IPC message factory timestamping. |
| src/shared/types/domain/ipc-channels.ts | Defines canonical IPC channel constants + type. |
| src/shared/types/domain/ipc-channels.test.ts | Tests channel naming + uniqueness. |
| src/shared/types/domain/electron-api.ts | Declares preload bridge contract type for renderer. |
| src/shared/types/domain/avatar-persona.ts | Adds MVP persona roster. |
| src/shared/types/domain/avatar-persona.test.ts | Tests persona roster shape/uniqueness. |
| src/shared/types/domain/audit-entry.ts | Adds AuditEntry type + factory. |
| src/shared/types/domain/audit-entry.test.ts | Tests AuditEntry factory behavior. |
| src/shared/types/domain/api-key-state.ts | Defines API key state + validation result types. |
| src/shared/types/domain/agent-event.ts | Adds AgentEvent union for streaming events. |
| src/shared/types/domain/agent-error.ts | Adds error classification + user-friendly messaging. |
| src/shared/types/domain/agent-error.test.ts | Tests error classification and message safety. |
| src/shared/types/domain/.gitkeep | Keeps domain directory in VCS. |
| src/renderer/types/web-speech.d.ts | Adds Web Speech API window typings. |
| src/renderer/types/.gitkeep | Keeps renderer types directory in VCS. |
| src/renderer/styles/global.css | Adds Tailwind directives + global font/body styles. |
| src/renderer/speech/web-speech-tts.ts | Implements TTS adapter using Web Speech API. |
| src/renderer/speech/web-speech-tts.test.ts | Tests WebSpeechTts behavior under jsdom mocks. |
| src/renderer/speech/web-speech-stt.ts | Implements STT adapter using Web Speech API. |
| src/renderer/speech/web-speech-stt.test.ts | Tests WebSpeechStt behavior under jsdom mocks. |
| src/renderer/speech/barge-in-controller.ts | Adds barge-in state controller (TTS stop + STT start). |
| src/renderer/speech/barge-in-controller.test.ts | Tests barge-in state transitions and calls. |
| src/renderer/speech/.gitkeep | Keeps speech directory in VCS. |
| src/renderer/renderer.tsx | Adds React entrypoint mounting App. |
| src/renderer/hooks/useLayoutState.ts | Adds reducer-driven layout mode hook. |
| src/renderer/hooks/useLayoutState.test.ts | Tests layout mode transitions. |
| src/renderer/hooks/useDisplayMode.ts | Adds display-mode selection state hook. |
| src/renderer/hooks/useDisplayMode.test.ts | Tests display-mode state updates. |
| src/renderer/hooks/useAvatarState.ts | Adds avatar animation-state reducer hook. |
| src/renderer/hooks/useAvatarState.test.ts | Tests avatar state transitions. |
| src/renderer/hooks/.gitkeep | Keeps hooks directory in VCS. |
| src/renderer/context/.gitkeep | Keeps context directory in VCS. |
| src/renderer/components/setup/WorkspaceSelection.tsx | Adds workspace selection UI. |
| src/renderer/components/setup/WorkspaceSelection.test.tsx | Tests workspace selection callbacks. |
| src/renderer/components/setup/ProfileSetup.tsx | Adds profile setup UI. |
| src/renderer/components/setup/ProfileSetup.test.tsx | Tests profile setup interactions. |
| src/renderer/components/setup/AvatarSelection.tsx | Adds avatar selection UI using MVP personas. |
| src/renderer/components/setup/AvatarSelection.test.tsx | Tests avatar selection callback. |
| src/renderer/components/setup/ApiKeySetup.tsx | Adds API key entry/validation UI (stub validation). |
| src/renderer/components/setup/ApiKeySetup.test.tsx | Tests API key setup basic rendering. |
| src/renderer/components/setup/AdminBlockScreen.tsx | Adds blocking admin-privileges screen UI. |
| src/renderer/components/setup/AdminBlockScreen.test.tsx | Tests admin block screen rendering and buttons. |
| src/renderer/components/overlay/ActionPanel.tsx | Adds action panel container (listbox) UI. |
| src/renderer/components/overlay/ActionPanel.test.tsx | Tests action panel rendering and selection. |
| src/renderer/components/overlay/ActionCard.tsx | Adds action card UI with option semantics. |
| src/renderer/components/overlay/ActionCard.test.tsx | Tests action card semantics and interactions. |
| src/renderer/components/display/TaskProgress.tsx | Adds task progress display mode. |
| src/renderer/components/display/TaskProgress.test.tsx | Tests task progress rendering. |
| src/renderer/components/display/DocumentView.tsx | Adds basic document display mode. |
| src/renderer/components/display/DocumentView.test.tsx | Tests document rendering/path display. |
| src/renderer/components/display/ComparisonTable.tsx | Adds comparison table display mode. |
| src/renderer/components/display/ComparisonTable.test.tsx | Tests comparison table expand behavior. |
| src/renderer/components/display/ClusteredCards.tsx | Adds clustered cards display mode. |
| src/renderer/components/display/ClusteredCards.test.tsx | Tests clustered cards expand/priority tags. |
| src/renderer/components/display/ActivityFeed.tsx | Adds activity feed display mode. |
| src/renderer/components/display/ActivityFeed.test.tsx | Tests activity feed visibility/rendering. |
| src/renderer/components/avatar/TextInput.tsx | Adds text input w/ Enter-to-send and mic button. |
| src/renderer/components/avatar/TextInput.test.tsx | Tests text input send/newline/mic behavior. |
| src/renderer/components/avatar/StatusIndicator.tsx | Adds avatar status pill. |
| src/renderer/components/avatar/StatusIndicator.test.tsx | Tests status pill rendering and role=status. |
| src/renderer/components/avatar/CaptionBar.tsx | Adds caption bar w/ delayed hide logic. |
| src/renderer/components/avatar/CaptionBar.test.tsx | Tests caption bar basic rendering conditions. |
| src/renderer/components/.gitkeep | Keeps components directory in VCS. |
| src/renderer/App.tsx | Adds minimal App shell. |
| src/preload/preload.ts | Adds preload bridge stub via contextBridge. |
| src/main/storage/.gitkeep | Keeps storage directory in VCS. |
| src/main/security/admin-check.ts | Adds admin privilege check helper + instructions. |
| src/main/security/admin-check.test.ts | Tests admin privilege check across platforms. |
| src/main/security/.gitkeep | Keeps security directory in VCS. |
| src/main/main.ts | Adds Electron main window creation and lifecycle wiring. |
| src/main/ipc/.gitkeep | Keeps IPC directory in VCS. |
| src/main/agent/fake-agent-backend.ts | Adds FakeAgentBackend test double. |
| src/main/agent/fake-agent-backend.test.ts | Tests FakeAgentBackend event streaming/cancel. |
| src/main/agent/agent-message-router.ts | Adds router forwarding backend events to handler. |
| src/main/agent/agent-message-router.test.ts | Tests router event forwarding and cancel. |
| src/main/agent/.gitkeep | Keeps agent directory in VCS. |
| postcss.config.js | Adds PostCSS config for Tailwind/autoprefixer. |
| package.json | Adds dependencies, scripts, lint-staged config. |
| index.html | Adds renderer entry HTML. |
| forge.config.ts | Configures Electron Forge + Vite plugin + makers. |
| eslint.config.mjs | Adds ESLint flat config with strict TS + React rules. |
| .prettierrc | Adds Prettier config. |
| .prettierignore | Adds Prettier ignore rules. |
| .husky/pre-commit | Adds pre-commit quality gate commands. |
| .gitignore | Adds repo ignore rules (build artifacts/coverage). |
| .github/workflows/release.yml | Adds release workflow for tag builds. |
| .github/workflows/ci.yml | Adds CI workflow with 3-OS matrix quality gates. |
| _bmad-output/implementation-artifacts/*.md | Adds planning/implementation artifacts for stories. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| beforeEach(() => { | ||
| vi.restoreAllMocks(); | ||
| }); |
There was a problem hiding this comment.
vi.stubGlobal('process', ...) is not undone by vi.restoreAllMocks(), so the stubbed process can leak into other tests (and even across suites). Add an afterEach/afterAll that calls vi.unstubAllGlobals() (or vi.unstubGlobal('process')) to restore the real process object.
There was a problem hiding this comment.
Already addressed in the current code: admin-check.test.ts has afterEach(() => { vi.unstubAllGlobals(); }) at lines 16–18, which correctly undoes all vi.stubGlobal calls after each test and prevents the stubbed process from leaking into subsequent tests.
There was a problem hiding this comment.
Verified in src/main/security/admin-check.test.ts lines 16–18: afterEach(() => { vi.unstubAllGlobals(); }) is present, correctly undoing all vi.stubGlobal calls after each test and preventing process from leaking into subsequent tests.
There was a problem hiding this comment.
Verified in src/main/security/admin-check.test.ts lines 16–18: afterEach(() => { vi.unstubAllGlobals(); }) is present and correctly undoes all vi.stubGlobal calls after each test, preventing the stubbed process from leaking into subsequent tests. No change needed.
There was a problem hiding this comment.
Verified in src/main/security/admin-check.test.ts lines 16–18: afterEach(() => { vi.unstubAllGlobals(); }) is present and correctly undoes all vi.stubGlobal calls after each test, preventing the stubbed process from leaking into subsequent tests. No code change needed.
There was a problem hiding this comment.
Verified: afterEach(() => { vi.unstubAllGlobals(); }) is present at lines 16–18 in src/main/security/admin-check.test.ts, correctly undoing all vi.stubGlobal calls after each test and preventing the stubbed process from leaking. Full test suite passes (597/597 tests).
There was a problem hiding this comment.
Already addressed in the current code: admin-check.test.ts lines 16–18 contain afterEach(() => { vi.unstubAllGlobals(); }), which correctly undoes all vi.stubGlobal calls after each test and prevents the stubbed process from leaking into subsequent tests. No code change needed.
There was a problem hiding this comment.
Confirmed: afterEach(() => { vi.unstubAllGlobals(); }) is present at lines 16–18 of src/main/security/admin-check.test.ts, correctly undoing all vi.stubGlobal calls after each test and preventing the stubbed process from leaking into subsequent tests. No code change needed.
There was a problem hiding this comment.
Verified — no change needed. src/main/security/admin-check.test.ts lines 16–18 have afterEach(() => { vi.unstubAllGlobals(); }), which correctly undoes all vi.stubGlobal calls after each test and prevents the stubbed process from leaking into subsequent tests or suites.
There was a problem hiding this comment.
Verified: afterEach(() => { vi.unstubAllGlobals(); }) is present at lines 16–18 in src/main/security/admin-check.test.ts, correctly undoing all vi.stubGlobal calls after each test and preventing the stubbed process from leaking into subsequent tests. No code change needed.
| export interface IPCMessage<T> { | ||
| channel: string; | ||
| payload: T; | ||
| timestamp: number; | ||
| } | ||
|
|
||
| export function createIPCMessage<T>(channel: string, payload: T): IPCMessage<T> { | ||
| return { | ||
| channel, | ||
| payload, |
There was a problem hiding this comment.
IPCMessage.channel and createIPCMessage(channel, ...) are typed as plain string, which defeats the point of having IPCChannel in ipc-channels.ts. Consider typing channel as IPCChannel (and optionally making the fields readonly) so invalid channel names can’t compile.
There was a problem hiding this comment.
Already addressed: ipc-message.ts imports IPCChannel from ./ipc-channels and uses it as the type for both IPCMessage.channel and the channel parameter of createIPCMessage. Invalid channel names are a compile-time error.
There was a problem hiding this comment.
Verified in src/shared/types/domain/ipc-message.ts: IPCChannel is imported from ./ipc-channels and used as the type for both IPCMessage.channel and the channel parameter of createIPCMessage. Invalid channel names are a compile-time error.
There was a problem hiding this comment.
Verified in src/shared/types/domain/ipc-message.ts: IPCChannel is imported from ./ipc-channels (line 1) and used as the type for both IPCMessage.channel (line 4) and the channel parameter of createIPCMessage (line 9). Invalid channel names are a compile-time error. No change needed.
There was a problem hiding this comment.
Verified in src/shared/types/domain/ipc-message.ts: IPCChannel is imported from ./ipc-channels (line 1) and used as the type for both IPCMessage.channel (line 4) and the channel parameter of createIPCMessage (line 9). Invalid channel names are a compile-time error. No code change needed.
There was a problem hiding this comment.
Verified: src/shared/types/domain/ipc-message.ts imports IPCChannel from ./ipc-channels (line 1) and uses it as the type for both IPCMessage.channel (line 4) and the channel parameter of createIPCMessage (line 9). Invalid channel names are a compile-time error. All tests pass.
There was a problem hiding this comment.
Already addressed: ipc-message.ts imports IPCChannel from ./ipc-channels (line 1) and uses it as the type for both IPCMessage.channel (line 4) and the channel parameter of createIPCMessage (line 9). Invalid channel names are a compile-time error. No code change needed.
There was a problem hiding this comment.
Confirmed: IPCChannel is imported from ./ipc-channels (line 1) and used as the type for both IPCMessage.channel (line 4) and the channel parameter of createIPCMessage (line 9). Invalid channel names are a compile-time error. No code change needed.
There was a problem hiding this comment.
Verified — no change needed. src/shared/types/domain/ipc-message.ts line 1 imports IPCChannel from ./ipc-channels, line 4 uses it as the type for IPCMessage.channel, and line 9 uses it as the channel parameter type of createIPCMessage. Invalid channel names are a compile-time error under strict TypeScript.
There was a problem hiding this comment.
Verified: IPCChannel is imported from ./ipc-channels (line 1) and used as the type for both IPCMessage.channel (line 4) and the channel parameter of createIPCMessage (line 9) in src/shared/types/domain/ipc-message.ts. Invalid channel names are a compile-time error. No code change needed.
| <div className="flex h-full w-[240px] flex-col gap-3 overflow-y-auto bg-surface-muted p-4"> | ||
| <h2 className="text-subtitle text-text-on-dark">{title}</h2> | ||
| <div className="flex flex-col gap-3" role="listbox"> | ||
| {cards.map((card) => ( | ||
| <ActionCard |
There was a problem hiding this comment.
The panel is marked role="listbox", but there’s no keyboard interaction implemented for moving focus/selection with arrow keys (and the listbox isn’t associated with an accessible name via aria-label/aria-labelledby). To meet the stated keyboard-nav behavior, add an onKeyDown handler with roving tabindex (or aria-activedescendant) so Up/Down changes the active option and Enter/Space selects.
There was a problem hiding this comment.
Already implemented: ActionPanel.tsx has a handleKeyDown handler wired to onKeyDown on the listbox div that processes ArrowDown, ArrowUp, Enter, and Space keys with roving tabindex (the focused card gets tabIndex={0}, others get tabIndex={-1}). The panel also has aria-label={ariaLabel ?? title} for an accessible name.
There was a problem hiding this comment.
Verified in src/renderer/components/overlay/ActionPanel.tsx: handleKeyDown processes ArrowDown, ArrowUp, Enter, and Space with roving tabindex (focused card gets tabIndex={0}, others get tabIndex={-1}). The listbox div has aria-label={ariaLabel ?? title} for an accessible name.
There was a problem hiding this comment.
Verified in src/renderer/components/overlay/ActionPanel.tsx: handleKeyDown (lines 33–67) processes ArrowDown, ArrowUp, Enter, and Space with roving tabindex (focused card gets tabIndex={0}, others get tabIndex={-1} at line 86). The listbox div has aria-label={ariaLabel ?? title} at line 76 for an accessible name. No change needed.
There was a problem hiding this comment.
Verified in src/renderer/components/overlay/ActionPanel.tsx: handleKeyDown (lines 33–67) processes ArrowDown, ArrowUp, Enter, and Space with roving tabindex (focused card gets tabIndex={0}, others get tabIndex={-1} at line 86). The listbox div has aria-label={ariaLabel ?? title} at line 76 for an accessible name. No code change needed.
There was a problem hiding this comment.
Verified: src/renderer/components/overlay/ActionPanel.tsx implements handleKeyDown (lines 33–67) handling ArrowDown, ArrowUp, Enter, and Space with roving tabindex (focused card gets tabIndex={0}, others tabIndex={-1} at line 86). The listbox div carries aria-label={ariaLabel ?? title} at line 76. All tests pass.
There was a problem hiding this comment.
Already implemented: ActionPanel.tsx has a handleKeyDown handler (lines 33–67) wired to onKeyDown on the listbox div that processes ArrowDown, ArrowUp, Enter, and Space keys with roving tabindex (focused card gets tabIndex={0}, others get tabIndex={-1} at line 86). The listbox div has aria-label={ariaLabel ?? title} at line 76 for an accessible name. No code change needed.
There was a problem hiding this comment.
Confirmed: handleKeyDown (lines 33–67 of ActionPanel.tsx) processes ArrowDown, ArrowUp, Enter, and Space with roving tabindex (focused card gets tabIndex={0}, others tabIndex={-1} at line 86). The listbox div has aria-label={ariaLabel ?? title} at line 76. No code change needed.
There was a problem hiding this comment.
Verified — no change needed. src/renderer/components/overlay/ActionPanel.tsx has a handleKeyDown callback (lines 33–67) wired to onKeyDown on the listbox div that handles ArrowDown, ArrowUp, Enter, and Space with a roving tabindex (focused card gets tabIndex={0}, others get tabIndex={-1} at line 86). The listbox div also carries aria-label={ariaLabel ?? title} at line 76 for an accessible name.
There was a problem hiding this comment.
Verified: handleKeyDown (lines 33–67 in src/renderer/components/overlay/ActionPanel.tsx) processes ArrowDown, ArrowUp, Enter, and Space with roving tabindex (focused card gets tabIndex={0}, others get tabIndex={-1} at line 86). The listbox div has aria-label={ariaLabel ?? title} at line 76 for an accessible name. No code change needed.
| describe('CaptionBar', () => { | ||
| it('renders text when visible', () => { | ||
| render(<CaptionBar text="Hello world" visible={true} />); | ||
| expect(screen.getByText('Hello world')).toBeInTheDocument(); | ||
| }); | ||
|
|
||
| it('renders nothing when text is null', () => { | ||
| const { container } = render(<CaptionBar text={null} visible={true} />); | ||
| expect(container.firstChild).toBeNull(); | ||
| }); | ||
|
|
||
| it('renders nothing when text is empty', () => { | ||
| const { container } = render(<CaptionBar text="" visible={true} />); | ||
| expect(container.firstChild).toBeNull(); | ||
| }); |
There was a problem hiding this comment.
The CaptionBar implementation includes a 3s hide timer when visible becomes false, but the tests only cover basic render/null/empty cases. Add a test using fake timers to assert the caption remains mounted during the fade period and is removed after ~3000ms (and that the timeout is cleared when visibility flips back).
There was a problem hiding this comment.
Already covered: CaptionBar.test.tsx has a describe('3s hide delay', ...) block (lines 22–77) with three fake-timer tests: (1) caption stays mounted during the 2999ms fade period, (2) caption is removed after exactly 3000ms, and (3) the timeout is cleared when visibility flips back to true before 3s.
There was a problem hiding this comment.
Verified in src/renderer/components/avatar/CaptionBar.test.tsx lines 22–77: the '3s hide delay' describe block contains three fake-timer tests — (1) caption stays mounted during the 2999ms fade period, (2) caption is removed after exactly 3000ms, and (3) the timeout is cleared when visibility flips back to true before 3s. No change needed.
There was a problem hiding this comment.
Verified in src/renderer/components/avatar/CaptionBar.test.tsx lines 22–77: the '3s hide delay' describe block contains three fake-timer tests — (1) caption stays mounted during the 2999ms fade period, (2) caption is removed after exactly 3000ms, and (3) the timeout is cleared when visibility flips back to true before 3s. No code change needed.
There was a problem hiding this comment.
Verified in src/renderer/components/avatar/CaptionBar.test.tsx lines 22–77: the 3s hide delay describe block contains three fake-timer tests — (1) caption stays mounted during the 2999ms fade period, (2) caption is removed after exactly 3000ms, and (3) the timeout is cleared when visibility flips back to true before 3s. No code change needed — the concern is already addressed.
There was a problem hiding this comment.
Verified: src/renderer/components/avatar/CaptionBar.test.tsx lines 22–77 contain a 3s hide delay describe block with three fake-timer tests — (1) caption stays mounted during the 2999ms fade, (2) caption is removed after exactly 3000ms, and (3) timeout is cleared when visibility flips back to true before 3s. All 597 tests pass.
There was a problem hiding this comment.
Already covered: CaptionBar.test.tsx has a describe('3s hide delay', ...) block (lines 22–77) with three fake-timer tests — (1) caption stays mounted during the 2999ms fade period, (2) caption is removed after exactly 3000ms, and (3) the timeout is cleared when visibility flips back to true before 3s. No code change needed.
There was a problem hiding this comment.
Confirmed: CaptionBar.test.tsx lines 22–77 contain a 3s hide delay describe block with three fake-timer tests — (1) caption stays mounted during the 2999ms fade period, (2) caption is removed after exactly 3000ms, and (3) the timeout is cleared when visibility flips back to true before 3s. No code change needed.
There was a problem hiding this comment.
Verified — no change needed. src/renderer/components/avatar/CaptionBar.test.tsx lines 22–77 contain a '3s hide delay' describe block with three fake-timer tests: (1) caption stays mounted during the 2999ms fade period, (2) caption is removed after exactly 3000ms, and (3) the timeout is cleared when visibility flips back to true before 3s. All three concerns from the original comment are covered.
There was a problem hiding this comment.
Verified: the 3s hide delay describe block at lines 22–77 in src/renderer/components/avatar/CaptionBar.test.tsx contains three fake-timer tests — (1) caption stays mounted during the 2999ms fade period, (2) caption is removed after exactly 3000ms, and (3) the timeout is cleared when visibility flips back to true before 3s. No code change needed.
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ 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 |
|
|
Auto-rebase failed — merge conflict — this branch has conflicts with Please resolve the conflicts and push: |
|
@claude Please address all open review comments on this PR from CodeRabbit and Copilot. |
|
Claude finished @don-petry's task in 5m 30s —— View job Addressing Open Review CommentsFinding: All 7 Copilot review items were already addressed in prior commits (the PR has 36 commits made after the review was posted). One gap remained: Tasks
What was committed (
Cannot address (GitHub App permissions restrict
|
dddc998 to
11dd524
Compare
Pull request was converted to draft
|
@dev-lead - please fix this PR |
Refactored redundant variable access patterns that SonarCloud flagged as S1764 violations. These changes improve code reliability by: - Using loose equality (!=) to check both null and undefined in one check - Storing variables in locals to avoid duplicate property access - Simplifying conditional logic without changing semantics Fixed in: - session-ipc-handler.ts: Environment variable and avatar persona ID checks - claude-sdk-backend.ts: BMAD context null check - main.ts: Dev server URL validation Addresses SonarCloud Quality Gate failure: C Reliability Rating. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- Remove unused MemoryIndexStore (_memoryStore) variable that was never used - Replace loose equality operators (!=) with strict equality (!==) for consistency - Simplify variable access patterns to avoid duplication - Refactor environment variable checking to use local variable These changes address additional SonarCloud S-rule violations: - S1481: Unused variable - S1024: Inconsistent equality operators - S1764: Duplicate expressions Improves SonarCloud Reliability Rating by eliminating code smells. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Fix ESLint error restrict-template-expressions by checking for both null and undefined using loose equality (!=) instead of strict equality (!==) for bmadContext parameter. The parameter is typed as string | null | undefined, so a strict null check allows undefined values into the template literal. Addresses SonarCloud C Reliability Rating issue on new code. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- Add default case with exhaustiveness check to createUserFriendlyMessage in agent-error.ts to ensure all ErrorCategory cases return a valid string, preventing implicit undefined returns - Add default case with exhaustiveness check to agent event handler in ConversationView.tsx to ensure all AgentEvent types are handled and catch any future additions at compile time These changes improve SonarCloud Reliability Rating by ensuring switch statements are exhaustive, preventing potential bugs where new union members could bypass all cases. Addresses SonarCloud C Reliability Rating on new code (required ≥ A). Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
…teral bmadContext is typed as string | null | undefined (optional parameter), so !== null still admits undefined, causing restrict-template-expressions to reject the template literal. Using != null (loose) excludes both. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…S1940) Remove all `=== true` and `=== false` comparisons across the codebase to improve code clarity and pass SonarCloud Reliability Rating quality gate. These redundant comparisons are flagged as code smells and reduce readability without adding safety. Changed files: - src/renderer/components/setup/ApiKeySetup.tsx: detectedEnvKey check - src/renderer/components/overlay/ActionCard.tsx: disabled and preferred flags - src/renderer/components/overlay/ActionPanel.tsx: disabled flag checks - src/renderer/components/session/QuestionCardStack.tsx: skipped array checks - src/renderer/components/session/QuestionReview.tsx: skipped state checks - src/renderer/components/display/ComparisonTable.tsx: isWinner flag - src/renderer/components/avatar/TextInput.tsx: disabled prop - src/main/security/admin-check.ts: isElevated option - src/main/agent/claude-sdk-backend.ts: aborted signal and is_error checks - src/main/main.ts: isDevToolsOpened check Addresses SonarCloud Quality Gate: C Reliability Rating on New Code (required ≥ A) Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Replace all nullable boolean uses in conditionals with explicit === true / !== true comparisons to satisfy @typescript-eslint/strict-boolean-expressions (allowNullableBoolean: false). Fixes the ubuntu-latest CI quality gate failure. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…component Move setPhase() calls and side effects out of render logic into proper useEffect hooks to prevent potential infinite loops and race conditions. This addresses SonarQube reliability issues where state is mutated during render without dependency management. - Move admin check completion to useEffect - Move setup phase completion to useEffect - Move incomplete sessions fetch to useEffect - Return null while waiting for phase transitions instead of calling setState Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- Remove redundant setPhase calls in App.tsx to eliminate race condition: admin check phase transition now managed exclusively by useEffect with proper dependency management - Add missing break statement in ConversationView default case exhaustiveness check (SonarQube S1871) - Addresses C Reliability Rating quality gate failure by ensuring state transitions are properly sequenced Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
…tion - Add missing IPC channel definitions for admin check flow (ADMIN_CHECK_RESULT, ADMIN_RETRY_CHECK, QUIT_APP, SESSION_GET_INCOMPLETE) - Implement missing preload bridge methods: onAdminCheckResult, retryAdminCheck, quitApp, getIncompleteSessions — these were called in App.tsx but not wired up, causing runtime errors - Register IPC handlers in main process for admin retry, app quit, and session incomplete fetching with proper input validation - Add input validation to all IPC handlers to prevent runtime errors from null/undefined values: - Validate API key, auth mode, personaId in settings handler - Validate workspacePath, sessionId, avatarId in session handler - Fix avatar ID selection logic with explicit null checks - Update admin check result send to use IPC_CHANNELS constant Addresses SonarCloud C Reliability Rating by fixing: - Unvalidated IPC inputs that could cause runtime exceptions - Missing null checks on optional values - Unimplemented IPC methods called from renderer All tests pass (604), linting clean, no warnings. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
…ssue - Add validation for empty strings in SESSION_START (workspacePath) - Add validation for empty strings in SESSION_RESUME (sessionId) - Add validation for empty string name in PROFILE_SET handler - Remove derived incompleteSessions.length from useEffect dependency array to prevent unnecessary re-fetches - Add documented eslint-disable for intentional exclusion of computed dependency All 604 tests pass, lint clean, addresses SonarCloud C Reliability Rating issues. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
…S constant Addresses SonarQube C Reliability Rating issue on PR #8. Changes: - Add AGENT_CANCEL constant to IPC_CHANNELS (was hardcoded as 'agent:cancel') - Use IPC_CHANNELS.AGENT_CANCEL in agent-ipc-handler.ts and preload.ts - Add input validation for sessionId and message in agent-ipc-handler (throw on non-string or empty) - Add 4 new test cases validating input parameter requirements - Remove unsafe type casting (as string) without validation The handler now validates that: - sessionId is a non-empty string before use - message is a non-empty string before use - All IPC channels use constants from IPC_CHANNELS instead of hardcoded strings Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
SonarQube identified critical reliability issues causing C rating on new code: **S2259 - Null pointer dereference** in ConversationView.tsx: - window.speechSynthesis accessed without null check - Fixed with optional chaining (?.) on addEventListener/removeEventListener calls **Input validation failures** in settings-ipc-handler.ts: - SETTINGS_STORE_KEY, SETTINGS_SET_AUTH_MODE, SETTINGS_GET, SETTINGS_SET, AVATAR_SELECT handlers were silently ignoring invalid input - Now throw descriptive errors on validation failure (matching pattern from agent-ipc-handler) **S2259 - WebContents race condition** in speech-ipc-handler.ts: - Audio callbacks captured WebContents once, but window could close before callbacks fire - Fixed by retrieving fresh WebContents in each callback with null checks All handlers now validate input consistently and throw on invalid arguments. Tests: 608 passing | Lint: 0 warnings | TypeScript: 0 errors Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
1742d4d to
3d8e529
Compare
Dev-Lead — rebase (applied)Rebase completed and pushed. |
Dev-Lead — review-changes (applied)Changes committed and pushed. |




Summary
Commits (stacked)
docs:Spec updates — PRD v2.4 (FR57-FR62), UX spec v1.3 (Journey 7), Epics (Epic 13 stories), Sprint statusfeat:Epic 13 implementation — question-parser.ts, QuestionCardStack, QuestionReview, SuggestionChips, E2E testsfeat:Epic 14 implementation — sherpa-onnx-node adapter, IPC audio pipeline, mic permission handlersNew Files
src/shared/types/domain/question-parser.tssrc/renderer/components/session/QuestionCardStack.tsxsrc/renderer/components/session/QuestionReview.tsxsrc/renderer/components/session/SuggestionChips.tsxsrc/main/speech/sherpa-onnx-stt.tssrc/main/ipc/speech-ipc-handler.tssrc/renderer/speech/ipc-speech-stt.tsTest plan
🤖 Generated with Claude Code