Conversation
…with different screens, adding consistency to elements and consolidating as many as possible first round
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
v0.0.7 release candidate
…e, and consistent button alignment. Enhance QR modal with better status feedback and fix 'Try Again' loading state.
…not be using bfcred yet
Feature/qr scanning and pings
bugfix/recovery-forms
…ecode dropdown on signer
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In @src/components/AddShare.tsx:
- Around line 395-415: The IPC call to window.electronAPI.computeRelayPlan is
passing explicitRelays: null and envRelay: null which will fail
RelayPlanArgsSchema validation because the schema uses .optional() (accepts
undefined/omission, not null); change the AddShare.tsx call to pass undefined
(or omit the keys) for explicitRelays and envRelay so the payload conforms to
RelayPlanArgsSchema, or alternatively update RelayPlanArgsSchema to use
.nullable()/.nullish() if you intend to accept nulls—prefer the AddShare.tsx
change to undefined to minimize schema changes.
In @src/main.ts:
- Around line 116-127: The unquoted Unix path regex in function
sanitizeErrorForLog incorrectly excludes spaces; update the pattern used in
sanitizeErrorForLog from /\/(?:[^\/\s:]+\/)+([^\/\s:]+)/g to a pattern that
allows spaces in path segments (for example /\/(?:[^\/\s]+\/)+([^\/\s]+)/g) so
that "/path/with spaces/file.txt" is fully replaced to "<path>/file.txt"; after
changing the regex, run and add unit tests exercising sanitizeErrorForLog with
unquoted Unix paths that include spaces to verify the behavior.
🧹 Nitpick comments (9)
index.html (1)
5-27: Strong CSP implementation with well-documented trade-offs.The Content-Security-Policy provides robust protection for an Electron application:
✓ Strong protections:
script-src 'self'blocks inline scripts and evalobject-src 'none'prevents plugin executionframe-ancestors 'none'prevents clickjacking- Blocks insecure
ws://connections✓ Necessary allowances (well-documented):
style-src 'unsafe-inline'required for Tailwind CSS (lower risk than script injection)connect-src wss:wildcard required for user-configured nostr relays (intentionally blocks non-TLSws://)The comments clearly explain the rationale for each allowance, making the security trade-offs transparent.
Optional future hardening: If relay URLs become available at initialization time, consider implementing a dynamic CSP or validating relay URLs to further restrict the
wss:wildcard.src/__tests__/integration/computeRelayPlan.test.ts (1)
14-68: Useful static analysis tests for IPC contract verification.The static analysis approach verifies the IPC handler structure without executing it, providing early detection of:
- Missing handler registration
- Schema definition changes
- Env var fallback logic
- Input normalization patterns
However, these tests may be brittle to code refactoring (e.g., variable renaming, code reorganization) while the actual behavior remains correct.
Consider complementing static analysis with a unit test for the actual
computeRelayPlanlogic inechoRelays.tsto ensure the behavior is tested independently of code structure.src/__tests__/components/Recover.test.tsx (1)
426-435: Consider making masked character count assertion more flexible.The assertion
expect(screen.getByText(/•{40}/))assumes exactly 40 masking characters. If the NSEC length varies or the masking logic changes, this test will fail. Consider a more flexible pattern like/•{10,}/or deriving the expected count from the NSEC length.♻️ Suggested change
- expect(screen.getByText(/•{40}/)).toBeInTheDocument(); + // Verify masking dots are present (flexible count) + expect(screen.getByText(/•{10,}/)).toBeInTheDocument();src/main.ts (2)
267-288: Consider extracting URL canonicalization to a shared utility.The
relayTargetKeyfunction duplicates logic fromdedupeKeyinsrc/lib/echoRelays.ts. Consider importing and reusing the shared implementation for consistency.
496-565: Consider adding timeout for echo listener startup.The
startEchoMonitorcall could hang if relay connections stall. Consider wrapping with a timeout to prevent indefinite blocking.♻️ Suggested timeout wrapper
+const ECHO_START_TIMEOUT_MS = 30000; + try { - const listener = await startEchoMonitor(groupCredential, normalizedShares, (shareIndex, shareCredential, challenge) => { + const listenerPromise = startEchoMonitor(groupCredential, normalizedShares, (shareIndex, shareCredential, challenge) => { if (!event.sender.isDestroyed()) { event.sender.send('echo-received', { listenerId, shareIndex, shareCredential, challenge: challenge ?? null, }); } }); + + const timeoutPromise = new Promise<never>((_, reject) => + setTimeout(() => reject(new Error('Echo listener startup timed out')), ECHO_START_TIMEOUT_MS) + ); + + const listener = await Promise.race([listenerPromise, timeoutPromise]);src/components/AddShare.tsx (1)
125-154: Good validation with centralized limits, but consider using validateShareName utility.The
evaluateShareNamefunction implements name validation inline. The codebase now hasvalidateShareNameinsrc/lib/validation.tsthat provides similar functionality with normalization. Consider using the shared utility for consistency.src/__tests__/integration/electron-security.test.ts (1)
82-86: Regex may be overly strict for ipcRenderer exposure check.The pattern
exposeInMainWorld\([^)]*ipcRenderer[^)]*\)checks for raw ipcRenderer exposure but may not catch all patterns. Consider also checking for patterns likeipcRenderer.sendoripcRenderer.invokebeing directly exposed.src/lib/validation.ts (1)
127-153: Comprehensive SSRF protection for private IP ranges.The function correctly blocks:
- RFC 1918 private ranges (10.x, 172.16-31.x, 192.168.x)
- Loopback (127.x)
- Link-local (169.254.x)
- Reserved (0.x)
Consider also blocking:
- Broadcast (255.255.255.255)
- Multicast (224.0.0.0 - 239.255.255.255)
♻️ Extended SSRF protection
// Reserved if (parts[0] === 0) return true; // 0.0.0.0/8 + // Broadcast + if (parts[0] === 255 && parts[1] === 255 && parts[2] === 255 && parts[3] === 255) return true; + + // Multicast (Class D) + if (parts[0] >= 224 && parts[0] <= 239) return true; // 224.0.0.0/4 + return false;src/components/Recover.tsx (1)
758-805: Inconsistent indentation in button layout.The nested button elements have inconsistent indentation which affects readability. The second and third buttons inside the
flex gap-2container should align with the first button.🔧 Suggested fix for indentation
<div className="flex gap-2"> <Button type="button" onClick={handleCopyNsec} className={`flex-1 text-sm ${copyError ? 'bg-red-600 hover:bg-red-700' : 'bg-blue-600 hover:bg-blue-700'}`} > {isNsecCopied ? ( <> <Check className="w-4 h-4 mr-2" /> Copied! </> ) : ( <> <Copy className="w-4 h-4 mr-2" /> Copy to Clipboard </> )} </Button> - <Button - type="button" - onClick={handleToggleNsecReveal} - variant="outline" - className="bg-gray-700 hover:bg-gray-600 border-gray-600 text-sm" - > - {isNsecRevealed ? ( - <> - <EyeOff className="w-4 h-4 mr-2" /> - Hide - </> - ) : ( - <> - <Eye className="w-4 h-4 mr-2" /> - Reveal - </> - )} - </Button> - - <Button - type="button" - onClick={clearRecoveredNsec} - variant="outline" - className="bg-red-900/30 hover:bg-red-800/50 border-red-700/50 text-red-300 text-sm" - > - Clear - </Button> + <Button + type="button" + onClick={handleToggleNsecReveal} + variant="outline" + className="bg-gray-700 hover:bg-gray-600 border-gray-600 text-sm" + > + {isNsecRevealed ? ( + <> + <EyeOff className="w-4 h-4 mr-2" /> + Hide + </> + ) : ( + <> + <Eye className="w-4 h-4 mr-2" /> + Reveal + </> + )} + </Button> + + <Button + type="button" + onClick={clearRecoveredNsec} + variant="outline" + className="bg-red-900/30 hover:bg-red-800/50 border-red-700/50 text-red-300 text-sm" + > + Clear + </Button> </div>
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (37)
CLAUDE.mdSECURITY_AUDIT_2026-01-06.mdindex.htmlpackage.jsonsrc/__tests__/__mocks__/bifrost.mock.tssrc/__tests__/components/AddShare.test.tsxsrc/__tests__/components/LoadShare.test.tsxsrc/__tests__/components/Recover.test.tsxsrc/__tests__/components/SaveShare.test.tsxsrc/__tests__/components/Signer.test.tsxsrc/__tests__/integration/clientShareManager.test.tssrc/__tests__/integration/computeRelayPlan.test.tssrc/__tests__/integration/electron-security.test.tssrc/__tests__/integration/userInputValidation.test.tssrc/__tests__/lib/echoRelays.test.tssrc/__tests__/lib/igloo-core-integration.test.tssrc/__tests__/lib/shareManager.test.tssrc/__tests__/lib/validation.test.tssrc/__tests__/setup.tssrc/__tests__/workflows/keyset-creation.test.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/components/AddShare.tsxsrc/components/Create.tsxsrc/components/Keyset.tsxsrc/components/LoadShare.tsxsrc/components/Recover.tsxsrc/components/SaveShare.tsxsrc/components/Signer.tsxsrc/lib/clientShareManager.tssrc/lib/echoRelays.tssrc/lib/shareManager.tssrc/lib/validation.tssrc/main.tssrc/preload.tstsconfig.preload.jsontsconfig.test.jsonwebpack.config.cjs
🧰 Additional context used
📓 Path-based instructions (17)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Use strict TypeScript mode with explicit types for function parameters and returns
Prefer interfaces over types for defining object shapes in TypeScript
Use @/ path alias for imports instead of relative paths
Use camelCase for functions and variables
Use UPPER_SNAKE_CASE for constants
Files:
src/lib/clientShareManager.tssrc/lib/shareManager.tssrc/__tests__/components/AddShare.test.tsxsrc/components/Signer.tsxsrc/lib/echoRelays.tssrc/__tests__/lib/shareManager.test.tssrc/__tests__/integration/userInputValidation.test.tssrc/__tests__/components/Recover.test.tsxsrc/__tests__/components/LoadShare.test.tsxsrc/components/Create.tsxsrc/__tests__/__mocks__/bifrost.mock.tssrc/__tests__/integration/clientShareManager.test.tssrc/components/AddShare.tsxsrc/__tests__/integration/computeRelayPlan.test.tssrc/preload.tssrc/main.tssrc/__tests__/components/SaveShare.test.tsxsrc/__tests__/integration/electron-security.test.tssrc/components/Keyset.tsxsrc/__tests__/lib/igloo-core-integration.test.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/components/LoadShare.tsxsrc/__tests__/workflows/keyset-creation.test.tssrc/__tests__/lib/echoRelays.test.tssrc/components/SaveShare.tsxsrc/__tests__/components/Signer.test.tsxsrc/components/Recover.tsxsrc/__tests__/setup.tssrc/__tests__/lib/validation.test.tssrc/lib/validation.ts
src/{components,lib,types}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
UI components sit under
src/components/, helpers insrc/lib/, shared types insrc/types/
Files:
src/lib/clientShareManager.tssrc/lib/shareManager.tssrc/components/Signer.tsxsrc/lib/echoRelays.tssrc/components/Create.tsxsrc/components/AddShare.tsxsrc/components/Keyset.tsxsrc/components/LoadShare.tsxsrc/components/SaveShare.tsxsrc/components/Recover.tsxsrc/lib/validation.ts
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/**/*.{ts,tsx}: All runtime code is TypeScript with two-space indentation and required semicolons
Import third-party packages before internal modules and use the@/alias for local paths
Files:
src/lib/clientShareManager.tssrc/lib/shareManager.tssrc/__tests__/components/AddShare.test.tsxsrc/components/Signer.tsxsrc/lib/echoRelays.tssrc/__tests__/lib/shareManager.test.tssrc/__tests__/integration/userInputValidation.test.tssrc/__tests__/components/Recover.test.tsxsrc/__tests__/components/LoadShare.test.tsxsrc/components/Create.tsxsrc/__tests__/__mocks__/bifrost.mock.tssrc/__tests__/integration/clientShareManager.test.tssrc/components/AddShare.tsxsrc/__tests__/integration/computeRelayPlan.test.tssrc/preload.tssrc/main.tssrc/__tests__/components/SaveShare.test.tsxsrc/__tests__/integration/electron-security.test.tssrc/components/Keyset.tsxsrc/__tests__/lib/igloo-core-integration.test.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/components/LoadShare.tsxsrc/__tests__/workflows/keyset-creation.test.tssrc/__tests__/lib/echoRelays.test.tssrc/components/SaveShare.tsxsrc/__tests__/components/Signer.test.tsxsrc/components/Recover.tsxsrc/__tests__/setup.tssrc/__tests__/lib/validation.test.tssrc/lib/validation.ts
src/lib/shareManager.ts
📄 CodeRabbit inference engine (CLAUDE.md)
src/lib/shareManager.ts: Never store plaintext share data; always encrypt with user passwords
Store shares in /igloo/shares/ directory using the defined JSON schema
Files:
src/lib/shareManager.ts
src/__tests__/**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
src/__tests__/**/*.test.{ts,tsx}: Mock @frostr/igloo-core functions at the module level in tests to avoid ESM/Jest complications
Use jest.clearAllMocks() in beforeEach hooks to ensure test isolation
Mock Electron's ipcRenderer and app APIs in tests
Files:
src/__tests__/components/AddShare.test.tsxsrc/__tests__/lib/shareManager.test.tssrc/__tests__/integration/userInputValidation.test.tssrc/__tests__/components/Recover.test.tsxsrc/__tests__/components/LoadShare.test.tsxsrc/__tests__/integration/clientShareManager.test.tssrc/__tests__/integration/computeRelayPlan.test.tssrc/__tests__/components/SaveShare.test.tsxsrc/__tests__/integration/electron-security.test.tssrc/__tests__/lib/igloo-core-integration.test.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/__tests__/workflows/keyset-creation.test.tssrc/__tests__/lib/echoRelays.test.tssrc/__tests__/components/Signer.test.tsxsrc/__tests__/lib/validation.test.ts
src/__tests__/components/**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Test React component behavior in tests/components/ directory
Files:
src/__tests__/components/AddShare.test.tsxsrc/__tests__/components/Recover.test.tsxsrc/__tests__/components/LoadShare.test.tsxsrc/__tests__/components/SaveShare.test.tsxsrc/__tests__/components/Signer.test.tsx
src/__tests__/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Tests mirror runtime code under
src/__tests__/withintegration/,performance/, and__mocks__/subdirectories for feature-specific coverage
Files:
src/__tests__/components/AddShare.test.tsxsrc/__tests__/lib/shareManager.test.tssrc/__tests__/integration/userInputValidation.test.tssrc/__tests__/components/Recover.test.tsxsrc/__tests__/components/LoadShare.test.tsxsrc/__tests__/__mocks__/bifrost.mock.tssrc/__tests__/integration/clientShareManager.test.tssrc/__tests__/integration/computeRelayPlan.test.tssrc/__tests__/components/SaveShare.test.tsxsrc/__tests__/integration/electron-security.test.tssrc/__tests__/lib/igloo-core-integration.test.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/__tests__/workflows/keyset-creation.test.tssrc/__tests__/lib/echoRelays.test.tssrc/__tests__/components/Signer.test.tsxsrc/__tests__/setup.tssrc/__tests__/lib/validation.test.ts
src/**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Jest with Testing Library powers renderer specs; place new tests beside features as
<subject>.test.tsx
Files:
src/__tests__/components/AddShare.test.tsxsrc/__tests__/lib/shareManager.test.tssrc/__tests__/integration/userInputValidation.test.tssrc/__tests__/components/Recover.test.tsxsrc/__tests__/components/LoadShare.test.tsxsrc/__tests__/integration/clientShareManager.test.tssrc/__tests__/integration/computeRelayPlan.test.tssrc/__tests__/components/SaveShare.test.tsxsrc/__tests__/integration/electron-security.test.tssrc/__tests__/lib/igloo-core-integration.test.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/__tests__/workflows/keyset-creation.test.tssrc/__tests__/lib/echoRelays.test.tssrc/__tests__/components/Signer.test.tsxsrc/__tests__/lib/validation.test.ts
src/components/[A-Z]*.tsx
📄 CodeRabbit inference engine (CLAUDE.md)
Use PascalCase for component files
Files:
src/components/Signer.tsxsrc/components/Create.tsxsrc/components/AddShare.tsxsrc/components/Keyset.tsxsrc/components/LoadShare.tsxsrc/components/SaveShare.tsxsrc/components/Recover.tsx
src/components/**/*.tsx
📄 CodeRabbit inference engine (CLAUDE.md)
src/components/**/*.tsx: Use Tailwind CSS utility classes in JSX and use cn() utility for conditional classes
Avoid inline styles unless conditionally computed
Use functional components with hooks instead of class components
Use ipcRenderer.invoke() in renderer process to call IPC handlers without direct file system accessTailwind utility classes style JSX; reserve inline styles for dynamic values only
Files:
src/components/Signer.tsxsrc/components/Create.tsxsrc/components/AddShare.tsxsrc/components/Keyset.tsxsrc/components/LoadShare.tsxsrc/components/SaveShare.tsxsrc/components/Recover.tsx
src/components/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/components/**/*.{ts,tsx}: Prefer functional React components; name them in PascalCase and helpers in camelCase
Components insrc/components/follow kebab-case filenames (e.g.,share-list.tsx)
Files:
src/components/Signer.tsxsrc/components/Create.tsxsrc/components/AddShare.tsxsrc/components/Keyset.tsxsrc/components/LoadShare.tsxsrc/components/SaveShare.tsxsrc/components/Recover.tsx
src/__tests__/lib/**/*.test.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Test utility functions in tests/lib/ directory
Files:
src/__tests__/lib/shareManager.test.tssrc/__tests__/lib/igloo-core-integration.test.tssrc/__tests__/lib/echoRelays.test.tssrc/__tests__/lib/validation.test.ts
src/__tests__/integration/**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Test Electron IPC communication in tests/integration/ directory
Files:
src/__tests__/integration/userInputValidation.test.tssrc/__tests__/integration/clientShareManager.test.tssrc/__tests__/integration/computeRelayPlan.test.tssrc/__tests__/integration/electron-security.test.ts
src/__tests__/__mocks__/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Place shared mock implementations in tests/mocks/ for use across test files
Files:
src/__tests__/__mocks__/bifrost.mock.ts
src/__tests__/{setup.ts,__mocks__/**}
📄 CodeRabbit inference engine (AGENTS.md)
Register shared mocks in
src/__tests__/setup.tsand reuse fixtures fromsrc/__tests__/__mocks__/
Files:
src/__tests__/__mocks__/bifrost.mock.tssrc/__tests__/setup.ts
src/main.ts
📄 CodeRabbit inference engine (CLAUDE.md)
src/main.ts: Register IPC handlers in main.ts using ipcMain.handle() for file system operations
Electron's main process uses CommonJS (require) while renderer uses ESM (import)Main Electron process lives in
src/main.ts; the renderer bootstraps fromsrc/renderer.tsx
Files:
src/main.ts
src/__tests__/workflows/**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Test end-to-end user flows in tests/workflows/ directory
Files:
src/__tests__/workflows/share-lifecycle.test.tssrc/__tests__/workflows/keyset-creation.test.ts
🧠 Learnings (28)
📓 Common learnings
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T23:50:29.859Z
Learning: Applies to src/**/*ipc*.{ts,tsx} : Cover new IPC handlers with unit tests plus at least one scenario in `src/__tests__/integration/`
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/__tests__/integration/**/*.test.{ts,tsx} : Test Electron IPC communication in __tests__/integration/ directory
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/lib/shareManager.ts : Store shares in <appData>/igloo/shares/ directory using the defined JSON schema
Applied to files:
src/lib/clientShareManager.tssrc/lib/shareManager.tssrc/__tests__/lib/shareManager.test.tssrc/__tests__/integration/clientShareManager.test.tssrc/components/AddShare.tsxsrc/main.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/components/Recover.tsxCLAUDE.md
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/__tests__/integration/**/*.test.{ts,tsx} : Test Electron IPC communication in __tests__/integration/ directory
Applied to files:
src/lib/clientShareManager.tssrc/__tests__/components/AddShare.test.tsxsrc/__tests__/lib/shareManager.test.tssrc/__tests__/integration/userInputValidation.test.tssrc/__tests__/components/Recover.test.tsxsrc/__tests__/components/LoadShare.test.tsxsrc/__tests__/integration/clientShareManager.test.tssrc/__tests__/integration/computeRelayPlan.test.tssrc/preload.tssrc/main.tssrc/__tests__/components/SaveShare.test.tsxsrc/__tests__/integration/electron-security.test.tssrc/__tests__/lib/igloo-core-integration.test.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/__tests__/lib/echoRelays.test.tssrc/__tests__/setup.tssrc/__tests__/lib/validation.test.tsCLAUDE.md
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/lib/shareManager.ts : Never store plaintext share data; always encrypt with user passwords
Applied to files:
src/lib/clientShareManager.tssrc/lib/shareManager.tssrc/__tests__/components/AddShare.test.tsxsrc/__tests__/lib/shareManager.test.tssrc/__tests__/components/LoadShare.test.tsxsrc/__tests__/__mocks__/bifrost.mock.tssrc/__tests__/integration/clientShareManager.test.tssrc/components/AddShare.tsxsrc/__tests__/components/SaveShare.test.tsxsrc/components/Keyset.tsxsrc/__tests__/workflows/share-lifecycle.test.tssrc/components/LoadShare.tsxsrc/__tests__/workflows/keyset-creation.test.tssrc/components/SaveShare.tsxsrc/components/Recover.tsxCLAUDE.mdSECURITY_AUDIT_2026-01-06.md
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/main.ts : Register IPC handlers in main.ts using ipcMain.handle() for file system operations
Applied to files:
src/lib/clientShareManager.tssrc/__tests__/integration/computeRelayPlan.test.tssrc/preload.tssrc/main.tssrc/__tests__/integration/electron-security.test.tssrc/components/Keyset.tsx
📚 Learning: 2026-01-02T23:50:29.859Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T23:50:29.859Z
Learning: Applies to src/**/*ipc*.{ts,tsx} : Cover new IPC handlers with unit tests plus at least one scenario in `src/__tests__/integration/`
Applied to files:
src/lib/clientShareManager.tssrc/__tests__/components/AddShare.test.tsxsrc/__tests__/lib/shareManager.test.tssrc/__tests__/integration/userInputValidation.test.tssrc/__tests__/components/Recover.test.tsxsrc/__tests__/components/LoadShare.test.tsxsrc/__tests__/integration/clientShareManager.test.tssrc/__tests__/integration/computeRelayPlan.test.tssrc/main.tssrc/__tests__/components/SaveShare.test.tsxsrc/__tests__/integration/electron-security.test.tssrc/__tests__/lib/igloo-core-integration.test.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/__tests__/lib/echoRelays.test.tssrc/__tests__/components/Signer.test.tsxsrc/__tests__/setup.tssrc/__tests__/lib/validation.test.ts
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/components/**/*.tsx : Use ipcRenderer.invoke() in renderer process to call IPC handlers without direct file system access
Applied to files:
src/lib/clientShareManager.tssrc/__tests__/integration/clientShareManager.test.tssrc/__tests__/integration/computeRelayPlan.test.tssrc/preload.tssrc/main.tssrc/__tests__/integration/electron-security.test.tssrc/components/Keyset.tsxsrc/__tests__/setup.ts
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/__tests__/**/*.test.{ts,tsx} : Mock Electron's ipcRenderer and app APIs in tests
Applied to files:
src/__tests__/components/AddShare.test.tsxsrc/__tests__/components/Recover.test.tsxsrc/__tests__/integration/clientShareManager.test.tssrc/__tests__/integration/computeRelayPlan.test.tssrc/preload.tssrc/main.tssrc/__tests__/integration/electron-security.test.tssrc/__tests__/workflows/share-lifecycle.test.tswebpack.config.cjssrc/__tests__/components/Signer.test.tsxsrc/__tests__/setup.ts
📚 Learning: 2026-01-02T23:50:29.859Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T23:50:29.859Z
Learning: Applies to src/__tests__/{setup.ts,__mocks__/**} : Register shared mocks in `src/__tests__/setup.ts` and reuse fixtures from `src/__tests__/__mocks__/`
Applied to files:
src/__tests__/components/AddShare.test.tsxsrc/__tests__/components/Recover.test.tsxsrc/__tests__/__mocks__/bifrost.mock.tssrc/__tests__/integration/clientShareManager.test.tssrc/__tests__/components/SaveShare.test.tsxsrc/__tests__/lib/igloo-core-integration.test.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/__tests__/workflows/keyset-creation.test.tssrc/__tests__/components/Signer.test.tsxsrc/__tests__/setup.ts
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/__tests__/__mocks__/**/*.ts : Place shared mock implementations in __tests__/__mocks__/ for use across test files
Applied to files:
src/__tests__/components/AddShare.test.tsxsrc/__tests__/lib/shareManager.test.tssrc/__tests__/__mocks__/bifrost.mock.tssrc/__tests__/integration/clientShareManager.test.tssrc/__tests__/components/SaveShare.test.tsxtsconfig.test.jsonsrc/__tests__/lib/igloo-core-integration.test.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/__tests__/workflows/keyset-creation.test.tssrc/__tests__/setup.ts
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/__tests__/**/*.test.{ts,tsx} : Mock frostr/igloo-core functions at the module level in tests to avoid ESM/Jest complications
Applied to files:
src/__tests__/components/AddShare.test.tsxsrc/__tests__/lib/shareManager.test.tssrc/__tests__/components/Recover.test.tsxsrc/__tests__/__mocks__/bifrost.mock.tssrc/__tests__/integration/clientShareManager.test.tstsconfig.test.jsonsrc/__tests__/lib/igloo-core-integration.test.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/__tests__/workflows/keyset-creation.test.tssrc/__tests__/lib/echoRelays.test.tssrc/__tests__/components/Signer.test.tsxsrc/__tests__/setup.tspackage.json
📚 Learning: 2026-01-02T23:50:29.859Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T23:50:29.859Z
Learning: Applies to src/__tests__/**/*.{ts,tsx} : Tests mirror runtime code under `src/__tests__/` with `integration/`, `performance/`, and `__mocks__/` subdirectories for feature-specific coverage
Applied to files:
src/__tests__/components/AddShare.test.tsxsrc/__tests__/lib/shareManager.test.tssrc/__tests__/components/Recover.test.tsxsrc/__tests__/components/LoadShare.test.tsxsrc/__tests__/integration/clientShareManager.test.tssrc/__tests__/integration/computeRelayPlan.test.tssrc/__tests__/components/SaveShare.test.tsxsrc/__tests__/integration/electron-security.test.tstsconfig.test.jsonsrc/__tests__/lib/igloo-core-integration.test.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/__tests__/lib/echoRelays.test.tssrc/__tests__/components/Signer.test.tsxsrc/__tests__/setup.tssrc/__tests__/lib/validation.test.ts
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/__tests__/**/*.test.{ts,tsx} : Use jest.clearAllMocks() in beforeEach hooks to ensure test isolation
Applied to files:
src/__tests__/components/AddShare.test.tsxsrc/__tests__/components/Recover.test.tsxsrc/__tests__/integration/clientShareManager.test.tstsconfig.test.jsonsrc/__tests__/workflows/share-lifecycle.test.tssrc/__tests__/workflows/keyset-creation.test.tssrc/__tests__/components/Signer.test.tsxsrc/__tests__/setup.ts
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/__tests__/components/**/*.test.{ts,tsx} : Test React component behavior in __tests__/components/ directory
Applied to files:
src/__tests__/components/AddShare.test.tsxsrc/__tests__/components/Recover.test.tsxsrc/__tests__/components/LoadShare.test.tsxsrc/__tests__/components/SaveShare.test.tsxsrc/__tests__/integration/electron-security.test.tstsconfig.test.jsonsrc/__tests__/lib/validation.test.ts
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/__tests__/lib/**/*.test.ts : Test utility functions in __tests__/lib/ directory
Applied to files:
src/__tests__/components/AddShare.test.tsxsrc/__tests__/lib/shareManager.test.tssrc/__tests__/components/Recover.test.tsxsrc/__tests__/components/LoadShare.test.tsxsrc/__tests__/integration/computeRelayPlan.test.tssrc/__tests__/components/SaveShare.test.tsxsrc/__tests__/integration/electron-security.test.tstsconfig.test.jsonsrc/__tests__/lib/igloo-core-integration.test.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/__tests__/lib/echoRelays.test.tssrc/__tests__/lib/validation.test.tsCLAUDE.md
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Do not implement cryptographic logic in the desktop app; delegate all crypto operations to frostr/igloo-core
Applied to files:
src/components/Signer.tsxsrc/components/AddShare.tsxCLAUDE.md
📚 Learning: 2026-01-02T23:50:29.859Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T23:50:29.859Z
Learning: Applies to src/**/*.test.{ts,tsx} : Jest with Testing Library powers renderer specs; place new tests beside features as `<subject>.test.tsx`
Applied to files:
src/__tests__/components/Recover.test.tsxsrc/__tests__/integration/electron-security.test.tstsconfig.test.jsonsrc/__tests__/components/Signer.test.tsxsrc/__tests__/setup.tssrc/__tests__/lib/validation.test.ts
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/lib/encryption.ts : Use PBKDF2 with 600,000 iterations for encrypting share files
Applied to files:
src/__tests__/__mocks__/bifrost.mock.tssrc/components/LoadShare.tsxsrc/components/SaveShare.tsx
📚 Learning: 2026-01-02T23:50:29.859Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T23:50:29.859Z
Learning: Applies to src/**/*.{ts,tsx} : Import third-party packages before internal modules and use the `@/` alias for local paths
Applied to files:
tsconfig.preload.jsontsconfig.test.jsonwebpack.config.cjsCLAUDE.md
📚 Learning: 2026-01-02T23:50:29.859Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T23:50:29.859Z
Learning: Applies to src/**/*.{ts,tsx} : All runtime code is TypeScript with two-space indentation and required semicolons
Applied to files:
tsconfig.preload.jsontsconfig.test.json
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/main.ts : Electron's main process uses CommonJS (require) while renderer uses ESM (import)
Applied to files:
src/preload.tssrc/main.tssrc/__tests__/integration/electron-security.test.tswebpack.config.cjssrc/__tests__/setup.tsCLAUDE.mdpackage.json
📚 Learning: 2026-01-02T23:50:29.859Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T23:50:29.859Z
Learning: Applies to src/main.ts : Main Electron process lives in `src/main.ts`; the renderer bootstraps from `src/renderer.tsx`
Applied to files:
src/preload.tssrc/__tests__/integration/electron-security.test.tswebpack.config.cjsCLAUDE.mdpackage.json
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/__tests__/workflows/**/*.test.{ts,tsx} : Test end-to-end user flows in __tests__/workflows/ directory
Applied to files:
src/__tests__/components/SaveShare.test.tsxsrc/__tests__/workflows/share-lifecycle.test.ts
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to **/*.{ts,tsx} : Use @/ path alias for imports instead of relative paths
Applied to files:
tsconfig.test.jsonwebpack.config.cjs
📚 Learning: 2026-01-02T23:50:29.859Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T23:50:29.859Z
Learning: Applies to src/{components,lib,types}/**/*.{ts,tsx} : UI components sit under `src/components/`, helpers in `src/lib/`, shared types in `src/types/`
Applied to files:
tsconfig.test.jsonCLAUDE.md
📚 Learning: 2026-01-02T23:50:29.859Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T23:50:29.859Z
Learning: Debug flaky Electron tests with `npm test -- --runInBand` to serialize execution
Applied to files:
src/__tests__/workflows/share-lifecycle.test.tssrc/__tests__/setup.ts
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Use props and callbacks for component communication instead of external state libraries like Redux
Applied to files:
CLAUDE.md
📚 Learning: 2026-01-02T23:50:29.859Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T23:50:29.859Z
Learning: PRs should describe the change set, include screenshots or recordings for UI tweaks, and list run commands (`npm test`, `npm run lint`)
Applied to files:
package.json
🧬 Code graph analysis (16)
src/lib/clientShareManager.ts (1)
src/types/index.ts (1)
IglooShare(44-55)
src/__tests__/components/AddShare.test.tsx (1)
src/__tests__/setup.ts (1)
mockElectronAPI(191-191)
src/components/Create.tsx (1)
src/lib/validation.ts (3)
validateShareName(389-419)VALIDATION_LIMITS(4-15)validatePositiveInteger(335-369)
src/__tests__/integration/clientShareManager.test.ts (2)
src/__tests__/setup.ts (1)
mockElectronAPI(191-191)src/lib/clientShareManager.ts (1)
clientShareManager(98-98)
src/components/AddShare.tsx (2)
src/lib/validation.ts (2)
VALIDATION_LIMITS(4-15)sanitizeUserError(432-458)src/types/index.ts (1)
DecodedGroup(9-19)
src/__tests__/integration/computeRelayPlan.test.ts (1)
src/__tests__/setup.ts (1)
mockElectronAPI(191-191)
src/preload.ts (1)
src/lib/echoRelays.ts (1)
RelayPlan(134-141)
src/main.ts (1)
src/lib/echoRelays.ts (1)
computeRelayPlan(151-227)
src/__tests__/components/SaveShare.test.tsx (1)
src/lib/encryption.ts (1)
derive_secret_async(24-73)
src/__tests__/integration/electron-security.test.ts (1)
webpack.config.cjs (1)
path(1-1)
src/__tests__/workflows/share-lifecycle.test.ts (2)
src/__tests__/setup.ts (2)
mockElectronAPI(191-191)mockDeriveSecret(136-136)src/lib/clientShareManager.ts (1)
clientShareManager(98-98)
src/components/LoadShare.tsx (1)
src/lib/validation.ts (2)
VALIDATION_LIMITS(4-15)sanitizeUserError(432-458)
src/__tests__/lib/echoRelays.test.ts (1)
src/lib/echoRelays.ts (2)
normalizeRelayUrl(229-229)computeRelayPlan(151-227)
src/components/SaveShare.tsx (1)
src/lib/validation.ts (1)
VALIDATION_LIMITS(4-15)
src/components/Recover.tsx (1)
src/lib/validation.ts (1)
VALIDATION_LIMITS(4-15)
src/__tests__/lib/validation.test.ts (1)
src/lib/validation.ts (7)
VALIDATION_LIMITS(4-15)validatePassword(32-49)validatePasswordLength(467-487)validatePositiveInteger(335-369)validateShareName(389-419)sanitizeUserError(432-458)formatRelayUrl(230-304)
🪛 LanguageTool
SECURITY_AUDIT_2026-01-06.md
[grammar] ~269-~269: Use a hyphen to join words.
Context: ...m invalid threshold values --- ## High Severity Issues ### 6. ✅ FIXED: Insecur...
(QB_NEW_EN_HYPHEN)
[grammar] ~838-~838: Use a hyphen to join words.
Context: ...")` = NaN silently accepted --- ## Low Severity Issues ### 33. ✅ FIXED: No IPC...
(QB_NEW_EN_HYPHEN)
[grammar] ~976-~976: Use a hyphen to join words.
Context: ...ion fixes covering all critical and high severity React component validation issu...
(QB_NEW_EN_HYPHEN)
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In @src/lib/echoRelays.ts:
- Around line 134-141: Consolidate the duplicated RelayPlan by creating a single
exported interface RelayPlan in the project's shared types directory (use
interface, not type) with the fields relays, envRelays, defaultRelays,
groupRelays, explicitRelays, and groupExtras; then remove the local RelayPlan
definitions and import this shared RelayPlan in both the echoRelays module and
the preload module so both files reference the same interface.
🧹 Nitpick comments (9)
src/__tests__/lib/validation.test.ts (1)
65-70: Verify completeness of max-length password test.The test checks
hasMaxLengthandhasMinLengthbut doesn't verifyisValid. Since the password'Aa1!' + 'x'.repeat(252)should satisfy all requirements (uppercase, lowercase, number, special char, length), consider assertingresult.isValidto ensure the complete validation logic works correctly.✨ Suggested addition
it('should accept passwords at max length', () => { const maxPassword = 'Aa1!' + 'x'.repeat(252); const result = validatePassword(maxPassword); expect(result.hasMaxLength).toBe(true); expect(result.hasMinLength).toBe(true); + expect(result.isValid).toBe(true); });src/__tests__/components/Recover.test.tsx (1)
426-435: Consider making mask length assertion less brittle.The regex
/•{40}/assumes a specific number of mask characters. If the masking logic changes (e.g., different NSEC lengths), this test could break unexpectedly.♻️ Suggestion: Use a more flexible assertion
- expect(screen.getByText(/•{40}/)).toBeInTheDocument(); + // Assert that masked characters exist without hard-coding count + expect(screen.getByText(/•+/)).toBeInTheDocument();Alternatively, assert that the full NSEC is not visible while some masked portion is, which you already do.
src/components/AddShare.tsx (1)
395-409: Inline type definition could be extracted for reuse.The
LegacyDecodedGrouptype is defined inline within the function. If this pattern is needed elsewhere, consider extracting it tosrc/types/index.ts.src/__tests__/integration/computeRelayPlan.test.ts (1)
26-68: Static analysis tests are effective but may be fragile.Testing by reading source file content and using regex patterns is unconventional but provides valuable verification that IPC handlers are registered correctly. However, these tests may break if code formatting or structure changes without functional impact.
Consider adding a comment noting that these tests verify contract/structure and may need updates during refactoring:
describe('Handler Registration (static analysis)', () => { + // NOTE: These regex-based tests verify handler structure in main.ts. + // If formatting changes cause failures, update patterns as needed. it('should register compute-relay-plan IPC handler', () => {src/components/Recover.tsx (2)
751-754: Consider whether revealing the NSEC prefix is acceptable.The masked display shows the first 8 characters of the NSEC (
{recoveredNsec.substring(0, 8)}). While this helps users confirm they have the correct key, NSEC prefixes are predictable (nsec1...), so this is low risk. However, if future key formats include identifying info in the prefix, this could leak data.🔒 Optional: Use a fully masked placeholder
) : ( <div className="text-xs font-mono text-gray-400"> - {recoveredNsec.substring(0, 8)}{'•'.repeat(40)}... + {'•'.repeat(48)}... </div> )}
461-462: Avoid logging error details for clipboard operations.The
console.error('Failed to copy NSEC:', err)may expose error stack traces or internal details. Consider logging only a generic message.🔒 Suggested fix
} catch (err) { - console.error('Failed to copy NSEC:', err); + console.error('[Recover] Clipboard write failed');src/lib/validation.ts (1)
184-199: Consider IPv6 localhost and link-local addresses for SSRF protection.The current implementation blocks IPv4 private ranges and
localhost, but IPv6 equivalents like::1,::ffff:127.0.0.1, orfe80::link-local addresses could bypass these checks. Relay URLs might accept IPv6 addresses.🔒 Add IPv6 SSRF protection
// SSRF Protection: Block localhost if (host === 'localhost') return false; + + // SSRF Protection: Block IPv6 loopback and mapped addresses + if (host === '::1' || host === '[::1]') return false; + if (host.startsWith('::ffff:')) return false; // Validate the host partOr alternatively, validate IPv6 addresses in a separate function before the domain pattern check.
SECURITY_AUDIT_2026-01-06.md (2)
269-269: Grammar: Use hyphens for compound modifiers before nouns.Three instances flagged by static analysis:
- Line 269: "Early return prevents state explosion from invalid threshold values --- ## High Severity Issues" → suggest "High-Severity"
- Line 838: "
Number("")= 0 andNumber("abc")= NaN silently accepted --- ## Low Severity Issues" → suggest "Low-Severity"- Line 976: "all critical and high severity React component validation issues" → suggest "critical and high-severity"
Also applies to: 838-838, 976-976
18-18: Clarify discrepancy in issue count—summary table vs. statistics table.Line 18 states: "
⚠️ Open | 23 | Issues requiring future attention"But line 51 (Executive Summary table) shows:
- Critical: 5 fixed, 0 remaining ✓
- High: 7 fixed, 3 remaining
- Medium: 4 fixed, 13 remaining
- Low: 2 fixed, 7 remaining
Total remaining: 3 + 13 + 7 = 23 ✓
Counts match, but the visibility of open HIGH/MEDIUM issues in the summary table would help stakeholders understand the risk profile at a glance. Consider adding a "Remaining by Severity" breakdown near line 18.
Also applies to: 51-51
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (37)
CLAUDE.mdSECURITY_AUDIT_2026-01-06.mdindex.htmlpackage.jsonsrc/__tests__/__mocks__/bifrost.mock.tssrc/__tests__/components/AddShare.test.tsxsrc/__tests__/components/LoadShare.test.tsxsrc/__tests__/components/Recover.test.tsxsrc/__tests__/components/SaveShare.test.tsxsrc/__tests__/components/Signer.test.tsxsrc/__tests__/integration/clientShareManager.test.tssrc/__tests__/integration/computeRelayPlan.test.tssrc/__tests__/integration/electron-security.test.tssrc/__tests__/integration/userInputValidation.test.tssrc/__tests__/lib/echoRelays.test.tssrc/__tests__/lib/igloo-core-integration.test.tssrc/__tests__/lib/shareManager.test.tssrc/__tests__/lib/validation.test.tssrc/__tests__/setup.tssrc/__tests__/workflows/keyset-creation.test.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/components/AddShare.tsxsrc/components/Create.tsxsrc/components/Keyset.tsxsrc/components/LoadShare.tsxsrc/components/Recover.tsxsrc/components/SaveShare.tsxsrc/components/Signer.tsxsrc/lib/clientShareManager.tssrc/lib/echoRelays.tssrc/lib/shareManager.tssrc/lib/validation.tssrc/main.tssrc/preload.tstsconfig.preload.jsontsconfig.test.jsonwebpack.config.cjs
🧰 Additional context used
📓 Path-based instructions (17)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Use strict TypeScript mode with explicit types for function parameters and returns
Prefer interfaces over types for defining object shapes in TypeScript
Use @/ path alias for imports instead of relative paths
Use camelCase for functions and variables
Use UPPER_SNAKE_CASE for constants
Files:
src/__tests__/lib/shareManager.test.tssrc/__tests__/components/AddShare.test.tsxsrc/__tests__/lib/igloo-core-integration.test.tssrc/__tests__/integration/userInputValidation.test.tssrc/components/LoadShare.tsxsrc/components/Recover.tsxsrc/__tests__/__mocks__/bifrost.mock.tssrc/__tests__/lib/echoRelays.test.tssrc/lib/shareManager.tssrc/components/Signer.tsxsrc/lib/echoRelays.tssrc/__tests__/components/Recover.test.tsxsrc/__tests__/setup.tssrc/components/Create.tsxsrc/components/Keyset.tsxsrc/__tests__/components/SaveShare.test.tsxsrc/lib/clientShareManager.tssrc/components/AddShare.tsxsrc/__tests__/integration/electron-security.test.tssrc/__tests__/integration/computeRelayPlan.test.tssrc/__tests__/workflows/keyset-creation.test.tssrc/preload.tssrc/__tests__/lib/validation.test.tssrc/lib/validation.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/components/SaveShare.tsxsrc/__tests__/integration/clientShareManager.test.tssrc/__tests__/components/Signer.test.tsxsrc/main.tssrc/__tests__/components/LoadShare.test.tsx
src/__tests__/**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
src/__tests__/**/*.test.{ts,tsx}: Mock @frostr/igloo-core functions at the module level in tests to avoid ESM/Jest complications
Use jest.clearAllMocks() in beforeEach hooks to ensure test isolation
Mock Electron's ipcRenderer and app APIs in tests
Files:
src/__tests__/lib/shareManager.test.tssrc/__tests__/components/AddShare.test.tsxsrc/__tests__/lib/igloo-core-integration.test.tssrc/__tests__/integration/userInputValidation.test.tssrc/__tests__/lib/echoRelays.test.tssrc/__tests__/components/Recover.test.tsxsrc/__tests__/components/SaveShare.test.tsxsrc/__tests__/integration/electron-security.test.tssrc/__tests__/integration/computeRelayPlan.test.tssrc/__tests__/workflows/keyset-creation.test.tssrc/__tests__/lib/validation.test.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/__tests__/integration/clientShareManager.test.tssrc/__tests__/components/Signer.test.tsxsrc/__tests__/components/LoadShare.test.tsx
src/__tests__/lib/**/*.test.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Test utility functions in tests/lib/ directory
Files:
src/__tests__/lib/shareManager.test.tssrc/__tests__/lib/igloo-core-integration.test.tssrc/__tests__/lib/echoRelays.test.tssrc/__tests__/lib/validation.test.ts
src/__tests__/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Tests mirror runtime code under
src/__tests__/withintegration/,performance/, and__mocks__/subdirectories for feature-specific coverage
Files:
src/__tests__/lib/shareManager.test.tssrc/__tests__/components/AddShare.test.tsxsrc/__tests__/lib/igloo-core-integration.test.tssrc/__tests__/integration/userInputValidation.test.tssrc/__tests__/__mocks__/bifrost.mock.tssrc/__tests__/lib/echoRelays.test.tssrc/__tests__/components/Recover.test.tsxsrc/__tests__/setup.tssrc/__tests__/components/SaveShare.test.tsxsrc/__tests__/integration/electron-security.test.tssrc/__tests__/integration/computeRelayPlan.test.tssrc/__tests__/workflows/keyset-creation.test.tssrc/__tests__/lib/validation.test.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/__tests__/integration/clientShareManager.test.tssrc/__tests__/components/Signer.test.tsxsrc/__tests__/components/LoadShare.test.tsx
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/**/*.{ts,tsx}: All runtime code is TypeScript with two-space indentation and required semicolons
Import third-party packages before internal modules and use the@/alias for local paths
Files:
src/__tests__/lib/shareManager.test.tssrc/__tests__/components/AddShare.test.tsxsrc/__tests__/lib/igloo-core-integration.test.tssrc/__tests__/integration/userInputValidation.test.tssrc/components/LoadShare.tsxsrc/components/Recover.tsxsrc/__tests__/__mocks__/bifrost.mock.tssrc/__tests__/lib/echoRelays.test.tssrc/lib/shareManager.tssrc/components/Signer.tsxsrc/lib/echoRelays.tssrc/__tests__/components/Recover.test.tsxsrc/__tests__/setup.tssrc/components/Create.tsxsrc/components/Keyset.tsxsrc/__tests__/components/SaveShare.test.tsxsrc/lib/clientShareManager.tssrc/components/AddShare.tsxsrc/__tests__/integration/electron-security.test.tssrc/__tests__/integration/computeRelayPlan.test.tssrc/__tests__/workflows/keyset-creation.test.tssrc/preload.tssrc/__tests__/lib/validation.test.tssrc/lib/validation.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/components/SaveShare.tsxsrc/__tests__/integration/clientShareManager.test.tssrc/__tests__/components/Signer.test.tsxsrc/main.tssrc/__tests__/components/LoadShare.test.tsx
src/**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Jest with Testing Library powers renderer specs; place new tests beside features as
<subject>.test.tsx
Files:
src/__tests__/lib/shareManager.test.tssrc/__tests__/components/AddShare.test.tsxsrc/__tests__/lib/igloo-core-integration.test.tssrc/__tests__/integration/userInputValidation.test.tssrc/__tests__/lib/echoRelays.test.tssrc/__tests__/components/Recover.test.tsxsrc/__tests__/components/SaveShare.test.tsxsrc/__tests__/integration/electron-security.test.tssrc/__tests__/integration/computeRelayPlan.test.tssrc/__tests__/workflows/keyset-creation.test.tssrc/__tests__/lib/validation.test.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/__tests__/integration/clientShareManager.test.tssrc/__tests__/components/Signer.test.tsxsrc/__tests__/components/LoadShare.test.tsx
src/__tests__/components/**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Test React component behavior in tests/components/ directory
Files:
src/__tests__/components/AddShare.test.tsxsrc/__tests__/components/Recover.test.tsxsrc/__tests__/components/SaveShare.test.tsxsrc/__tests__/components/Signer.test.tsxsrc/__tests__/components/LoadShare.test.tsx
src/__tests__/integration/**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Test Electron IPC communication in tests/integration/ directory
Files:
src/__tests__/integration/userInputValidation.test.tssrc/__tests__/integration/electron-security.test.tssrc/__tests__/integration/computeRelayPlan.test.tssrc/__tests__/integration/clientShareManager.test.ts
src/components/[A-Z]*.tsx
📄 CodeRabbit inference engine (CLAUDE.md)
Use PascalCase for component files
Files:
src/components/LoadShare.tsxsrc/components/Recover.tsxsrc/components/Signer.tsxsrc/components/Create.tsxsrc/components/Keyset.tsxsrc/components/AddShare.tsxsrc/components/SaveShare.tsx
src/components/**/*.tsx
📄 CodeRabbit inference engine (CLAUDE.md)
src/components/**/*.tsx: Use Tailwind CSS utility classes in JSX and use cn() utility for conditional classes
Avoid inline styles unless conditionally computed
Use functional components with hooks instead of class components
Use ipcRenderer.invoke() in renderer process to call IPC handlers without direct file system accessTailwind utility classes style JSX; reserve inline styles for dynamic values only
Files:
src/components/LoadShare.tsxsrc/components/Recover.tsxsrc/components/Signer.tsxsrc/components/Create.tsxsrc/components/Keyset.tsxsrc/components/AddShare.tsxsrc/components/SaveShare.tsx
src/{components,lib,types}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
UI components sit under
src/components/, helpers insrc/lib/, shared types insrc/types/
Files:
src/components/LoadShare.tsxsrc/components/Recover.tsxsrc/lib/shareManager.tssrc/components/Signer.tsxsrc/lib/echoRelays.tssrc/components/Create.tsxsrc/components/Keyset.tsxsrc/lib/clientShareManager.tssrc/components/AddShare.tsxsrc/lib/validation.tssrc/components/SaveShare.tsx
src/components/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/components/**/*.{ts,tsx}: Prefer functional React components; name them in PascalCase and helpers in camelCase
Components insrc/components/follow kebab-case filenames (e.g.,share-list.tsx)
Files:
src/components/LoadShare.tsxsrc/components/Recover.tsxsrc/components/Signer.tsxsrc/components/Create.tsxsrc/components/Keyset.tsxsrc/components/AddShare.tsxsrc/components/SaveShare.tsx
src/__tests__/__mocks__/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Place shared mock implementations in tests/mocks/ for use across test files
Files:
src/__tests__/__mocks__/bifrost.mock.ts
src/__tests__/{setup.ts,__mocks__/**}
📄 CodeRabbit inference engine (AGENTS.md)
Register shared mocks in
src/__tests__/setup.tsand reuse fixtures fromsrc/__tests__/__mocks__/
Files:
src/__tests__/__mocks__/bifrost.mock.tssrc/__tests__/setup.ts
src/lib/shareManager.ts
📄 CodeRabbit inference engine (CLAUDE.md)
src/lib/shareManager.ts: Never store plaintext share data; always encrypt with user passwords
Store shares in /igloo/shares/ directory using the defined JSON schema
Files:
src/lib/shareManager.ts
src/__tests__/workflows/**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Test end-to-end user flows in tests/workflows/ directory
Files:
src/__tests__/workflows/keyset-creation.test.tssrc/__tests__/workflows/share-lifecycle.test.ts
src/main.ts
📄 CodeRabbit inference engine (CLAUDE.md)
src/main.ts: Register IPC handlers in main.ts using ipcMain.handle() for file system operations
Electron's main process uses CommonJS (require) while renderer uses ESM (import)Main Electron process lives in
src/main.ts; the renderer bootstraps fromsrc/renderer.tsx
Files:
src/main.ts
🧠 Learnings (28)
📓 Common learnings
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T23:50:29.859Z
Learning: Applies to src/**/*ipc*.{ts,tsx} : Cover new IPC handlers with unit tests plus at least one scenario in `src/__tests__/integration/`
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/lib/shareManager.ts : Store shares in <appData>/igloo/shares/ directory using the defined JSON schema
Applied to files:
src/__tests__/lib/shareManager.test.tssrc/components/Recover.tsxsrc/lib/shareManager.tssrc/lib/clientShareManager.tssrc/components/AddShare.tsxsrc/__tests__/workflows/share-lifecycle.test.tssrc/__tests__/integration/clientShareManager.test.tsCLAUDE.mdsrc/main.ts
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/__tests__/lib/**/*.test.ts : Test utility functions in __tests__/lib/ directory
Applied to files:
src/__tests__/lib/shareManager.test.tssrc/__tests__/components/AddShare.test.tsxsrc/__tests__/lib/igloo-core-integration.test.tssrc/__tests__/lib/echoRelays.test.tssrc/__tests__/components/Recover.test.tsxsrc/__tests__/components/SaveShare.test.tsxsrc/__tests__/integration/electron-security.test.tssrc/__tests__/integration/computeRelayPlan.test.tssrc/__tests__/lib/validation.test.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/__tests__/integration/clientShareManager.test.tsCLAUDE.mdsrc/__tests__/components/LoadShare.test.tsx
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/lib/shareManager.ts : Never store plaintext share data; always encrypt with user passwords
Applied to files:
src/__tests__/lib/shareManager.test.tssrc/__tests__/components/AddShare.test.tsxsrc/components/LoadShare.tsxsrc/components/Recover.tsxsrc/__tests__/__mocks__/bifrost.mock.tssrc/lib/shareManager.tssrc/components/Keyset.tsxsrc/__tests__/components/SaveShare.test.tsxsrc/lib/clientShareManager.tssrc/components/AddShare.tsxsrc/__tests__/workflows/keyset-creation.test.tssrc/__tests__/workflows/share-lifecycle.test.tsSECURITY_AUDIT_2026-01-06.mdsrc/components/SaveShare.tsxsrc/__tests__/integration/clientShareManager.test.tsCLAUDE.mdsrc/__tests__/components/LoadShare.test.tsx
📚 Learning: 2026-01-02T23:50:29.859Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T23:50:29.859Z
Learning: Applies to src/**/*ipc*.{ts,tsx} : Cover new IPC handlers with unit tests plus at least one scenario in `src/__tests__/integration/`
Applied to files:
src/__tests__/lib/shareManager.test.tssrc/__tests__/components/AddShare.test.tsxsrc/__tests__/lib/igloo-core-integration.test.tssrc/__tests__/integration/userInputValidation.test.tssrc/__tests__/lib/echoRelays.test.tssrc/__tests__/components/Recover.test.tsxsrc/__tests__/setup.tssrc/__tests__/components/SaveShare.test.tsxsrc/lib/clientShareManager.tssrc/components/AddShare.tsxsrc/__tests__/integration/electron-security.test.tssrc/__tests__/integration/computeRelayPlan.test.tssrc/__tests__/lib/validation.test.tssrc/__tests__/workflows/share-lifecycle.test.tsSECURITY_AUDIT_2026-01-06.mdsrc/__tests__/integration/clientShareManager.test.tssrc/__tests__/components/Signer.test.tsxsrc/main.tssrc/__tests__/components/LoadShare.test.tsx
📚 Learning: 2026-01-02T23:50:29.859Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T23:50:29.859Z
Learning: Applies to src/__tests__/**/*.{ts,tsx} : Tests mirror runtime code under `src/__tests__/` with `integration/`, `performance/`, and `__mocks__/` subdirectories for feature-specific coverage
Applied to files:
src/__tests__/lib/shareManager.test.tssrc/__tests__/components/AddShare.test.tsxsrc/__tests__/lib/igloo-core-integration.test.tssrc/__tests__/lib/echoRelays.test.tssrc/__tests__/components/Recover.test.tsxsrc/__tests__/setup.tssrc/__tests__/components/SaveShare.test.tsxsrc/__tests__/integration/electron-security.test.tssrc/__tests__/integration/computeRelayPlan.test.tssrc/__tests__/lib/validation.test.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/__tests__/integration/clientShareManager.test.tssrc/__tests__/components/Signer.test.tsxsrc/__tests__/components/LoadShare.test.tsxtsconfig.test.json
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/__tests__/__mocks__/**/*.ts : Place shared mock implementations in __tests__/__mocks__/ for use across test files
Applied to files:
src/__tests__/lib/shareManager.test.tssrc/__tests__/components/AddShare.test.tsxsrc/__tests__/lib/igloo-core-integration.test.tssrc/__tests__/__mocks__/bifrost.mock.tssrc/__tests__/setup.tssrc/__tests__/components/SaveShare.test.tsxsrc/__tests__/workflows/keyset-creation.test.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/__tests__/integration/clientShareManager.test.tstsconfig.test.json
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/__tests__/integration/**/*.test.{ts,tsx} : Test Electron IPC communication in __tests__/integration/ directory
Applied to files:
src/__tests__/lib/shareManager.test.tssrc/__tests__/components/AddShare.test.tsxsrc/__tests__/lib/igloo-core-integration.test.tssrc/__tests__/integration/userInputValidation.test.tssrc/__tests__/lib/echoRelays.test.tssrc/__tests__/components/Recover.test.tsxsrc/__tests__/setup.tssrc/lib/clientShareManager.tssrc/components/AddShare.tsxsrc/__tests__/integration/electron-security.test.tssrc/__tests__/integration/computeRelayPlan.test.tssrc/preload.tssrc/__tests__/lib/validation.test.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/__tests__/integration/clientShareManager.test.tsCLAUDE.mdsrc/main.tssrc/__tests__/components/LoadShare.test.tsx
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/__tests__/**/*.test.{ts,tsx} : Mock frostr/igloo-core functions at the module level in tests to avoid ESM/Jest complications
Applied to files:
src/__tests__/lib/shareManager.test.tspackage.jsonsrc/__tests__/components/AddShare.test.tsxsrc/__tests__/lib/igloo-core-integration.test.tssrc/__tests__/__mocks__/bifrost.mock.tssrc/__tests__/lib/echoRelays.test.tssrc/__tests__/components/Recover.test.tsxsrc/__tests__/setup.tssrc/__tests__/workflows/keyset-creation.test.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/__tests__/integration/clientShareManager.test.tssrc/__tests__/components/Signer.test.tsxtsconfig.test.json
📚 Learning: 2026-01-02T23:50:29.859Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T23:50:29.859Z
Learning: PRs should describe the change set, include screenshots or recordings for UI tweaks, and list run commands (`npm test`, `npm run lint`)
Applied to files:
package.json
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/main.ts : Electron's main process uses CommonJS (require) while renderer uses ESM (import)
Applied to files:
package.jsonwebpack.config.cjssrc/__tests__/setup.tssrc/__tests__/integration/electron-security.test.tssrc/preload.tsCLAUDE.md
📚 Learning: 2026-01-02T23:50:29.859Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T23:50:29.859Z
Learning: Applies to src/main.ts : Main Electron process lives in `src/main.ts`; the renderer bootstraps from `src/renderer.tsx`
Applied to files:
package.jsonwebpack.config.cjssrc/__tests__/integration/electron-security.test.tssrc/preload.tsCLAUDE.md
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/__tests__/**/*.test.{ts,tsx} : Mock Electron's ipcRenderer and app APIs in tests
Applied to files:
src/__tests__/components/AddShare.test.tsxwebpack.config.cjssrc/__tests__/components/Recover.test.tsxsrc/__tests__/setup.tssrc/__tests__/integration/electron-security.test.tssrc/__tests__/integration/computeRelayPlan.test.tssrc/preload.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/__tests__/integration/clientShareManager.test.tssrc/__tests__/components/Signer.test.tsxsrc/main.ts
📚 Learning: 2026-01-02T23:50:29.859Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T23:50:29.859Z
Learning: Applies to src/__tests__/{setup.ts,__mocks__/**} : Register shared mocks in `src/__tests__/setup.ts` and reuse fixtures from `src/__tests__/__mocks__/`
Applied to files:
src/__tests__/components/AddShare.test.tsxsrc/__tests__/lib/igloo-core-integration.test.tssrc/__tests__/__mocks__/bifrost.mock.tssrc/__tests__/components/Recover.test.tsxsrc/__tests__/setup.tssrc/__tests__/components/SaveShare.test.tsxsrc/__tests__/workflows/keyset-creation.test.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/__tests__/integration/clientShareManager.test.tssrc/__tests__/components/Signer.test.tsx
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/__tests__/**/*.test.{ts,tsx} : Use jest.clearAllMocks() in beforeEach hooks to ensure test isolation
Applied to files:
src/__tests__/components/AddShare.test.tsxsrc/__tests__/components/Recover.test.tsxsrc/__tests__/setup.tssrc/__tests__/workflows/keyset-creation.test.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/__tests__/integration/clientShareManager.test.tstsconfig.test.json
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/__tests__/components/**/*.test.{ts,tsx} : Test React component behavior in __tests__/components/ directory
Applied to files:
src/__tests__/components/AddShare.test.tsxsrc/__tests__/components/Recover.test.tsxsrc/__tests__/components/SaveShare.test.tsxsrc/__tests__/integration/electron-security.test.tssrc/__tests__/components/LoadShare.test.tsxtsconfig.test.json
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/lib/encryption.ts : Use PBKDF2 with 600,000 iterations for encrypting share files
Applied to files:
src/components/LoadShare.tsxsrc/__tests__/__mocks__/bifrost.mock.tssrc/components/SaveShare.tsx
📚 Learning: 2026-01-02T23:50:29.859Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T23:50:29.859Z
Learning: Applies to src/**/*.{ts,tsx} : Import third-party packages before internal modules and use the `@/` alias for local paths
Applied to files:
webpack.config.cjstsconfig.preload.jsonCLAUDE.mdtsconfig.test.json
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to **/*.{ts,tsx} : Use @/ path alias for imports instead of relative paths
Applied to files:
webpack.config.cjstsconfig.test.json
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/__tests__/workflows/**/*.test.{ts,tsx} : Test end-to-end user flows in __tests__/workflows/ directory
Applied to files:
src/__tests__/lib/echoRelays.test.tssrc/__tests__/components/SaveShare.test.tsxsrc/__tests__/workflows/share-lifecycle.test.ts
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Do not implement cryptographic logic in the desktop app; delegate all crypto operations to frostr/igloo-core
Applied to files:
src/components/Signer.tsxsrc/components/AddShare.tsxCLAUDE.md
📚 Learning: 2026-01-02T23:50:29.859Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T23:50:29.859Z
Learning: Applies to src/**/*.test.{ts,tsx} : Jest with Testing Library powers renderer specs; place new tests beside features as `<subject>.test.tsx`
Applied to files:
src/__tests__/components/Recover.test.tsxsrc/__tests__/setup.tssrc/__tests__/integration/electron-security.test.tssrc/__tests__/lib/validation.test.tssrc/__tests__/components/Signer.test.tsxtsconfig.test.json
📚 Learning: 2026-01-02T23:50:29.859Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T23:50:29.859Z
Learning: Debug flaky Electron tests with `npm test -- --runInBand` to serialize execution
Applied to files:
src/__tests__/setup.tssrc/__tests__/integration/electron-security.test.tssrc/__tests__/workflows/share-lifecycle.test.ts
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/components/**/*.tsx : Use ipcRenderer.invoke() in renderer process to call IPC handlers without direct file system access
Applied to files:
src/__tests__/setup.tssrc/components/Keyset.tsxsrc/lib/clientShareManager.tssrc/__tests__/integration/electron-security.test.tssrc/__tests__/integration/computeRelayPlan.test.tssrc/preload.tssrc/__tests__/integration/clientShareManager.test.tssrc/main.ts
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/main.ts : Register IPC handlers in main.ts using ipcMain.handle() for file system operations
Applied to files:
src/components/Keyset.tsxsrc/lib/clientShareManager.tssrc/__tests__/integration/electron-security.test.tssrc/__tests__/integration/computeRelayPlan.test.tssrc/preload.tssrc/main.ts
📚 Learning: 2026-01-02T23:50:29.859Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T23:50:29.859Z
Learning: Applies to src/**/*.{ts,tsx} : All runtime code is TypeScript with two-space indentation and required semicolons
Applied to files:
tsconfig.preload.jsontsconfig.test.json
📚 Learning: 2026-01-02T23:50:29.859Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T23:50:29.859Z
Learning: Applies to src/{components,lib,types}/**/*.{ts,tsx} : UI components sit under `src/components/`, helpers in `src/lib/`, shared types in `src/types/`
Applied to files:
CLAUDE.mdtsconfig.test.json
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Use props and callbacks for component communication instead of external state libraries like Redux
Applied to files:
CLAUDE.md
🧬 Code graph analysis (16)
src/components/LoadShare.tsx (1)
src/lib/validation.ts (2)
VALIDATION_LIMITS(4-15)sanitizeUserError(432-458)
src/components/Recover.tsx (1)
src/lib/validation.ts (1)
VALIDATION_LIMITS(4-15)
src/__tests__/lib/echoRelays.test.ts (1)
src/lib/echoRelays.ts (1)
computeRelayPlan(151-227)
src/lib/echoRelays.ts (1)
src/preload.ts (1)
RelayPlan(14-21)
src/components/Create.tsx (1)
src/lib/validation.ts (3)
validateShareName(389-419)VALIDATION_LIMITS(4-15)validatePositiveInteger(335-369)
src/components/Keyset.tsx (1)
src/components/ui/button.tsx (1)
Button(56-56)
src/__tests__/components/SaveShare.test.tsx (1)
src/lib/encryption.ts (1)
derive_secret_async(24-73)
src/lib/clientShareManager.ts (1)
src/types/index.ts (1)
IglooShare(44-55)
src/components/AddShare.tsx (2)
src/lib/validation.ts (2)
VALIDATION_LIMITS(4-15)sanitizeUserError(432-458)src/types/index.ts (1)
DecodedGroup(9-19)
src/__tests__/integration/computeRelayPlan.test.ts (2)
webpack.config.cjs (1)
path(1-1)src/__tests__/setup.ts (1)
mockElectronAPI(191-191)
src/preload.ts (1)
src/lib/echoRelays.ts (1)
RelayPlan(134-141)
src/__tests__/lib/validation.test.ts (1)
src/lib/validation.ts (7)
VALIDATION_LIMITS(4-15)validatePassword(32-49)validatePasswordLength(467-487)validatePositiveInteger(335-369)validateShareName(389-419)sanitizeUserError(432-458)formatRelayUrl(230-304)
src/__tests__/workflows/share-lifecycle.test.ts (2)
src/__tests__/setup.ts (2)
mockElectronAPI(191-191)mockDeriveSecret(136-136)src/lib/clientShareManager.ts (1)
clientShareManager(98-98)
src/components/SaveShare.tsx (1)
src/lib/validation.ts (1)
VALIDATION_LIMITS(4-15)
src/__tests__/integration/clientShareManager.test.ts (2)
src/__tests__/setup.ts (1)
mockElectronAPI(191-191)src/lib/clientShareManager.ts (1)
clientShareManager(98-98)
src/main.ts (1)
src/lib/echoRelays.ts (1)
computeRelayPlan(151-227)
🪛 LanguageTool
SECURITY_AUDIT_2026-01-06.md
[grammar] ~269-~269: Use a hyphen to join words.
Context: ...m invalid threshold values --- ## High Severity Issues ### 6. ✅ FIXED: Insecur...
(QB_NEW_EN_HYPHEN)
[grammar] ~838-~838: Use a hyphen to join words.
Context: ...")` = NaN silently accepted --- ## Low Severity Issues ### 33. ✅ FIXED: No IPC...
(QB_NEW_EN_HYPHEN)
[grammar] ~976-~976: Use a hyphen to join words.
Context: ...ion fixes covering all critical and high severity React component validation issu...
(QB_NEW_EN_HYPHEN)
There was a problem hiding this comment.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/main.ts (2)
459-470: Remove unusederrvariable to fix ESLint warning.The pipeline reports that
erris defined but never used on line 464.🔧 Suggested fix
try { existing?.cleanup?.(); - } catch (err) { + } catch { console.warn('[EchoBridge] Listener cleanup failed on sender destroyed', { listenerId }); } finally {
495-504: Remove unusederrvariable to fix ESLint warning.The pipeline reports that
erris defined but never used on line 499.🔧 Suggested fix
try { existing.cleanup?.(); - } catch (err) { + } catch { console.warn('[EchoBridge] Listener cleanup failed on stop', { listenerId }); } finally {
🤖 Fix all issues with AI agents
In @src/components/AddShare.tsx:
- Around line 419-433: The renderer is reading process.env.IGLOO_DEBUG_ECHO
directly (debugEnv/debugEnabled) which fails under contextIsolation; move debug
detection into the main process and pass it via IPC instead: add a debugEnabled
boolean to the computeRelayPlan IPC response in the main handler (same pattern
used for IGLOO_RELAY), then consume that debugEnabled value in AddShare.tsx when
building the eventConfig for sendEcho so you no longer access process.env from
the renderer; update the sendEcho call site to use the injected debugEnabled
flag and remove direct usage of debugEnv/debugEnabled variables in the renderer.
In @src/main.ts:
- Around line 425-434: The catch block around existing?.cleanup in the
activeEchoListeners handling defines an unused error parameter (err), causing an
ESLint warning; remove the unused parameter by changing the catch signature from
catch (err) to catch { ... } (or rename to catch (_err) if you prefer explicit
unused naming) and keep the existing console.warn('[EchoBridge] Failed to
cleanup existing listener during start', { listenerId }); and the finally block
that deletes from activeEchoListeners to preserve behavior.
- Around line 33-44: The regexes in sanitizeErrorForLog contain unnecessary
backslashes (e.g. '\/' and '[^\/]') that ESLint flags; update each .replace
regex to remove needless escapes for forward slashes and similar characters
while preserving required escapes for backslashes (\\) and quote delimiters.
Specifically, edit the four patterns in sanitizeErrorForLog (the first replace's
/(['"])(\/(?:[^\/]+\/)+)([^\/'"]*)\1/g, the second
/\/(?:[^\/\s:]+\/)+([^\/\s:]+)/g, the third
/(['"])([A-Za-z]:\\(?:[^\\]+\\)+)([^\\'"]*)(\1)/g, and the fourth
/[A-Za-z]:\\(?:[^\\:\s]+\\)+([^\\:\s]+)/g) to use unescaped forward slashes
inside character classes and sequences (e.g. use [^/]+ instead of [^\/]+, and
/\/.../ occurrences inside character classes removed) while keeping backslash
escapes intact for Windows paths.
In @src/preload.ts:
- Line 121: The handler references Electron.IpcRendererEvent but the Electron
types are not imported; import the correct type and update the handler signature
accordingly—add a top-level import like "import type { IpcRendererEvent } from
'electron'" (or "import * as Electron from 'electron'" if you prefer the
namespace) and change the handler parameter from "(_event:
Electron.IpcRendererEvent, data: unknown)" to "(_event: IpcRendererEvent, data:
unknown)" (or keep Electron.IpcRendererEvent if using the namespace import) so
TypeScript/linters recognize the type.
- Line 141: The handler parameter uses the Electron type
Electron.IpcRendererEvent which isn't imported; add the proper Electron type
import in src/preload.ts (e.g., import or import type for IpcRendererEvent from
'electron') and update any existing import statement used at the top of the file
so that Electron.IpcRendererEvent is resolved for the handler function named
handler.
🧹 Nitpick comments (1)
src/lib/echoRelays.ts (1)
170-180: Consider extracting shared deduplication logic.The
dedupefunction duplicates the deduplication logic fromnormalizeList. While the separation makes sense (one normalizes + dedupes, one only dedupes), you could extract the pure deduplication into a shared helper to reduce duplication.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (10)
src/__tests__/components/AddShare.test.tsxsrc/__tests__/integration/computeRelayPlan.test.tssrc/__tests__/integration/electron-security.test.tssrc/__tests__/lib/ipcSchemas.test.tssrc/components/AddShare.tsxsrc/lib/echoRelays.tssrc/lib/ipcSchemas.tssrc/main.tssrc/preload.tssrc/types/index.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- src/tests/components/AddShare.test.tsx
🧰 Additional context used
📓 Path-based instructions (13)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Use strict TypeScript mode with explicit types for function parameters and returns
Prefer interfaces over types for defining object shapes in TypeScript
Use @/ path alias for imports instead of relative paths
Use camelCase for functions and variables
Use UPPER_SNAKE_CASE for constants
Files:
src/components/AddShare.tsxsrc/__tests__/lib/ipcSchemas.test.tssrc/main.tssrc/lib/echoRelays.tssrc/types/index.tssrc/lib/ipcSchemas.tssrc/__tests__/integration/electron-security.test.tssrc/__tests__/integration/computeRelayPlan.test.tssrc/preload.ts
src/components/[A-Z]*.tsx
📄 CodeRabbit inference engine (CLAUDE.md)
Use PascalCase for component files
Files:
src/components/AddShare.tsx
src/components/**/*.tsx
📄 CodeRabbit inference engine (CLAUDE.md)
src/components/**/*.tsx: Use Tailwind CSS utility classes in JSX and use cn() utility for conditional classes
Avoid inline styles unless conditionally computed
Use functional components with hooks instead of class components
Use ipcRenderer.invoke() in renderer process to call IPC handlers without direct file system accessTailwind utility classes style JSX; reserve inline styles for dynamic values only
Files:
src/components/AddShare.tsx
src/{components,lib,types}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
UI components sit under
src/components/, helpers insrc/lib/, shared types insrc/types/
Files:
src/components/AddShare.tsxsrc/lib/echoRelays.tssrc/types/index.tssrc/lib/ipcSchemas.ts
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/**/*.{ts,tsx}: All runtime code is TypeScript with two-space indentation and required semicolons
Import third-party packages before internal modules and use the@/alias for local paths
Files:
src/components/AddShare.tsxsrc/__tests__/lib/ipcSchemas.test.tssrc/main.tssrc/lib/echoRelays.tssrc/types/index.tssrc/lib/ipcSchemas.tssrc/__tests__/integration/electron-security.test.tssrc/__tests__/integration/computeRelayPlan.test.tssrc/preload.ts
src/components/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/components/**/*.{ts,tsx}: Prefer functional React components; name them in PascalCase and helpers in camelCase
Components insrc/components/follow kebab-case filenames (e.g.,share-list.tsx)
Files:
src/components/AddShare.tsx
src/__tests__/**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
src/__tests__/**/*.test.{ts,tsx}: Mock @frostr/igloo-core functions at the module level in tests to avoid ESM/Jest complications
Use jest.clearAllMocks() in beforeEach hooks to ensure test isolation
Mock Electron's ipcRenderer and app APIs in tests
Files:
src/__tests__/lib/ipcSchemas.test.tssrc/__tests__/integration/electron-security.test.tssrc/__tests__/integration/computeRelayPlan.test.ts
src/__tests__/lib/**/*.test.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Test utility functions in tests/lib/ directory
Files:
src/__tests__/lib/ipcSchemas.test.ts
src/__tests__/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Tests mirror runtime code under
src/__tests__/withintegration/,performance/, and__mocks__/subdirectories for feature-specific coverage
Files:
src/__tests__/lib/ipcSchemas.test.tssrc/__tests__/integration/electron-security.test.tssrc/__tests__/integration/computeRelayPlan.test.ts
src/**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Jest with Testing Library powers renderer specs; place new tests beside features as
<subject>.test.tsx
Files:
src/__tests__/lib/ipcSchemas.test.tssrc/__tests__/integration/electron-security.test.tssrc/__tests__/integration/computeRelayPlan.test.ts
src/**/*ipc*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Cover new IPC handlers with unit tests plus at least one scenario in
src/__tests__/integration/
Files:
src/__tests__/lib/ipcSchemas.test.tssrc/lib/ipcSchemas.ts
src/main.ts
📄 CodeRabbit inference engine (CLAUDE.md)
src/main.ts: Register IPC handlers in main.ts using ipcMain.handle() for file system operations
Electron's main process uses CommonJS (require) while renderer uses ESM (import)Main Electron process lives in
src/main.ts; the renderer bootstraps fromsrc/renderer.tsx
Files:
src/main.ts
src/__tests__/integration/**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Test Electron IPC communication in tests/integration/ directory
Files:
src/__tests__/integration/electron-security.test.tssrc/__tests__/integration/computeRelayPlan.test.ts
🧠 Learnings (18)
📓 Common learnings
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T23:50:29.859Z
Learning: Applies to src/**/*ipc*.{ts,tsx} : Cover new IPC handlers with unit tests plus at least one scenario in `src/__tests__/integration/`
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/lib/shareManager.ts : Never store plaintext share data; always encrypt with user passwords
Applied to files:
src/components/AddShare.tsx
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/lib/shareManager.ts : Store shares in <appData>/igloo/shares/ directory using the defined JSON schema
Applied to files:
src/components/AddShare.tsxsrc/__tests__/lib/ipcSchemas.test.tssrc/main.tssrc/lib/ipcSchemas.ts
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/__tests__/integration/**/*.test.{ts,tsx} : Test Electron IPC communication in __tests__/integration/ directory
Applied to files:
src/components/AddShare.tsxsrc/__tests__/lib/ipcSchemas.test.tssrc/main.tssrc/__tests__/integration/electron-security.test.tssrc/__tests__/integration/computeRelayPlan.test.tssrc/preload.ts
📚 Learning: 2026-01-02T23:50:29.859Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T23:50:29.859Z
Learning: Applies to src/**/*ipc*.{ts,tsx} : Cover new IPC handlers with unit tests plus at least one scenario in `src/__tests__/integration/`
Applied to files:
src/components/AddShare.tsxsrc/__tests__/lib/ipcSchemas.test.tssrc/main.tssrc/lib/ipcSchemas.tssrc/__tests__/integration/electron-security.test.tssrc/__tests__/integration/computeRelayPlan.test.tssrc/preload.ts
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Do not implement cryptographic logic in the desktop app; delegate all crypto operations to frostr/igloo-core
Applied to files:
src/components/AddShare.tsx
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/__tests__/lib/**/*.test.ts : Test utility functions in __tests__/lib/ directory
Applied to files:
src/__tests__/lib/ipcSchemas.test.tssrc/__tests__/integration/electron-security.test.tssrc/__tests__/integration/computeRelayPlan.test.ts
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/__tests__/**/*.test.{ts,tsx} : Mock Electron's ipcRenderer and app APIs in tests
Applied to files:
src/__tests__/lib/ipcSchemas.test.tssrc/__tests__/integration/electron-security.test.tssrc/__tests__/integration/computeRelayPlan.test.tssrc/preload.ts
📚 Learning: 2026-01-02T23:50:29.859Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T23:50:29.859Z
Learning: Applies to src/__tests__/**/*.{ts,tsx} : Tests mirror runtime code under `src/__tests__/` with `integration/`, `performance/`, and `__mocks__/` subdirectories for feature-specific coverage
Applied to files:
src/__tests__/lib/ipcSchemas.test.tssrc/__tests__/integration/electron-security.test.tssrc/__tests__/integration/computeRelayPlan.test.ts
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/main.ts : Register IPC handlers in main.ts using ipcMain.handle() for file system operations
Applied to files:
src/main.tssrc/__tests__/integration/electron-security.test.tssrc/__tests__/integration/computeRelayPlan.test.tssrc/preload.ts
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/main.ts : Electron's main process uses CommonJS (require) while renderer uses ESM (import)
Applied to files:
src/__tests__/integration/electron-security.test.tssrc/preload.ts
📚 Learning: 2026-01-02T23:50:29.859Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T23:50:29.859Z
Learning: Applies to src/main.ts : Main Electron process lives in `src/main.ts`; the renderer bootstraps from `src/renderer.tsx`
Applied to files:
src/__tests__/integration/electron-security.test.tssrc/preload.ts
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/__tests__/components/**/*.test.{ts,tsx} : Test React component behavior in __tests__/components/ directory
Applied to files:
src/__tests__/integration/electron-security.test.ts
📚 Learning: 2026-01-02T23:50:29.859Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T23:50:29.859Z
Learning: Applies to src/**/*.test.{ts,tsx} : Jest with Testing Library powers renderer specs; place new tests beside features as `<subject>.test.tsx`
Applied to files:
src/__tests__/integration/electron-security.test.ts
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/__tests__/workflows/**/*.test.{ts,tsx} : Test end-to-end user flows in __tests__/workflows/ directory
Applied to files:
src/__tests__/integration/electron-security.test.ts
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/components/**/*.tsx : Use ipcRenderer.invoke() in renderer process to call IPC handlers without direct file system access
Applied to files:
src/__tests__/integration/electron-security.test.tssrc/__tests__/integration/computeRelayPlan.test.tssrc/preload.ts
📚 Learning: 2026-01-02T23:50:29.859Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T23:50:29.859Z
Learning: Debug flaky Electron tests with `npm test -- --runInBand` to serialize execution
Applied to files:
src/__tests__/integration/electron-security.test.ts
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/__tests__/**/*.test.{ts,tsx} : Mock frostr/igloo-core functions at the module level in tests to avoid ESM/Jest complications
Applied to files:
src/__tests__/integration/electron-security.test.ts
🧬 Code graph analysis (7)
src/components/AddShare.tsx (2)
src/lib/validation.ts (2)
VALIDATION_LIMITS(4-15)sanitizeUserError(432-458)src/types/index.ts (1)
DecodedGroup(9-19)
src/__tests__/lib/ipcSchemas.test.ts (1)
src/lib/ipcSchemas.ts (9)
ShareIdSchema(14-17)HexSaltSchema(20-23)RelayUrlSchema(26-26)ShareCredentialSchema(29-31)GroupCredentialSchema(34-36)SaveShareSchema(39-67)RelayPlanArgsSchema(70-75)EchoStartArgsSchema(78-87)EchoStopArgsSchema(90-94)
src/main.ts (2)
src/lib/echoRelays.ts (1)
computeRelayPlan(143-219)src/lib/ipcSchemas.ts (5)
SaveShareSchema(39-67)ShareIdSchema(14-17)RelayPlanArgsSchema(70-75)EchoStartArgsSchema(78-87)EchoStopArgsSchema(90-94)
src/lib/echoRelays.ts (1)
src/types/index.ts (1)
RelayPlan(191-198)
src/__tests__/integration/electron-security.test.ts (1)
webpack.config.cjs (1)
path(1-1)
src/__tests__/integration/computeRelayPlan.test.ts (1)
src/__tests__/setup.ts (1)
mockElectronAPI(191-191)
src/preload.ts (1)
src/types/index.ts (1)
RelayPlan(191-198)
🪛 GitHub Actions: CI
src/main.ts
[warning] 37-37: Unnecessary escape character: / no-useless-escape
[warning] 37-37: Unnecessary escape character: / no-useless-escape
[warning] 39-39: Unnecessary escape character: / no-useless-escape
[warning] 39-39: Unnecessary escape character: / no-useless-escape
[warning] 429-429: 'err' is defined but never used @typescript-eslint/no-unused-vars
[warning] 464-464: 'err' is defined but never used @typescript-eslint/no-unused-vars
[warning] 499-499: 'err' is defined but never used @typescript-eslint/no-unused-vars
src/preload.ts
[error] 121-121: 'Electron' is not defined no-undef
🪛 GitHub Check: Lint and Test (18)
src/preload.ts
[failure] 141-141:
'Electron' is not defined
[failure] 121-121:
'Electron' is not defined
🪛 GitHub Check: Lint and Test (20)
src/preload.ts
[failure] 141-141:
'Electron' is not defined
[failure] 121-121:
'Electron' is not defined
🔇 Additional comments (35)
src/types/index.ts (1)
190-198: LGTM! Clean type definition.The RelayPlan interface is well-structured with clear property names that describe the different relay categories. The interface follows TypeScript conventions and integrates cleanly with the relay planning utilities.
src/preload.ts (2)
56-84: Excellent runtime validation pattern.The type guards (
isEchoReceivedDataandisEchoErrorData) provide strong runtime safety by validating IPC payloads before passing them to renderer callbacks. This prevents malformed data from the main process from causing issues in the renderer.
108-152: Robust event listener implementation.The implementation correctly:
- Validates callbacks before registering handlers
- Returns no-op cleanup functions for invalid callbacks
- Validates incoming data with type guards
- Logs malformed data without crashing
- Provides proper cleanup via
removeListenerThis is a secure and maintainable pattern for IPC event handling.
src/__tests__/lib/ipcSchemas.test.ts (1)
1-444: Excellent comprehensive test coverage.This test suite provides thorough validation coverage for all IPC schemas:
- Tests both valid and invalid inputs
- Verifies boundary conditions (min/max lengths, array sizes)
- Confirms error messages are user-friendly
- Covers optional vs required field handling
- Tests undefined vs null distinctions (important for Zod)
The functional tests provide stronger guarantees than simple regex-based existence checks and will catch schema regressions early.
src/components/AddShare.tsx (3)
127-139: Strengthened name validation.The updated validation correctly enforces the maximum name length using centralized
VALIDATION_LIMITS.NAME_MAX, improving consistency and maintainability. Trimming the input before validation prevents whitespace-only names.
265-270: Improved password validation with maximum length.Adding an upper bound (
VALIDATION_LIMITS.PASSWORD_MAX) prevents potential issues with extremely long passwords that could impact performance or storage. The validation now properly enforces both minimum and maximum constraints.
404-415: Correct IPC pattern for relay planning.Using
window.electronAPI.computeRelayPlanto delegate relay planning to the main process is the right approach. The main process has access to Node.js APIs (environment variables, file system) while keeping the renderer isolated. Error handling correctly propagates failures with user-friendly messages.src/__tests__/integration/computeRelayPlan.test.ts (1)
1-188: Comprehensive integration test coverage.This test suite effectively validates the compute-relay-plan IPC handler from multiple angles:
- Static analysis verifies critical implementation details (env var fallback, input normalization, error handling)
- Client-side integration tests the renderer's interaction with the mocked IPC surface
- Response structure validates the RelayPlan shape matches the type definition
- Preload exposure confirms the API is properly exposed to the renderer
The combination of static and runtime testing provides strong coverage without requiring a full Electron environment. Based on learnings, this aligns with the project's testing strategy for IPC handlers.
src/lib/echoRelays.ts (6)
1-5: LGTM!The imports are well-organized with Node.js core modules using the
node:prefix, external package imports, and internal types using the@/alias per coding guidelines.
19-34: LGTM!The URL normalization logic correctly enforces secure WebSocket connections (
wss://) by upgrading insecure protocols. The regex patterns and replacements are correct.
36-44: LGTM!Good defensive coding with proper handling of environments where
processmay not exist.
69-90: LGTM!Synchronous config file reading is acceptable here since it's called from the main process for small configuration files. Error handling appropriately returns
undefinedfor missing files or parse errors.
92-106: LGTM!The canonicalization logic correctly handles URL normalization with a sensible fallback for malformed URLs.
197-206: LGTM!Excellent security measure ensuring at least one relay is always configured. The fallback chain with appropriate warnings and a final error throw prevents silent failures.
src/__tests__/integration/electron-security.test.ts (8)
1-18: LGTM!Good integration test setup for verifying Electron security configurations. Reading source files to verify security patterns is a pragmatic approach for ensuring security settings aren't accidentally removed.
20-57: LGTM!Comprehensive coverage of critical Electron security settings. These tests act as guardrails against accidentally disabling security features.
59-106: LGTM!Good verification that the preload script follows Electron security best practices by using
contextBridgeand not exposing rawipcRenderer.
109-170: LGTM!Comprehensive CSP verification tests that ensure clickjacking prevention, safe script loading, and proper restrictions on various resource types.
172-195: LGTM!Good enforcement of the secure IPC pattern. These tests ensure renderer code doesn't bypass the security boundary by directly importing Electron APIs.
197-286: LGTM!Comprehensive verification that all IPC handlers use Zod schema validation. This ensures input validation isn't accidentally bypassed.
288-315: LGTM!Good verification that error sanitization is properly implemented to prevent leaking sensitive file paths in logs.
317-370: LGTM!Complete coverage of navigation security and file permission hardening. These tests ensure the app is protected against navigation attacks and files have restrictive permissions.
src/main.ts (6)
6-19: LGTM!Clean imports with proper separation of concerns - importing
computeRelayPlanfor relay logic and IPC schemas for validation. Follows the coding guideline of importing third-party packages before internal modules.
57-74: LGTM!The SimplePool shim is properly guarded with try-catch and uses a flag to prevent double-patching. Good compatibility fix for relay filter handling.
78-162: LGTM!Well-structured echo monitoring with proper relay plan integration and robust callback handling that supports both old and new payload shapes from
@frostr/igloo-core.
262-309: LGTM!Excellent security hardening with:
- Secure
webPreferences(nodeIntegration: false, contextIsolation: true, sandbox: true)- Navigation protection blocking external URLs
- Safe handling of new window requests via system browser
322-336: LGTM!Proper Zod validation pattern with
safeParseand sanitized error logging. Returns appropriate failure response on validation errors.
372-411: LGTM!Well-implemented IPC handler with proper Zod validation, environment variable fallback for sandboxed renderer, and structured response format. Good error handling with sanitized logging.
src/lib/ipcSchemas.ts (7)
1-12: LGTM!Well-structured module with clear documentation explaining the security rationale for input validation schemas.
13-17: LGTM!Good constraints for share IDs - the character restriction prevents path traversal attacks while allowing common identifier formats.
19-23: LGTM!Appropriate salt validation - 32 hex chars (16 bytes) minimum ensures cryptographic adequacy while max 128 prevents excessive allocation.
25-67: LGTM!Comprehensive schema definitions with appropriate length limits for all fields. The
SaveShareSchemaproperly handles nested optional structures including metadata and policy objects.
77-94: LGTM!Good array limits (100 share credentials, 50 relays) to prevent DoS attacks via oversized payloads while still allowing reasonable operational capacity.
96-103: LGTM!Standard pattern for deriving TypeScript types from Zod schemas using
z.infer, enabling type-safe handler implementations.
9-11: Unit test coverage for IPC schemas is comprehensive and verified.The test file
src/__tests__/lib/ipcSchemas.test.tsexists with extensive coverage for all schemas (ShareIdSchema, HexSaltSchema, RelayUrlSchema, ShareCredentialSchema, GroupCredentialSchema, SaveShareSchema, RelayPlanArgsSchema, EchoStartArgsSchema, EchoStopArgsSchema). Each schema is tested with valid inputs, boundary cases, invalid inputs, and format validation, confirming the module's design goal of testing schemas directly with valid/invalid payloads.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (8)
src/lib/signer-keepalive.ts (1)
74-74: LGTM! Clean removal of unused variable.The removal of
selfPubkeyfrom the destructuring is correct, as the variable is never referenced in the function body. The refactored no-peer handling (lines 284-293) now explicitly manages health state instead of pinging self, eliminating the need for this field.💡 Consider making selfPubkey optional in the interface
Since
selfPubkeyis not currently used, consider updating theKeepAliveConfiginterface to make it optional, which would better communicate to callers that this field is not required:interface KeepAliveConfig { node: BifrostNode; groupCredential: string; shareCredential: string; relays: string[]; - selfPubkey: string; + selfPubkey?: string; logger?: KeepAliveLogger; options?: Partial<KeepAliveOptions>; }This change would clarify the API contract and prevent confusion about whether the field needs to be provided.
src/components/Recover.tsx (3)
18-20: Consider using an environment variable for debug flags.While the security comment is helpful, debug flags can accidentally be committed as
true. Consider using a pattern like:const DEBUG_AUTO_POPULATE = import.meta.env.DEV && false;This ensures debug code never runs in production builds.
190-200: Good security practices with room for improvement.The NSEC handling follows good security patterns:
- Masked display by default
- Auto-clear after timeout
- Explicit user action required to reveal
However, consider these enhancements:
- Shorter auto-clear timeout: 60 seconds may be generous for such sensitive data. Consider 30 seconds or less.
- DevTools warning: React state is inspectable via browser DevTools. Consider adding a warning about keeping DevTools closed during recovery.
718-811: LGTM! Comprehensive secure NSEC display.The UI implementation balances security and usability well:
Security features:
- Prominent warning with security best practices
- Masked display by default
- Explicit reveal action required
- Manual clear option
UX features:
- Visual feedback for all actions (copy success/error, reveal/hide)
- Clear iconography with descriptive labels
- Error messages with recovery instructions
Minor suggestion: The conditional className on line 758 could use the
cn()utility for better readability:className={cn( 'flex-1 text-sm', copyError ? 'bg-red-600 hover:bg-red-700' : 'bg-blue-600 hover:bg-blue-700' )}src/preload.ts (1)
17-22: Consider more specific types for the API surface.The
getSharesreturn type (Promise<unknown>) andsaveShareparameter type (unknown) lose compile-time type safety for renderer code. While runtime validation occurs in the main process, explicit types here would catch errors at compile time and improve developer experience.Consider using the actual types (e.g.,
Promise<IglooShare[]>for getShares,IglooSharefor saveShare parameter) or document whyunknownis necessary.🔧 Example with explicit types
+import type { IglooShare } from '@/types'; + export interface ElectronAPI { // Share management - getShares: () => Promise<unknown>; - saveShare: (share: unknown) => Promise<boolean>; + getShares: () => Promise<IglooShare[]>; + saveShare: (share: IglooShare) => Promise<boolean>; deleteShare: (shareId: string) => Promise<boolean>;src/main.ts (2)
25-44: Consider unit tests for the security-critical sanitization logic.The
sanitizeErrorForLogfunction uses complex regex patterns to sanitize file paths. Given its security importance and complexity, dedicated unit tests would help ensure correctness across different path formats and edge cases.#!/bin/bash # Check if sanitizeErrorForLog has test coverage echo "=== Checking for sanitizeErrorForLog tests ===" rg -n "sanitizeErrorForLog" src/__tests__/ -A 3 -B 3
133-162: Consider adding inline documentation for callback signature handling.The
handleCoreCallbackfunction supports multiple callback signatures (3-arg tuple vs. single-arg payload) to maintain compatibility. While the implementation is correct, the complexity could be reduced with better inline documentation explaining which signature corresponds to which igloo-core version or use case.📝 Example documentation
function handleCoreCallback( arg1: number | EchoPayload, arg2?: string | Record<string, unknown>, arg3?: unknown ): void { try { - // Case 1: (subsetIndex: number, shareCredential: string, details?: { challenge?: string }) + // Case 1: Legacy igloo-core signature (v0.1.x-v0.2.x) + // (subsetIndex: number, shareCredential: string, details?: { challenge?: string }) if (typeof arg1 === 'number') { ... } - // Case 2: (payload: { shareIndex, shareCredential, challenge? }) + // Case 2: Modern igloo-core signature (v0.3.x+) + // (payload: { shareIndex, shareCredential, challenge? }) if (isEchoPayload(arg1)) { ... }src/components/AddShare.tsx (1)
395-398: Consider moving LegacyDecodedGroup to types file.The
LegacyDecodedGrouptype is defined inline here. Since it represents a shared IPC contract shape used for relay planning, consider moving it tosrc/types/index.tsalongsideDecodedGroupfor better discoverability and reusability.♻️ Refactor to shared types file
In
src/types/index.ts:export type LegacyDecodedGroup = DecodedGroup & { relayUrls?: string[]; relay_urls?: string[]; };In this file:
+import type { LegacyDecodedGroup } from '@/types'; + const AddShare: React.FC<AddShareProps> = ({ onComplete, onCancel }) => { ... try { ... - type LegacyDecodedGroup = DecodedGroup & { - relayUrls?: string[]; - relay_urls?: string[]; - }; - const legacyGroup = decodedGroup as LegacyDecodedGroup;
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
src/components/AddShare.tsxsrc/components/Recover.tsxsrc/lib/signer-keepalive.tssrc/main.tssrc/preload.ts
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Use strict TypeScript mode with explicit types for function parameters and returns
Prefer interfaces over types for defining object shapes in TypeScript
Use @/ path alias for imports instead of relative paths
Use camelCase for functions and variables
Use UPPER_SNAKE_CASE for constants
Files:
src/preload.tssrc/components/AddShare.tsxsrc/lib/signer-keepalive.tssrc/components/Recover.tsxsrc/main.ts
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/**/*.{ts,tsx}: All runtime code is TypeScript with two-space indentation and required semicolons
Import third-party packages before internal modules and use the@/alias for local paths
Files:
src/preload.tssrc/components/AddShare.tsxsrc/lib/signer-keepalive.tssrc/components/Recover.tsxsrc/main.ts
src/components/[A-Z]*.tsx
📄 CodeRabbit inference engine (CLAUDE.md)
Use PascalCase for component files
Files:
src/components/AddShare.tsxsrc/components/Recover.tsx
src/components/**/*.tsx
📄 CodeRabbit inference engine (CLAUDE.md)
src/components/**/*.tsx: Use Tailwind CSS utility classes in JSX and use cn() utility for conditional classes
Avoid inline styles unless conditionally computed
Use functional components with hooks instead of class components
Use ipcRenderer.invoke() in renderer process to call IPC handlers without direct file system accessTailwind utility classes style JSX; reserve inline styles for dynamic values only
Files:
src/components/AddShare.tsxsrc/components/Recover.tsx
src/{components,lib,types}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
UI components sit under
src/components/, helpers insrc/lib/, shared types insrc/types/
Files:
src/components/AddShare.tsxsrc/lib/signer-keepalive.tssrc/components/Recover.tsx
src/components/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/components/**/*.{ts,tsx}: Prefer functional React components; name them in PascalCase and helpers in camelCase
Components insrc/components/follow kebab-case filenames (e.g.,share-list.tsx)
Files:
src/components/AddShare.tsxsrc/components/Recover.tsx
src/main.ts
📄 CodeRabbit inference engine (CLAUDE.md)
src/main.ts: Register IPC handlers in main.ts using ipcMain.handle() for file system operations
Electron's main process uses CommonJS (require) while renderer uses ESM (import)Main Electron process lives in
src/main.ts; the renderer bootstraps fromsrc/renderer.tsx
Files:
src/main.ts
🧠 Learnings (11)
📓 Common learnings
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T23:50:29.859Z
Learning: Applies to src/**/*ipc*.{ts,tsx} : Cover new IPC handlers with unit tests plus at least one scenario in `src/__tests__/integration/`
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/main.ts : Electron's main process uses CommonJS (require) while renderer uses ESM (import)
Applied to files:
src/preload.tssrc/components/AddShare.tsx
📚 Learning: 2026-01-02T23:50:29.859Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T23:50:29.859Z
Learning: Applies to src/main.ts : Main Electron process lives in `src/main.ts`; the renderer bootstraps from `src/renderer.tsx`
Applied to files:
src/preload.tssrc/components/AddShare.tsx
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/__tests__/**/*.test.{ts,tsx} : Mock Electron's ipcRenderer and app APIs in tests
Applied to files:
src/preload.tssrc/components/AddShare.tsx
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/__tests__/integration/**/*.test.{ts,tsx} : Test Electron IPC communication in __tests__/integration/ directory
Applied to files:
src/preload.tssrc/components/AddShare.tsxsrc/main.ts
📚 Learning: 2026-01-02T23:50:29.859Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T23:50:29.859Z
Learning: Applies to src/**/*ipc*.{ts,tsx} : Cover new IPC handlers with unit tests plus at least one scenario in `src/__tests__/integration/`
Applied to files:
src/preload.tssrc/components/AddShare.tsxsrc/main.ts
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/main.ts : Register IPC handlers in main.ts using ipcMain.handle() for file system operations
Applied to files:
src/preload.tssrc/main.ts
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/components/**/*.tsx : Use ipcRenderer.invoke() in renderer process to call IPC handlers without direct file system access
Applied to files:
src/preload.tssrc/components/AddShare.tsx
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/lib/shareManager.ts : Never store plaintext share data; always encrypt with user passwords
Applied to files:
src/components/AddShare.tsxsrc/components/Recover.tsx
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Do not implement cryptographic logic in the desktop app; delegate all crypto operations to frostr/igloo-core
Applied to files:
src/components/AddShare.tsx
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/lib/shareManager.ts : Store shares in <appData>/igloo/shares/ directory using the defined JSON schema
Applied to files:
src/components/AddShare.tsxsrc/components/Recover.tsxsrc/main.ts
🧬 Code graph analysis (4)
src/preload.ts (1)
src/types/index.ts (1)
RelayPlan(191-198)
src/components/AddShare.tsx (2)
src/lib/validation.ts (2)
VALIDATION_LIMITS(4-15)sanitizeUserError(432-458)src/types/index.ts (1)
DecodedGroup(9-19)
src/components/Recover.tsx (2)
src/lib/validation.ts (1)
VALIDATION_LIMITS(4-15)src/components/ui/button.tsx (1)
Button(56-56)
src/main.ts (2)
src/lib/echoRelays.ts (1)
computeRelayPlan(143-219)src/lib/ipcSchemas.ts (5)
SaveShareSchema(39-67)ShareIdSchema(14-17)RelayPlanArgsSchema(70-75)EchoStartArgsSchema(78-87)EchoStopArgsSchema(90-94)
🔇 Additional comments (21)
src/components/Recover.tsx (10)
7-8: LGTM!Clean addition of icon imports and centralized validation constants to support the secure NSEC display features.
184-187: LGTM!Good improvement to support flexible result messages. Using
nullas the initial state is more idiomatic than an empty string.
328-344: LGTM! Excellent defensive validation.The threshold bounds check prevents potential edge cases where an invalid threshold could break the UI. Using
VALIDATION_LIMITSensures consistency across the codebase.The silent return is acceptable here since invalid thresholds should never occur during normal use (they're validated when the group credential is decoded).
365-365: LGTM!More explicit validation check improves code clarity without changing behavior.
427-445: LGTM!Comprehensive cleanup of NSEC state and timeouts. The
useCallbackwith empty dependencies is correct since all setters are stable.
447-474: LGTM! Excellent error handling.The clipboard copy implementation is robust:
- Proper timeout cleanup prevents multiple concurrent timers
- Resets success state on error to avoid contradictory UI
- User-friendly error messages with fallback instructions
- Auto-clears feedback states for clean UX
476-479: LGTM!Simple, correct state toggle with proper
useCallbackusage.
481-492: LGTM! Proper cleanup implementation.The timeout cleanup on unmount is correct. The
eslint-disablecomment is justified here since refs don't need to be in the dependency array, and accessing.currentin cleanup is the intended pattern.
502-502: LGTM!Consistent with the validation improvement at line 365.
553-594: LGTM! Secure NSEC recovery flow.The implementation properly manages the NSEC lifecycle:
- Clears any previous NSEC before storing the new one
- Resets all UI state for clean display
- Sets up auto-clear timeout for security
- Updates the user when auto-clear occurs
The automatic message update after 60 seconds helps users understand why the NSEC disappeared.
src/preload.ts (2)
57-85: LGTM: Runtime type validation.The type guards properly validate IPC payloads with appropriate handling of optional fields (
shareCredential,challenge). This prevents malformed data from reaching renderer callbacks.
88-154: LGTM: Secure IPC bridge with defensive callback handling.The implementation properly:
- Validates callbacks are functions before registering handlers (lines 118, 138)
- Validates IPC payloads before invoking callbacks (lines 123, 143)
- Returns cleanup functions for proper resource management
- Uses
satisfies ElectronAPIto ensure type compliancesrc/main.ts (5)
184-213: LGTM: Robust relay canonicalization with deduplication.The relay target canonicalization:
- Uses URL parsing with regex fallback for malformed URLs
- Normalizes protocol, hostname, and path components
- Deduplicates relay sets to prevent redundant listeners
This prevents cross-contamination between listener instances.
266-309: LGTM: Comprehensive Electron security hardening.The security configuration properly:
- Disables Node.js integration in renderer (line 268)
- Enables context isolation (line 269)
- Enables Chromium sandbox (line 270)
- Blocks navigation to external URLs (lines 291-296)
- Opens external links in system browser, not new Electron windows (lines 301-307)
These settings align with Electron security best practices.
322-370: LGTM: Input validation and error sanitization in IPC handlers.The IPC handlers properly:
- Validate inputs with Zod schemas before processing (lines 325, 341, 357)
- Log validation failures with specific issues (lines 328, 344, 360)
- Sanitize errors before logging (lines 333, 349, 367)
- Return appropriate responses for validation failures
This pattern provides defense-in-depth against malicious or malformed inputs.
413-482: LGTM: echo-start handler with validation and cleanup.The handler properly:
- Validates inputs with
EchoStartArgsSchema(line 415)- Cleans up existing listeners before creating new ones (lines 425-434)
- Normalizes and filters share credentials (lines 437-440)
- Registers cleanup on sender destruction (lines 459-470)
- Sanitizes errors in logs (line 479)
372-411: Add unit tests for compute-relay-plan IPC handlerIntegration tests for the handler exist (
src/__tests__/integration/computeRelayPlan.test.ts), but unit tests are missing. The learning requirement specifies both unit tests and integration test scenarios.The handler implementation is solid with proper validation via
RelayPlanArgsSchema, input normalization, env var fallback toprocess.env.IGLOO_RELAY, and error sanitization. Add unit tests covering:
- Input validation success/failure paths
- Each field normalization (trim, filter empty)
- Env var fallback logic
- Error handling
⛔ Skipped due to learnings
Learnt from: CR Repo: FROSTR-ORG/igloo-desktop PR: 0 File: AGENTS.md:0-0 Timestamp: 2026-01-02T23:50:29.859Z Learning: Applies to src/**/*ipc*.{ts,tsx} : Cover new IPC handlers with unit tests plus at least one scenario in `src/__tests__/integration/`Learnt from: CR Repo: FROSTR-ORG/igloo-desktop PR: 0 File: CLAUDE.md:0-0 Timestamp: 2026-01-02T23:50:16.045Z Learning: Applies to src/__tests__/integration/**/*.test.{ts,tsx} : Test Electron IPC communication in __tests__/integration/ directoryLearnt from: CR Repo: FROSTR-ORG/igloo-desktop PR: 0 File: CLAUDE.md:0-0 Timestamp: 2026-01-02T23:50:16.045Z Learning: Applies to src/components/**/*.tsx : Use ipcRenderer.invoke() in renderer process to call IPC handlers without direct file system accesssrc/components/AddShare.tsx (4)
125-154: LGTM: Share name validation with proper limits.The validation correctly:
- Trims input before checking (line 127)
- Enforces required field (lines 129-133)
- Applies max length from
VALIDATION_LIMITS.NAME_MAX(lines 135-139)- Prevents duplicates using normalized names (lines 141-147)
196-200: LGTM: Sanitized error messages for decode failures.Using
sanitizeUserErrorfor group and share decode errors (lines 198, 249) prevents exposing internal implementation details to users while providing helpful feedback.Also applies to: 246-251
259-274: LGTM: Password validation with updated limits.Password validation properly enforces:
- Minimum length via
VALIDATION_LIMITS.PASSWORD_MIN(line 265)- Maximum length via
VALIDATION_LIMITS.PASSWORD_MAX(line 268)- Clear error messages for each constraint
404-421: LGTM: Relay plan computation via secure IPC bridge.The implementation correctly:
- Computes relay plan via
window.electronAPI.computeRelayPlan(lines 404-409)- Passes group credential and decoded group for IPC serialization (lines 405-408)
- Handles failures by throwing with the provided message (lines 411-413)
- Uses computed relays for echo send with timeout (lines 417-419)
The environment variable access limitation (line 420 comment) is accurate since the renderer process cannot access
process.envdue tocontextIsolation: true.
|
@CodeRabbit full review |
✅ Actions performedFull review triggered. |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In @SECURITY_AUDIT_2026-01-06.md:
- Line 1031: Update the stale "3 critical issues requiring attention (#3, #4, #5
- React input validation)" note at line content and replace it with an accurate
statement that reflects the remediation status (e.g., "all 5 critical issues
have been fixed" or remove the parenthetical list entirely); ensure the
"Remaining Work" summary and any references to critical issue numbers are
consistent with the remediation section so the document no longer reports
resolved critical issues as open.
In @src/lib/ipcSchemas.ts:
- Around line 25-26: RelayUrlSchema currently only checks length; you must
enforce URL format and SSRF protection by either adding .refine(isValidRelayUrl)
to RelayUrlSchema so parsing validates each relay, or explicitly calling
isValidRelayUrl (and/or formatRelayUrl) for each relay after schema parsing in
the compute-relay-plan handler before passing to computeRelayPlan(); also remove
the unused relays field from EchoStartArgsSchema (and the echo-start handler) if
it’s truly dead code, and ensure normalizeRelayUrl remains only for protocol
normalization and not relied on for security checks.
In @src/lib/validation.ts:
- Around line 410-411: The current normalization uses trimmed.split(' share
')[0], which naively chops at any " share " occurrence and will incorrectly
shorten names like "My share backup"; update the logic that assigns normalized
(based on trimmed) to only strip a specific trailing suffix pattern instead of
splitting anywhere—e.g., remove a trailing " share" or " share backup"
(case-insensitive) only when it appears at the end, then re-trim; locate the
assignment to normalized and replace the split-based approach with a
suffix-aware regex or string-endsWith check operating on trimmed.
🧹 Nitpick comments (14)
src/__tests__/lib/igloo-core-integration.test.ts (1)
1-4: LGTM! Consider adding brief JSDoc comments.The helper functions correctly generate deterministic hex strings with appropriate lengths (64 chars for scalars, 66 chars for compressed points). The implementation is clean and serves the testing purpose well.
📝 Optional: Add JSDoc for clarity
+// Helper to generate realistic 64-char hex strings for scalar values (e.g., secret keys, nonces) const toScalarHex = (seed: number): string => seed.toString(16).padStart(64, '0'); +// Helper to generate realistic 66-char hex strings for public points (compressed EC point format) const toPointHex = (seed: number): string => '02' + seed.toString(16).padStart(64, '0');src/__tests__/integration/userInputValidation.test.ts (1)
2-3: Consider using @/ path alias for imports.Per coding guidelines, prefer
@/path alias over relative paths for internal imports.Suggested change
-import { validatePassword, formatRelayUrl, isValidRelayUrl, validateSalt, isValidSalt } from '../../lib/validation'; -import { sanitizeShareFilename, isFilenameSafe, FILESYSTEM_LIMITS } from '../../lib/filesystem'; +import { validatePassword, formatRelayUrl, isValidRelayUrl, validateSalt, isValidSalt } from '@/lib/validation'; +import { sanitizeShareFilename, isFilenameSafe, FILESYSTEM_LIMITS } from '@/lib/filesystem';src/__tests__/workflows/share-lifecycle.test.ts (1)
5-6: Consider importingtoScalarHexfrom shared mock.This helper duplicates the one in
bifrost.mock.ts. Import from the shared mock to maintain DRY principle.Suggested change
+import { toScalarHex } from '../__mocks__/bifrost.mock'; + -// Helper to generate realistic 64-char hex strings for scalar values -const toScalarHex = (seed: number): string => seed.toString(16).padStart(64, '0');Note: This requires exporting
toScalarHexfrombifrost.mock.ts(currently it's a file-scopedconst).src/lib/ipcSchemas.ts (1)
70-75:decodedGroupaccepts any object structure.
z.record(z.unknown())is very permissive. IfdecodedGrouphas a known structure, consider defining a stricter schema to catch malformed inputs at the IPC boundary.Consider typing decodedGroup more strictly
If the decoded group has a known shape:
const DecodedGroupSchema = z.object({ threshold: z.number().int().min(1), commits: z.array(z.object({ idx: z.number().int(), pubkey: z.string(), hidden_pn: z.string(), binder_pn: z.string(), })), group_pk: z.string(), }).optional();src/__tests__/lib/validation.test.ts (1)
8-16: Import uses relative path instead of@/alias.Per coding guidelines, prefer
@/path alias for imports instead of relative paths.Suggested import style
-import { - VALIDATION_LIMITS, - validatePassword, - validatePositiveInteger, - validateShareName, - sanitizeUserError, - validatePasswordLength, - formatRelayUrl, -} from '../../lib/validation'; +import { + VALIDATION_LIMITS, + validatePassword, + validatePositiveInteger, + validateShareName, + sanitizeUserError, + validatePasswordLength, + formatRelayUrl, +} from '@/lib/validation';src/__tests__/lib/echoRelays.test.ts (1)
1-3: Import uses relative path instead of@/alias.Per coding guidelines, prefer
@/path alias for imports.Suggested import style
-import { computeRelayPlan, normalizeRelayUrl } from '../../lib/echoRelays'; +import { computeRelayPlan, normalizeRelayUrl } from '@/lib/echoRelays';src/__tests__/integration/computeRelayPlan.test.ts (1)
14-74: Static analysis tests provide good structural verification, but consider fragility.Using regex to verify handler registration and schema usage is a pragmatic approach for integration tests. However, these tests may break with minor formatting changes. The tests do cover important aspects:
- Handler registration pattern
- Schema validation structure
- Environment variable fallback
- Input normalization
- Error handling structure
Consider adding a comment noting these tests verify structural contracts and may need updates if implementation formatting changes significantly.
src/__tests__/components/Recover.test.tsx (1)
13-19: Clipboard mock setup is correct.The mock enables testing copy-to-clipboard flows. Consider using
jest.spyOninstead ofObject.assignfor easier restoration in case other tests need the real clipboard API.Alternative clipboard mock approach
-// Mock clipboard API -const mockClipboardWriteText = jest.fn().mockResolvedValue(undefined); -Object.assign(navigator, { - clipboard: { - writeText: mockClipboardWriteText, - }, -}); +// Mock clipboard API +const mockClipboardWriteText = jest.fn().mockResolvedValue(undefined); +beforeAll(() => { + Object.defineProperty(navigator, 'clipboard', { + value: { writeText: mockClipboardWriteText }, + configurable: true, + }); +});src/lib/echoRelays.ts (2)
92-106: Consider URL parsing edge case.The
dedupeKeyfunction handles URL parsing failures gracefully with a regex fallback. However, the fallback regex doesn't preserve query strings and fragments from non-standard URLs.Minor: Include query/fragment in regex fallback
} catch { const match = url.match(/^(wss?):\/\/([^/?#]+)(.*)$/i); if (match) { - return `${match[1].toLowerCase()}://${match[2].toLowerCase()}${match[3] ?? ''}`; + // match[3] captures path, query, and fragment + return `${match[1].toLowerCase()}://${match[2].toLowerCase()}${match[3] || ''}`; } return url; }Note: The
?? ''and|| ''are functionally equivalent here sincematch[3]will be either a string orundefined, notnull. Current code is correct.
170-180: Duplicate dedupe function - consider consolidation.There's a local
dedupefunction insidecomputeRelayPlanthat has similar logic tonormalizeList. While the innerdedupeoperates on already-normalized strings (skipping the normalize step), this could be slightly confusing.Consider extracting to a shared helper
The inner
dedupefunction could be extracted asdedupeNormalizedto clarify it's for already-normalized URLs, ornormalizeListcould be enhanced to accept a skip-normalize flag.src/components/Recover.tsx (1)
753-800: Minor: Button layout could use consistent flex-1.The Copy button has
flex-1but Reveal and Clear don't, which may cause uneven button widths depending on content length. This is a minor styling consideration.Optional: Consistent button widths
<Button type="button" onClick={handleToggleNsecReveal} variant="outline" - className="bg-gray-700 hover:bg-gray-600 border-gray-600 text-sm" + className="flex-1 bg-gray-700 hover:bg-gray-600 border-gray-600 text-sm" >src/lib/validation.ts (1)
127-153: SSRF protection only handles IPv4 - consider IPv6.The
isPrivateOrReservedIpfunction only validates IPv4 addresses. IPv6 private/reserved ranges (e.g.,::1,fe80::,fc00::/7) are not blocked, which could allow SSRF bypasses via IPv6 addresses.🛡️ Consider adding IPv6 protection
+function isPrivateOrReservedIpv6(ip: string): boolean { + const normalized = ip.toLowerCase(); + // Loopback + if (normalized === '::1' || normalized === '0:0:0:0:0:0:0:1') return true; + // Link-local (fe80::/10) + if (normalized.startsWith('fe8') || normalized.startsWith('fe9') || + normalized.startsWith('fea') || normalized.startsWith('feb')) return true; + // Unique local (fc00::/7) + if (normalized.startsWith('fc') || normalized.startsWith('fd')) return true; + // IPv4-mapped IPv6 (::ffff:x.x.x.x) - delegate to IPv4 check + const v4Mapped = normalized.match(/^::ffff:(\d+\.\d+\.\d+\.\d+)$/); + if (v4Mapped) return isPrivateOrReservedIp(v4Mapped[1]); + return false; +}src/__tests__/integration/electron-security.test.ts (1)
129-135: CSP unsafe-eval check could have false negatives.The test only checks if
scriptSrcMatchexists before verifying nounsafe-eval. If the regex doesn't match (e.g., due to formatting), the test silently passes without verification.💡 Consider making the test more robust
it('should NOT allow unsafe-eval in scripts', () => { - // Check that script-src doesn't include unsafe-eval const scriptSrcMatch = indexHtmlContent.match(/script-src[^;]*/); - if (scriptSrcMatch) { - expect(scriptSrcMatch[0]).not.toContain('unsafe-eval'); - } + expect(scriptSrcMatch).not.toBeNull(); + expect(scriptSrcMatch![0]).not.toContain('unsafe-eval'); });SECURITY_AUDIT_2026-01-06.md (1)
269-269: Minor grammar nit per static analysis.Consider using "High-Severity" with a hyphen when used as a compound adjective before "Issues" for consistency.
-## High Severity Issues +## High-Severity Issues
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (41)
CLAUDE.mdSECURITY_AUDIT_2026-01-06.mdindex.htmlpackage.jsonsrc/__tests__/__mocks__/bifrost.mock.tssrc/__tests__/components/AddShare.test.tsxsrc/__tests__/components/LoadShare.test.tsxsrc/__tests__/components/Recover.test.tsxsrc/__tests__/components/SaveShare.test.tsxsrc/__tests__/components/Signer.test.tsxsrc/__tests__/integration/clientShareManager.test.tssrc/__tests__/integration/computeRelayPlan.test.tssrc/__tests__/integration/electron-security.test.tssrc/__tests__/integration/userInputValidation.test.tssrc/__tests__/lib/echoRelays.test.tssrc/__tests__/lib/igloo-core-integration.test.tssrc/__tests__/lib/ipcSchemas.test.tssrc/__tests__/lib/shareManager.test.tssrc/__tests__/lib/validation.test.tssrc/__tests__/setup.tssrc/__tests__/workflows/keyset-creation.test.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/components/AddShare.tsxsrc/components/Create.tsxsrc/components/Keyset.tsxsrc/components/LoadShare.tsxsrc/components/Recover.tsxsrc/components/SaveShare.tsxsrc/components/Signer.tsxsrc/lib/clientShareManager.tssrc/lib/echoRelays.tssrc/lib/ipcSchemas.tssrc/lib/shareManager.tssrc/lib/signer-keepalive.tssrc/lib/validation.tssrc/main.tssrc/preload.tssrc/types/index.tstsconfig.preload.jsontsconfig.test.jsonwebpack.config.cjs
🧰 Additional context used
📓 Path-based instructions (18)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Use strict TypeScript mode with explicit types for function parameters and returns
Prefer interfaces over types for defining object shapes in TypeScript
Use @/ path alias for imports instead of relative paths
Use camelCase for functions and variables
Use UPPER_SNAKE_CASE for constants
Files:
src/components/Signer.tsxsrc/__tests__/lib/igloo-core-integration.test.tssrc/__tests__/components/SaveShare.test.tsxsrc/components/Create.tsxsrc/preload.tssrc/__tests__/components/AddShare.test.tsxsrc/__tests__/lib/ipcSchemas.test.tssrc/__tests__/lib/shareManager.test.tssrc/__tests__/setup.tssrc/types/index.tssrc/lib/shareManager.tssrc/lib/signer-keepalive.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/__tests__/lib/echoRelays.test.tssrc/__tests__/lib/validation.test.tssrc/__tests__/components/Signer.test.tsxsrc/__tests__/components/LoadShare.test.tsxsrc/__tests__/components/Recover.test.tsxsrc/components/AddShare.tsxsrc/components/LoadShare.tsxsrc/__tests__/integration/electron-security.test.tssrc/lib/echoRelays.tssrc/__tests__/integration/computeRelayPlan.test.tssrc/lib/validation.tssrc/main.tssrc/lib/ipcSchemas.tssrc/__tests__/integration/clientShareManager.test.tssrc/lib/clientShareManager.tssrc/__tests__/workflows/keyset-creation.test.tssrc/components/SaveShare.tsxsrc/__tests__/__mocks__/bifrost.mock.tssrc/components/Keyset.tsxsrc/components/Recover.tsxsrc/__tests__/integration/userInputValidation.test.ts
src/components/[A-Z]*.tsx
📄 CodeRabbit inference engine (CLAUDE.md)
Use PascalCase for component files
Files:
src/components/Signer.tsxsrc/components/Create.tsxsrc/components/AddShare.tsxsrc/components/LoadShare.tsxsrc/components/SaveShare.tsxsrc/components/Keyset.tsxsrc/components/Recover.tsx
src/components/**/*.tsx
📄 CodeRabbit inference engine (CLAUDE.md)
src/components/**/*.tsx: Use Tailwind CSS utility classes in JSX and use cn() utility for conditional classes
Avoid inline styles unless conditionally computed
Use functional components with hooks instead of class components
Use ipcRenderer.invoke() in renderer process to call IPC handlers without direct file system accessTailwind utility classes style JSX; reserve inline styles for dynamic values only
Files:
src/components/Signer.tsxsrc/components/Create.tsxsrc/components/AddShare.tsxsrc/components/LoadShare.tsxsrc/components/SaveShare.tsxsrc/components/Keyset.tsxsrc/components/Recover.tsx
src/{components,lib,types}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
UI components sit under
src/components/, helpers insrc/lib/, shared types insrc/types/
Files:
src/components/Signer.tsxsrc/components/Create.tsxsrc/types/index.tssrc/lib/shareManager.tssrc/lib/signer-keepalive.tssrc/components/AddShare.tsxsrc/components/LoadShare.tsxsrc/lib/echoRelays.tssrc/lib/validation.tssrc/lib/ipcSchemas.tssrc/lib/clientShareManager.tssrc/components/SaveShare.tsxsrc/components/Keyset.tsxsrc/components/Recover.tsx
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/**/*.{ts,tsx}: All runtime code is TypeScript with two-space indentation and required semicolons
Import third-party packages before internal modules and use the@/alias for local paths
Files:
src/components/Signer.tsxsrc/__tests__/lib/igloo-core-integration.test.tssrc/__tests__/components/SaveShare.test.tsxsrc/components/Create.tsxsrc/preload.tssrc/__tests__/components/AddShare.test.tsxsrc/__tests__/lib/ipcSchemas.test.tssrc/__tests__/lib/shareManager.test.tssrc/__tests__/setup.tssrc/types/index.tssrc/lib/shareManager.tssrc/lib/signer-keepalive.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/__tests__/lib/echoRelays.test.tssrc/__tests__/lib/validation.test.tssrc/__tests__/components/Signer.test.tsxsrc/__tests__/components/LoadShare.test.tsxsrc/__tests__/components/Recover.test.tsxsrc/components/AddShare.tsxsrc/components/LoadShare.tsxsrc/__tests__/integration/electron-security.test.tssrc/lib/echoRelays.tssrc/__tests__/integration/computeRelayPlan.test.tssrc/lib/validation.tssrc/main.tssrc/lib/ipcSchemas.tssrc/__tests__/integration/clientShareManager.test.tssrc/lib/clientShareManager.tssrc/__tests__/workflows/keyset-creation.test.tssrc/components/SaveShare.tsxsrc/__tests__/__mocks__/bifrost.mock.tssrc/components/Keyset.tsxsrc/components/Recover.tsxsrc/__tests__/integration/userInputValidation.test.ts
src/components/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/components/**/*.{ts,tsx}: Prefer functional React components; name them in PascalCase and helpers in camelCase
Components insrc/components/follow kebab-case filenames (e.g.,share-list.tsx)
Files:
src/components/Signer.tsxsrc/components/Create.tsxsrc/components/AddShare.tsxsrc/components/LoadShare.tsxsrc/components/SaveShare.tsxsrc/components/Keyset.tsxsrc/components/Recover.tsx
src/__tests__/**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
src/__tests__/**/*.test.{ts,tsx}: Mock @frostr/igloo-core functions at the module level in tests to avoid ESM/Jest complications
Use jest.clearAllMocks() in beforeEach hooks to ensure test isolation
Mock Electron's ipcRenderer and app APIs in tests
Files:
src/__tests__/lib/igloo-core-integration.test.tssrc/__tests__/components/SaveShare.test.tsxsrc/__tests__/components/AddShare.test.tsxsrc/__tests__/lib/ipcSchemas.test.tssrc/__tests__/lib/shareManager.test.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/__tests__/lib/echoRelays.test.tssrc/__tests__/lib/validation.test.tssrc/__tests__/components/Signer.test.tsxsrc/__tests__/components/LoadShare.test.tsxsrc/__tests__/components/Recover.test.tsxsrc/__tests__/integration/electron-security.test.tssrc/__tests__/integration/computeRelayPlan.test.tssrc/__tests__/integration/clientShareManager.test.tssrc/__tests__/workflows/keyset-creation.test.tssrc/__tests__/integration/userInputValidation.test.ts
src/__tests__/lib/**/*.test.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Test utility functions in tests/lib/ directory
Files:
src/__tests__/lib/igloo-core-integration.test.tssrc/__tests__/lib/ipcSchemas.test.tssrc/__tests__/lib/shareManager.test.tssrc/__tests__/lib/echoRelays.test.tssrc/__tests__/lib/validation.test.ts
src/__tests__/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Tests mirror runtime code under
src/__tests__/withintegration/,performance/, and__mocks__/subdirectories for feature-specific coverage
Files:
src/__tests__/lib/igloo-core-integration.test.tssrc/__tests__/components/SaveShare.test.tsxsrc/__tests__/components/AddShare.test.tsxsrc/__tests__/lib/ipcSchemas.test.tssrc/__tests__/lib/shareManager.test.tssrc/__tests__/setup.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/__tests__/lib/echoRelays.test.tssrc/__tests__/lib/validation.test.tssrc/__tests__/components/Signer.test.tsxsrc/__tests__/components/LoadShare.test.tsxsrc/__tests__/components/Recover.test.tsxsrc/__tests__/integration/electron-security.test.tssrc/__tests__/integration/computeRelayPlan.test.tssrc/__tests__/integration/clientShareManager.test.tssrc/__tests__/workflows/keyset-creation.test.tssrc/__tests__/__mocks__/bifrost.mock.tssrc/__tests__/integration/userInputValidation.test.ts
src/**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Jest with Testing Library powers renderer specs; place new tests beside features as
<subject>.test.tsx
Files:
src/__tests__/lib/igloo-core-integration.test.tssrc/__tests__/components/SaveShare.test.tsxsrc/__tests__/components/AddShare.test.tsxsrc/__tests__/lib/ipcSchemas.test.tssrc/__tests__/lib/shareManager.test.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/__tests__/lib/echoRelays.test.tssrc/__tests__/lib/validation.test.tssrc/__tests__/components/Signer.test.tsxsrc/__tests__/components/LoadShare.test.tsxsrc/__tests__/components/Recover.test.tsxsrc/__tests__/integration/electron-security.test.tssrc/__tests__/integration/computeRelayPlan.test.tssrc/__tests__/integration/clientShareManager.test.tssrc/__tests__/workflows/keyset-creation.test.tssrc/__tests__/integration/userInputValidation.test.ts
src/__tests__/components/**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Test React component behavior in tests/components/ directory
Files:
src/__tests__/components/SaveShare.test.tsxsrc/__tests__/components/AddShare.test.tsxsrc/__tests__/components/Signer.test.tsxsrc/__tests__/components/LoadShare.test.tsxsrc/__tests__/components/Recover.test.tsx
src/**/*ipc*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Cover new IPC handlers with unit tests plus at least one scenario in
src/__tests__/integration/
Files:
src/__tests__/lib/ipcSchemas.test.tssrc/lib/ipcSchemas.ts
src/__tests__/{setup.ts,__mocks__/**}
📄 CodeRabbit inference engine (AGENTS.md)
Register shared mocks in
src/__tests__/setup.tsand reuse fixtures fromsrc/__tests__/__mocks__/
Files:
src/__tests__/setup.tssrc/__tests__/__mocks__/bifrost.mock.ts
src/lib/shareManager.ts
📄 CodeRabbit inference engine (CLAUDE.md)
src/lib/shareManager.ts: Never store plaintext share data; always encrypt with user passwords
Store shares in /igloo/shares/ directory using the defined JSON schema
Files:
src/lib/shareManager.ts
src/__tests__/workflows/**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Test end-to-end user flows in tests/workflows/ directory
Files:
src/__tests__/workflows/share-lifecycle.test.tssrc/__tests__/workflows/keyset-creation.test.ts
src/__tests__/integration/**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Test Electron IPC communication in tests/integration/ directory
Files:
src/__tests__/integration/electron-security.test.tssrc/__tests__/integration/computeRelayPlan.test.tssrc/__tests__/integration/clientShareManager.test.tssrc/__tests__/integration/userInputValidation.test.ts
src/main.ts
📄 CodeRabbit inference engine (CLAUDE.md)
src/main.ts: Register IPC handlers in main.ts using ipcMain.handle() for file system operations
Electron's main process uses CommonJS (require) while renderer uses ESM (import)Main Electron process lives in
src/main.ts; the renderer bootstraps fromsrc/renderer.tsx
Files:
src/main.ts
src/__tests__/__mocks__/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Place shared mock implementations in tests/mocks/ for use across test files
Files:
src/__tests__/__mocks__/bifrost.mock.ts
🧠 Learnings (28)
📓 Common learnings
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T23:50:29.859Z
Learning: Applies to src/**/*ipc*.{ts,tsx} : Cover new IPC handlers with unit tests plus at least one scenario in `src/__tests__/integration/`
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Do not implement cryptographic logic in the desktop app; delegate all crypto operations to frostr/igloo-core
Applied to files:
src/components/Signer.tsxsrc/components/AddShare.tsxCLAUDE.md
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/__tests__/**/*.test.{ts,tsx} : Mock frostr/igloo-core functions at the module level in tests to avoid ESM/Jest complications
Applied to files:
src/__tests__/lib/igloo-core-integration.test.tssrc/preload.tssrc/__tests__/components/AddShare.test.tsxsrc/__tests__/lib/shareManager.test.tssrc/__tests__/setup.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/__tests__/lib/echoRelays.test.tssrc/__tests__/components/Signer.test.tsxsrc/__tests__/components/Recover.test.tsxpackage.jsontsconfig.test.jsonsrc/__tests__/integration/electron-security.test.tssrc/__tests__/integration/clientShareManager.test.tssrc/__tests__/workflows/keyset-creation.test.tssrc/__tests__/__mocks__/bifrost.mock.ts
📚 Learning: 2026-01-02T23:50:29.859Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T23:50:29.859Z
Learning: Applies to src/**/*ipc*.{ts,tsx} : Cover new IPC handlers with unit tests plus at least one scenario in `src/__tests__/integration/`
Applied to files:
src/__tests__/lib/igloo-core-integration.test.tssrc/__tests__/components/SaveShare.test.tsxsrc/preload.tssrc/__tests__/components/AddShare.test.tsxsrc/__tests__/lib/ipcSchemas.test.tssrc/__tests__/lib/shareManager.test.tssrc/__tests__/setup.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/__tests__/lib/echoRelays.test.tssrc/__tests__/lib/validation.test.tssrc/__tests__/components/Signer.test.tsxsrc/__tests__/components/LoadShare.test.tsxsrc/__tests__/components/Recover.test.tsxsrc/components/AddShare.tsxsrc/__tests__/integration/electron-security.test.tssrc/__tests__/integration/computeRelayPlan.test.tssrc/main.tsSECURITY_AUDIT_2026-01-06.mdsrc/lib/ipcSchemas.tssrc/__tests__/integration/clientShareManager.test.tssrc/__tests__/integration/userInputValidation.test.ts
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/__tests__/lib/**/*.test.ts : Test utility functions in __tests__/lib/ directory
Applied to files:
src/__tests__/lib/igloo-core-integration.test.tssrc/__tests__/components/SaveShare.test.tsxsrc/preload.tssrc/__tests__/lib/ipcSchemas.test.tssrc/__tests__/lib/shareManager.test.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/__tests__/lib/echoRelays.test.tssrc/__tests__/lib/validation.test.tssrc/__tests__/components/Signer.test.tsxsrc/__tests__/components/LoadShare.test.tsxsrc/__tests__/components/Recover.test.tsxtsconfig.test.jsonsrc/__tests__/integration/electron-security.test.tsCLAUDE.mdsrc/__tests__/integration/computeRelayPlan.test.tssrc/__tests__/workflows/keyset-creation.test.ts
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/__tests__/__mocks__/**/*.ts : Place shared mock implementations in __tests__/__mocks__/ for use across test files
Applied to files:
src/__tests__/lib/igloo-core-integration.test.tssrc/__tests__/components/SaveShare.test.tsxsrc/preload.tssrc/__tests__/components/AddShare.test.tsxsrc/__tests__/lib/shareManager.test.tssrc/__tests__/setup.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/__tests__/lib/echoRelays.test.tstsconfig.test.jsonsrc/__tests__/integration/clientShareManager.test.tssrc/__tests__/workflows/keyset-creation.test.tssrc/__tests__/__mocks__/bifrost.mock.ts
📚 Learning: 2026-01-02T23:50:29.859Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T23:50:29.859Z
Learning: Applies to src/__tests__/{setup.ts,__mocks__/**} : Register shared mocks in `src/__tests__/setup.ts` and reuse fixtures from `src/__tests__/__mocks__/`
Applied to files:
src/__tests__/lib/igloo-core-integration.test.tssrc/__tests__/components/SaveShare.test.tsxsrc/preload.tssrc/__tests__/components/AddShare.test.tsxsrc/__tests__/setup.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/__tests__/lib/echoRelays.test.tssrc/__tests__/components/Signer.test.tsxsrc/__tests__/components/Recover.test.tsxsrc/__tests__/integration/clientShareManager.test.tssrc/__tests__/workflows/keyset-creation.test.tssrc/__tests__/__mocks__/bifrost.mock.ts
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/lib/shareManager.ts : Never store plaintext share data; always encrypt with user passwords
Applied to files:
src/__tests__/components/SaveShare.test.tsxsrc/__tests__/components/AddShare.test.tsxsrc/__tests__/lib/shareManager.test.tssrc/lib/shareManager.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/__tests__/components/LoadShare.test.tsxsrc/components/AddShare.tsxsrc/components/LoadShare.tsxCLAUDE.mdSECURITY_AUDIT_2026-01-06.mdsrc/__tests__/integration/clientShareManager.test.tssrc/lib/clientShareManager.tssrc/__tests__/workflows/keyset-creation.test.tssrc/components/SaveShare.tsxsrc/__tests__/__mocks__/bifrost.mock.tssrc/components/Keyset.tsxsrc/components/Recover.tsx
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/__tests__/components/**/*.test.{ts,tsx} : Test React component behavior in __tests__/components/ directory
Applied to files:
src/__tests__/components/SaveShare.test.tsxsrc/__tests__/components/AddShare.test.tsxsrc/__tests__/lib/shareManager.test.tssrc/__tests__/lib/echoRelays.test.tssrc/__tests__/components/LoadShare.test.tsxsrc/__tests__/components/Recover.test.tsxtsconfig.test.jsonsrc/__tests__/integration/electron-security.test.ts
📚 Learning: 2026-01-02T23:50:29.859Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T23:50:29.859Z
Learning: Applies to src/__tests__/**/*.{ts,tsx} : Tests mirror runtime code under `src/__tests__/` with `integration/`, `performance/`, and `__mocks__/` subdirectories for feature-specific coverage
Applied to files:
src/__tests__/components/SaveShare.test.tsxsrc/preload.tssrc/__tests__/components/AddShare.test.tsxsrc/__tests__/lib/ipcSchemas.test.tssrc/__tests__/lib/shareManager.test.tssrc/__tests__/setup.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/__tests__/lib/echoRelays.test.tssrc/__tests__/lib/validation.test.tssrc/__tests__/components/Signer.test.tsxsrc/__tests__/components/LoadShare.test.tsxsrc/__tests__/components/Recover.test.tsxtsconfig.test.jsonsrc/__tests__/integration/electron-security.test.tssrc/__tests__/integration/computeRelayPlan.test.tssrc/__tests__/integration/clientShareManager.test.ts
📚 Learning: 2026-01-02T23:50:29.859Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T23:50:29.859Z
Learning: Applies to src/**/*.{ts,tsx} : Import third-party packages before internal modules and use the `@/` alias for local paths
Applied to files:
tsconfig.preload.jsontsconfig.test.jsonCLAUDE.mdwebpack.config.cjs
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/main.ts : Electron's main process uses CommonJS (require) while renderer uses ESM (import)
Applied to files:
src/preload.tssrc/__tests__/setup.tssrc/components/AddShare.tsxpackage.jsonsrc/__tests__/integration/electron-security.test.tsCLAUDE.mdsrc/main.tswebpack.config.cjs
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/__tests__/**/*.test.{ts,tsx} : Mock Electron's ipcRenderer and app APIs in tests
Applied to files:
src/preload.tssrc/__tests__/components/AddShare.test.tsxsrc/__tests__/lib/ipcSchemas.test.tssrc/__tests__/setup.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/__tests__/components/Signer.test.tsxsrc/__tests__/components/Recover.test.tsxsrc/__tests__/integration/electron-security.test.tssrc/__tests__/integration/computeRelayPlan.test.tssrc/__tests__/integration/clientShareManager.test.tssrc/lib/clientShareManager.tswebpack.config.cjs
📚 Learning: 2026-01-02T23:50:29.859Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T23:50:29.859Z
Learning: Applies to src/main.ts : Main Electron process lives in `src/main.ts`; the renderer bootstraps from `src/renderer.tsx`
Applied to files:
src/preload.tssrc/__tests__/setup.tssrc/components/AddShare.tsxpackage.jsonCLAUDE.mdsrc/main.tswebpack.config.cjs
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/__tests__/integration/**/*.test.{ts,tsx} : Test Electron IPC communication in __tests__/integration/ directory
Applied to files:
src/preload.tssrc/__tests__/components/AddShare.test.tsxsrc/__tests__/lib/ipcSchemas.test.tssrc/__tests__/lib/shareManager.test.tssrc/__tests__/setup.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/__tests__/lib/echoRelays.test.tssrc/__tests__/lib/validation.test.tssrc/__tests__/components/LoadShare.test.tsxsrc/__tests__/components/Recover.test.tsxsrc/components/AddShare.tsxsrc/__tests__/integration/electron-security.test.tsCLAUDE.mdsrc/__tests__/integration/computeRelayPlan.test.tssrc/main.tssrc/lib/ipcSchemas.tssrc/__tests__/integration/clientShareManager.test.tssrc/lib/clientShareManager.tssrc/__tests__/integration/userInputValidation.test.ts
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/main.ts : Register IPC handlers in main.ts using ipcMain.handle() for file system operations
Applied to files:
src/preload.tssrc/__tests__/integration/electron-security.test.tssrc/__tests__/integration/computeRelayPlan.test.tssrc/main.tssrc/lib/clientShareManager.tssrc/components/Keyset.tsx
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/components/**/*.tsx : Use ipcRenderer.invoke() in renderer process to call IPC handlers without direct file system access
Applied to files:
src/preload.tssrc/__tests__/setup.tssrc/components/AddShare.tsxsrc/__tests__/integration/electron-security.test.tssrc/__tests__/integration/computeRelayPlan.test.tssrc/__tests__/integration/clientShareManager.test.tssrc/lib/clientShareManager.tssrc/components/Keyset.tsx
📚 Learning: 2026-01-02T23:50:29.859Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T23:50:29.859Z
Learning: Debug flaky Electron tests with `npm test -- --runInBand` to serialize execution
Applied to files:
src/preload.tssrc/__tests__/setup.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/__tests__/integration/electron-security.test.ts
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/__tests__/**/*.test.{ts,tsx} : Use jest.clearAllMocks() in beforeEach hooks to ensure test isolation
Applied to files:
src/__tests__/components/AddShare.test.tsxsrc/__tests__/setup.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/__tests__/components/Recover.test.tsxtsconfig.test.jsonsrc/__tests__/integration/clientShareManager.test.tssrc/__tests__/workflows/keyset-creation.test.ts
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/__tests__/workflows/**/*.test.{ts,tsx} : Test end-to-end user flows in __tests__/workflows/ directory
Applied to files:
src/__tests__/components/AddShare.test.tsxsrc/__tests__/workflows/share-lifecycle.test.tssrc/__tests__/lib/echoRelays.test.tssrc/__tests__/integration/electron-security.test.ts
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/lib/shareManager.ts : Store shares in <appData>/igloo/shares/ directory using the defined JSON schema
Applied to files:
src/__tests__/lib/ipcSchemas.test.tssrc/__tests__/lib/shareManager.test.tssrc/lib/shareManager.tssrc/__tests__/workflows/share-lifecycle.test.tssrc/components/AddShare.tsxCLAUDE.mdsrc/main.tssrc/lib/ipcSchemas.tssrc/__tests__/integration/clientShareManager.test.tssrc/lib/clientShareManager.tssrc/components/Recover.tsx
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to src/lib/encryption.ts : Use PBKDF2 with 600,000 iterations for encrypting share files
Applied to files:
src/lib/shareManager.tssrc/components/LoadShare.tsxsrc/components/SaveShare.tsxsrc/__tests__/__mocks__/bifrost.mock.ts
📚 Learning: 2026-01-02T23:50:29.859Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T23:50:29.859Z
Learning: Applies to src/**/*.test.{ts,tsx} : Jest with Testing Library powers renderer specs; place new tests beside features as `<subject>.test.tsx`
Applied to files:
src/__tests__/lib/echoRelays.test.tssrc/__tests__/lib/validation.test.tssrc/__tests__/components/Signer.test.tsxsrc/__tests__/components/Recover.test.tsxtsconfig.test.jsonsrc/__tests__/integration/electron-security.test.tssrc/__tests__/integration/computeRelayPlan.test.ts
📚 Learning: 2026-01-02T23:50:29.859Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T23:50:29.859Z
Learning: PRs should describe the change set, include screenshots or recordings for UI tweaks, and list run commands (`npm test`, `npm run lint`)
Applied to files:
package.json
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Applies to **/*.{ts,tsx} : Use @/ path alias for imports instead of relative paths
Applied to files:
tsconfig.test.jsonwebpack.config.cjs
📚 Learning: 2026-01-02T23:50:29.859Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T23:50:29.859Z
Learning: Applies to src/{components,lib,types}/**/*.{ts,tsx} : UI components sit under `src/components/`, helpers in `src/lib/`, shared types in `src/types/`
Applied to files:
tsconfig.test.jsonCLAUDE.md
📚 Learning: 2026-01-02T23:50:29.859Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T23:50:29.859Z
Learning: Applies to src/**/*.{ts,tsx} : All runtime code is TypeScript with two-space indentation and required semicolons
Applied to files:
tsconfig.test.json
📚 Learning: 2026-01-02T23:50:16.045Z
Learnt from: CR
Repo: FROSTR-ORG/igloo-desktop PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T23:50:16.045Z
Learning: Use props and callbacks for component communication instead of external state libraries like Redux
Applied to files:
CLAUDE.md
🧬 Code graph analysis (15)
src/__tests__/components/SaveShare.test.tsx (1)
src/lib/encryption.ts (1)
derive_secret_async(24-73)
src/components/Create.tsx (1)
src/lib/validation.ts (3)
validateShareName(389-419)VALIDATION_LIMITS(4-15)validatePositiveInteger(335-369)
src/preload.ts (1)
src/types/index.ts (1)
RelayPlan(191-198)
src/__tests__/components/AddShare.test.tsx (1)
src/__tests__/setup.ts (1)
mockElectronAPI(191-191)
src/__tests__/lib/ipcSchemas.test.ts (1)
src/lib/ipcSchemas.ts (9)
ShareIdSchema(14-17)HexSaltSchema(20-23)RelayUrlSchema(26-26)ShareCredentialSchema(29-31)GroupCredentialSchema(34-36)SaveShareSchema(39-67)RelayPlanArgsSchema(70-75)EchoStartArgsSchema(78-87)EchoStopArgsSchema(90-94)
src/__tests__/lib/echoRelays.test.ts (1)
src/lib/echoRelays.ts (2)
normalizeRelayUrl(221-221)computeRelayPlan(143-219)
src/__tests__/lib/validation.test.ts (1)
src/lib/validation.ts (7)
VALIDATION_LIMITS(4-15)validatePassword(32-49)validatePasswordLength(467-487)validatePositiveInteger(335-369)validateShareName(389-419)sanitizeUserError(432-458)formatRelayUrl(230-304)
src/components/AddShare.tsx (2)
src/lib/validation.ts (2)
VALIDATION_LIMITS(4-15)sanitizeUserError(432-458)src/types/index.ts (1)
DecodedGroup(9-19)
src/components/LoadShare.tsx (1)
src/lib/validation.ts (2)
VALIDATION_LIMITS(4-15)sanitizeUserError(432-458)
src/lib/echoRelays.ts (1)
src/types/index.ts (1)
RelayPlan(191-198)
src/__tests__/integration/computeRelayPlan.test.ts (2)
webpack.config.cjs (1)
path(1-1)src/__tests__/setup.ts (1)
mockElectronAPI(191-191)
src/main.ts (2)
src/lib/echoRelays.ts (1)
computeRelayPlan(143-219)src/lib/ipcSchemas.ts (5)
SaveShareSchema(39-67)ShareIdSchema(14-17)RelayPlanArgsSchema(70-75)EchoStartArgsSchema(78-87)EchoStopArgsSchema(90-94)
src/__tests__/integration/clientShareManager.test.ts (2)
src/__tests__/setup.ts (1)
mockElectronAPI(191-191)src/lib/clientShareManager.ts (1)
clientShareManager(98-98)
src/lib/clientShareManager.ts (1)
src/types/index.ts (1)
IglooShare(44-55)
src/components/SaveShare.tsx (1)
src/lib/validation.ts (1)
VALIDATION_LIMITS(4-15)
🪛 LanguageTool
SECURITY_AUDIT_2026-01-06.md
[grammar] ~269-~269: Use a hyphen to join words.
Context: ...m invalid threshold values --- ## High Severity Issues ### 6. ✅ FIXED: Insecur...
(QB_NEW_EN_HYPHEN)
[grammar] ~838-~838: Use a hyphen to join words.
Context: ...")` = NaN silently accepted --- ## Low Severity Issues ### 33. ✅ FIXED: No IPC...
(QB_NEW_EN_HYPHEN)
[grammar] ~976-~976: Use a hyphen to join words.
Context: ...ion fixes covering all critical and high severity React component validation issu...
(QB_NEW_EN_HYPHEN)
Summary by CodeRabbit
New Features
Bug Fixes
Security
Tests
✏️ Tip: You can customize this high-level summary in your review settings.