Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
2722cc8
Update package-lock.json, conversation-list.ts, and selectors.ts
Feb 9, 2026
2d69720
Filter out conversations with blank labels
bankjaneo Feb 9, 2026
19ac858
fix: auto-theme switching bug and high CPU usage
bankjaneo Feb 9, 2026
46ba088
Restore macOS 24px draggable area at top of window
bankjaneo Feb 9, 2026
e05401b
Add Windows jump list feature
bankjaneo Feb 9, 2026
4467511
Change Windows jump list header from Tasks to Conversations
bankjaneo Feb 9, 2026
34fe27a
Fix Windows process spawn on quit
bankjaneo Feb 10, 2026
03bc264
## Summary
bankjaneo Feb 10, 2026
254b4b8
Limit dock conversation list to 10 items on macOS
bankjaneo Feb 10, 2026
95f1332
Add AGENTS.md for agentic coding agents
bankjaneo Feb 12, 2026
5d4e29c
Migrate from messenger.com to facebook.com/messages
bankjaneo Feb 18, 2026
156766b
Fix dock and jump list showing timestamps instead of conversation names
bankjaneo Feb 18, 2026
acf5a04
Reposition macOS traffic lights to top-left of conversation list area
bankjaneo Feb 18, 2026
291fa9b
Fix conversation list width inconsistency by setting fixed width
bankjaneo Feb 18, 2026
4ba3828
Open individual chat profiles in default browser
bankjaneo Feb 18, 2026
7081407
Fix notifications and dock badge after facebook.com/messages migration
bankjaneo Feb 18, 2026
de6e74b
Update package-lock.json with dependency version bumps
bankjaneo Feb 18, 2026
84fe465
Fix GNOME dock badge and notification deduplication
bankjaneo Feb 19, 2026
47e029f
Fix notification badge and flashing issues on Windows
bankjaneo Feb 19, 2026
05d1fdc
Fix notification sound on Linux with multi-DE fallback support
bankjaneo Feb 20, 2026
e94c7fa
Fix notification sound on macOS using system afplay command with Tink…
bankjaneo Feb 20, 2026
3e4ac56
Add Facebook Messenger notification sound
bankjaneo Feb 20, 2026
4ccbf30
Fix Linux notification sound to play custom messenger sound
bankjaneo Feb 20, 2026
77832a8
Refactor notification sound to use native tools on all platforms
bankjaneo Feb 20, 2026
b62e898
fix: open all chat links in external browser, keep images in-app
bankjaneo Feb 21, 2026
59e20f3
Fix menu bar items after facebook.com/messages migration
bankjaneo Feb 21, 2026
245e7ef
Fix Mute Notifications after facebook.com/messages migration
bankjaneo Feb 21, 2026
c7c4a30
Fix conversation menu actions: Mute, Archive, Delete
bankjaneo Feb 21, 2026
f94e4d0
Fix notification features: message preview, unread badge, and mute no…
bankjaneo Feb 21, 2026
8b6be82
Fix notification repeat bug: track message content instead of time-ba…
bankjaneo Feb 21, 2026
fffc54b
Fix flash of white background and scrollbar on startup
bankjaneo Feb 22, 2026
9ac0a1b
Fix Linux window size not persisting across logout/login
bankjaneo Feb 22, 2026
bfc74ef
Fix broken menu bar items after facebook.com/messages migration
bankjaneo Feb 23, 2026
176d850
Fix menu bar items after Facebook Messenger UI migration
bankjaneo Feb 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 100 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# Caprine AGENTS.md

## Build/Lint/Test Commands

- **Build**: `npm run build` or `npm run start` (runs TypeScript compiler)
- **Lint**: `npm run lint` (runs both `npm run lint:xo` and `npm run lint:stylelint`)
- **Type checking**: `npm run test:tsc` (runs `npm run build`)
- **Full test suite**: `npm run test` (type check + lint)
- **Distribution**: `npm run dist:mac`, `npm run dist:linux`, or `npm run dist:win`

Note: There are no unit tests in this project. The test command only runs type checking and linting.

## Code Style Guidelines

### TypeScript/JavaScript (via XO)

- Extends XO with TypeScript support
- Target: ES2022, Module: commonjs
- Enabled esnext, dom, and dom.iterable lib types

