Files
openchamber/packages/electron/package.json
T
Bohdan Triapitsyn 9cf79a8890 feat(desktop): macOS menu bar tray with live session state and mini-chat UX
Add an always-visible macOS status bar (tray) item that surfaces OpenChamber's
live state and acts as a quick launcher, plus a series of related desktop UX
fixes around mini-chat, window routing, notifications and shortcuts.

Tray (new):
- Monochrome template cube glyph that adapts to the menu bar light/dark.
- Icon-driven activity indicator: a smooth, eased, infinite "breathing" fill
  while sessions are busy; a static filled cube when finished sessions are left
  unread; a plain outline when idle. Text counters next to the icon only for
  actionable states (pending approvals, errors).
- Menu lists active sessions (status glyph, branch, unread count) with overflow
  rolled into a submenu; pending permission/question approvals with inline
  Allow once / Allow always / Deny; quick actions (New Session, New Mini Chat,
  Show OpenChamber, Quit). Header shows the active instance name
  ("Local OpenChamber" or the remote host label) for multi-window clarity.
- Session list sourced from the global (cross-project) sessions store, sorted by
  last-updated, independent of which directories are currently open; live
  status/unread/branch merged in from directory sync stores where available.
  Sub-session (multi-run) activity rolls up to the parent row.
- Event-driven updates (global store + directory stores + notifications +
  registry) with a short debounce; polling kept only as a slow safety net.

Tray/window routing:
- Opening a session from the tray targets the surface the user was last on: if a
  mini-chat is active it switches that existing window to the session in place
  (no new window); otherwise the main window (revealed without a reload).
- app.activate (dock click) restores the last-focused/minimized window instead
  of spawning a new main window; only creates one when nothing is left.
- "Open in main window" and tray session-open now create the main window when
  none exists, queuing the session as a pending deep-link so it opens once the
  fresh renderer is ready.

Mini chat:
- New Mini Chat is now a customizable shortcut, exposed in Settings > Shortcuts,
  in the File menu (hint only, renderer owns the binding), and in the tray.
- Themed splash backdrop on window open to remove the white flash / flicker;
  dismissed once content is ready, leaving the content's single cube logo.
- Mini-chat can switch sessions in place via openchamber:open-session.

Notifications:
- The active/selected session only counts as "seen" when the window is focused,
  so turns completing while the app is backgrounded raise an unread marker;
  refocusing the window clears it.
2026-06-10 00:20:23 +03:00

129 lines
3.6 KiB
JSON

{
"name": "@openchamber/electron",
"version": "1.12.3",
"private": true,
"description": "Electron desktop runtime for OpenChamber",
"author": "OpenChamber",
"type": "module",
"main": "./dist-bundle/main.mjs",
"dependencies": {
"@openchamber/web": "workspace:*",
"electron-context-menu": "^4.1.2",
"electron-log": "^5.4.3",
"electron-updater": "^6.8.3"
},
"devDependencies": {
"@electron/rebuild": "^3.7.0",
"electron": "^41.2.1",
"electron-builder": "^26.0.0"
},
"desktopPrerequisites": [
"Electron runtime dependencies installed via bun install",
"Bun available for sidecar compilation",
"macOS: Xcode + build tools for notarized packaging",
"Windows: NSIS installed for installer creation"
],
"scripts": {
"dev": "node ./scripts/electron-dev.mjs",
"build:web-assets": "node ./scripts/build-web-assets.mjs",
"build": "bun -e \"process.exit(0)\"",
"bundle:main": "bun ./scripts/bundle-main.mjs",
"generate:macos-icon": "node ./scripts/generate-macos-icon-assets.cjs",
"rebuild:native": "node ./scripts/rebuild-native.mjs",
"package": "bun run build:web-assets && bun run bundle:main && bun run rebuild:native && node ./scripts/package.mjs",
"finalize:latest-yml": "node ./scripts/finalize-latest-yml.mjs",
"type-check": "node --check ./main.mjs && node --check ./preload.mjs",
"lint": "node -e \"process.exit(0)\""
},
"build": {
"appId": "dev.openchamber.desktop",
"productName": "OpenChamber",
"files": [
"dist-bundle/main.mjs",
"preload.mjs"
],
"extraResources": [
{
"from": "resources/web-dist",
"to": "web-dist"
},
{
"from": "resources/icons/icon.ico",
"to": "icons/icon.ico"
},
{
"from": "resources/icons/tray",
"to": "icons/tray"
}
],
"afterPack": "scripts/after-pack.cjs",
"directories": {
"buildResources": "resources/icons",
"output": "dist"
},
"artifactName": "${productName}-${version}-${arch}.${ext}",
"npmRebuild": false,
"mac": {
"category": "public.app-category.developer-tools",
"icon": "resources/icons/icon.icns",
"artifactName": "${productName}-${version}-mac-${arch}.${ext}",
"extendInfo": {
"CFBundleIconName": "AppIcon"
},
"hardenedRuntime": true,
"gatekeeperAssess": false,
"entitlements": "resources/entitlements.mac.plist",
"entitlementsInherit": "resources/entitlements.mac.plist",
"notarize": true,
"target": [
"dmg",
"zip"
]
},
"win": {
"icon": "resources/icons/icon.ico",
"target": [
"nsis"
],
"verifyUpdateCodeSignature": false,
"artifactName": "${productName}-${version}-win-${arch}.${ext}"
},
"nsis": {
"oneClick": true,
"perMachine": false,
"installerIcon": "resources/icons/icon.ico",
"uninstallerIcon": "resources/icons/icon.ico",
"installerHeaderIcon": "resources/icons/icon.ico"
},
"dmg": {
"sign": true,
"title": "${productName} ${version}",
"backgroundColor": "#FFFCF0",
"iconSize": 100,
"iconTextSize": 13,
"window": {
"width": 540,
"height": 340
},
"contents": [
{
"x": 180,
"y": 140,
"type": "file"
},
{
"x": 360,
"y": 140,
"type": "link",
"path": "/Applications"
}
]
},
"publish": {
"provider": "github",
"owner": "openchamber",
"repo": "openchamber"
}
}
}