#### Disabled Rules (explicitly allowed):
- `@typescript-eslint/ban-ts-comment` - `@ts-expect-error` comments allowed
- `@typescript-eslint/consistent-type-imports` - Dynamic imports allowed
- `@typescript-eslint/naming-convention` - No strict naming requirements
- `@typescript-eslint/no-floating-promises` - Async functions without await allowed
- `@typescript-eslint/no-loop-func` - Functions in loops allowed
- `@typescript-eslint/no-non-null-assertion` - Non-null assertions (!) allowed
- `@typescript-eslint/no-require-imports` - CommonJS require() allowed
- `@typescript-eslint/no-unsafe-*` - Many type safety checks disabled for flexibility
- `import/extensions` - File extensions in imports allowed
- `import/no-anonymous-default-export` - Anonymous default exports allowed
- `import/no-cycle` - Circular dependencies allowed
- `n/file-extension-in-import` - File extensions in imports allowed
- `unicorn/prefer-at` - Use of .at() not required
- `unicorn/prefer-module` - CommonJS allowed
- `unicorn/prefer-top-level-await` - Top-level await not required

#### Conventions:
- Use `const` for variables, `let` for reassignment, avoid `var`
- Use double quotes for strings
- Use 2-space indentation (configured inxo config)
- No trailing semicolons (XO default)
- Use `camelCase` for functions/variables, `PascalCase` for types/classes
- Use `ts-expect-error` for known type issues
- Prioritize readability over strict type safety

### CSS/Style (via Stylelint)

- Extends `stylelint-config-xo`
- Based on XO style guide (2-space indentation, double quotes)

#### Disabled Rules:
- `declaration-no-important` - `!important` allowed
- `no-descending-specificity` - Specificity order not enforced
- `no-duplicate-selectors` - Duplicate selectors allowed
- `rule-empty-line-before` - No empty line requirement before rules
- `selector-class-pattern` - No naming pattern enforced
- `selector-id-pattern` - No ID naming pattern enforced
- `selector-max-class` - No class count limit

#### Conventions:
- Use BEM-style class names (e.g., `.x9f619`, `.x1n2onr6`)
- Prefer attribute selectors for Facebook elements (fragile but necessary)
- Use `!important` liberally to override Facebook's inline styles
- Organize CSS by feature (browser.css, dark-mode.css, etc.)

### Error Handling

- Use `try-catch` for async operations where appropriate
- Prefer returning undefined/null over throwing for recoverable errors
- Use `dialog.showMessageBoxSync` for critical errors requiring user interaction
- Log errors to console when appropriate

### Naming Conventions

- Functions/variables: `camelCase` (e.g., `sendAction`, `getWindow`, `toggleTrayIcon`)
- Types/Interfaces: `PascalCase` with `I` prefix for interfaces (e.g., `IToggleSounds`)
- Constants: `UPPER_SNAKE_CASE` (e.g., `messengerDomain`)
- Selectors: lowercase with hyphens (Facebook's naming)
- File names: `camelCase` or `kebab-case`

### Imports

- Use ES module syntax (`import`) where possible
- CommonJS `require()` allowed when needed (e.g., electron modules)
- Import from `./` relative paths within project
- Order: external libs → internal modules → types

## Additional Notes

- **Electron version**: v29.0.1
- **Node requirement**: >=16
- **Main output**: `dist-js/` directory
- **Build system**: TypeScript + electron-builder
- **License**: MIT
- **Platform support**: macOS, Linux, Windows

## Cursor/Copilot Rules

No Cursor rules or Copilot instructions found in the repository.
77 changes: 34 additions & 43 deletions css/browser.css
Original file line number Diff line number Diff line change
Expand Up @@ -27,27 +27,6 @@ body {
font-feature-settings: 'liga', 'clig', 'kern';
}

/* Bind the toolbar as the window's draggable region */
/* Bar above conversation list */
[role='navigation'] .x78zum5.xdt5ytf.xzd29fr {
-webkit-app-region: drag;
}
/* New message button */
[role='navigation'] .x16n37ib {
-webkit-app-region: no-drag;
}
/* Bar above chat */
[role='main'] .x1u998qt.x1vjfegm {
-webkit-app-region: drag;
}
/* Conversation name */
[role='main'] .x1i10hfl.x1qjc9v5.xjbqb8w.xjqpnuy.xa49m3k.xqeqjp1.x2hbi6w.x13fuv20.xu3j5b3.x1q0q8m5.x26u7qi.x972fbf.xcfux6l.x1qhh985.xm0m39n.x9f619.x1ypdohk.xdl72j9.x2lah0s.xe8uvvx.xdj266r.x11i5rnm.xat24cr.x1mh8g0r.x2lwn1j.xeuugli.xexx8yu.x4uap5.x18d9i69.xkhd6sd.x1n2onr6.x16tdsg8.x1hl2dhg.xggy1nq.x1ja2u2z.x1t137rt.x1o1ewxj.x3x9cwd.x1e5q0jg.x13rtm0m.x1q0g3np.x87ps6o.x1lku1pv.x1a2a7pz.x78zum5 {
-webkit-app-region: no-drag;
}
/* Top right buttons */
[role='main'] .x9f619.x1n2onr6.x1ja2u2z.x78zum5.x2lah0s.x1qughib.x6s0dn4.xozqiw3.x1q0g3np.xykv574.xbmpl8g.x4cne27.xifccgj {
-webkit-app-region: no-drag;
}
/* View label above conversation list margin */
.os-darwin [role='navigation'] .x1heor9g.x1qlqyl8.x1pd3egz.x1a2a7pz {
margin-left: 60px;
Expand All @@ -74,6 +53,40 @@ body {
display: none !important;
}

/* Hide Facebook top navigation bar (not present on messenger.com) */
[role='banner'] {
display: none !important;
}

/* Remove top offset and card spacing reserved for Facebook navbar and layout */
:root,
.__fb-light-mode,
.__fb-dark-mode {
--header-height: 0 !important;
--messenger-card-spacing: 0 !important;
}

/* Add card-style margins and gaps around the messenger layout (matching messenger.com spacing) */
div:has(> [role='navigation'][aria-label='Thread list']) {
padding: 16px !important;
box-sizing: border-box !important;
gap: 16px !important;
}

/* Add gap between chat area and right sidebar */
[role='main'] > div > div > div {
gap: 16px !important;
}

/* Round the conversation list container to match the chat container */
[role='navigation'][aria-label='Thread list'] {
border-radius: 8px !important;
overflow: hidden !important;
width: 360px !important;
min-width: 360px !important;
max-width: 360px !important;
}

/* Cookies notification: Adjust size for smaller windows */
._9o-g {
height: 290px !important;
Expand Down Expand Up @@ -194,28 +207,6 @@ html.private-mode .gvxzyvdx.aeinzg81.t7p7dqev.gh25dzvf.rse6dlih.ocv3nf92.nfkogya
display: none;
}

/* Dragable region for macOS */
.os-darwin .rq0escxv.l9j0dhe7.du4w35lb.j83agx80.pfnyh3mw.i1fnvgqd.bp9cbjyn.owycx6da.btwxx1t3.jei6r52m.wkznzc2l.n851cfcs.dhix69tm.ahb00how,
.os-darwin .rq0escxv.l9j0dhe7.du4w35lb.j83agx80.pfnyh3mw.i1fnvgqd.bp9cbjyn.owycx6da.btwxx1t3.hv4rvrfc.dati1w0a.f10w8fjw.pybr56ya.b5q2rw42.lq239pai.mysgfdmx.hddg9phg {
-webkit-app-region: drag !important;
}
.os-darwin .rq0escxv.l9j0dhe7.du4w35lb.j83agx80.pfnyh3mw.i1fnvgqd.bp9cbjyn.owycx6da.btwxx1t3.jei6r52m.wkznzc2l.n851cfcs.dhix69tm.ahb00how {
margin: 0 !important;
padding: 12px 16px 0 !important;
}
.os-darwin .rq0escxv.l9j0dhe7.du4w35lb.j83agx80.cbu4d94t.g5gj957u.d2edcug0.hpfvmrgz.kud993qy.buofh1pr {
margin-top: 24px !important;
}

@media (max-width: 900px) {
.os-darwin .rq0escxv.l9j0dhe7.du4w35lb.jbae33se.hv4rvrfc.dati1w0a.pybr56ya {
display: none !important;
}
.os-darwin .rpm2j7zs.k7i0oixp.gvuykj2m.j83agx80.cbu4d94t.ni8dbmo4.du4w35lb.q5bimw55.ofs802cu.pohlnb88.dkue75c7.mb9wzai9.d8ncny3e.buofh1pr.g5gj957u.tgvbjcpo.l56l04vs.r57mb794.kh7kg01d.eg9m0zos.c3g1iek1.l9j0dhe7.k4xni2cv {
padding-top: 36px !important;
}
}

/* -- Sidebar views -- */

/* Hidden: Hide sidebar */
Expand Down
Loading