internal-joseph/pulse
  • Rust 46.9%
  • JavaScript 46.3%
  • HTML 6%
  • Shell 0.8%
Find a file
Joseph 230000bb2e fix(desktop): popup buttons fire again — addEventListener + hide() + main-thread close
Resolves the long-running "standup done button doesn't do anything" bug.
Three independent root causes were compounded — each individually prevented
the popup from closing:

1. `user-select: none` on <body> silently swallows mousedown on <button>
   descendants in Tauri v2 + WebView2. Removed from body, scoped to
   non-interactive elements only (.message, .checks, .header, etc).

2. Inline `onclick="..."` / `onmousedown="..."` attributes on <button>
   elements do not execute at all in Tauri v2 + WebView2. Handlers must
   be bound via JS addEventListener. Migrated both standup and phase
   popup buttons to the addEventListener pattern.

3. `window.close()` / `window.destroy()` called from inside the webview's
   own Tauri command handler races with WebView2 tear-down and crashes
   the daemon with ERROR_CLASS_HAS_WINDOWS on Chrome_WidgetWin_0 (the
   tray window shares the class). Replaced with:
   - Rust commands schedule close via `app.run_on_main_thread()` from
     a new `defer_close()` helper — close runs AFTER the command returns.
   - Close functions use `window.hide()` instead of `destroy()` — keeps
     the webview alive so the next fire re-shows and refocuses the same
     window. No class unregister, no crash.
   - show_standup_popup / show_phase_popup now call `.show()` + (for
     standup) `.set_focus()` if a hidden instance already exists.

Also in this commit:

- Scheduler honors PULSE_SKIP_WORK_HOURS=1 as a full "dev quiet" mode:
  startup gate bypassed, check_end_of_day suppressed, AND all ambient
  auto-fire (phase popups, standups, closing mode, reflection, weekly)
  skipped so only manual tray triggers surface UI during testing.

- 10-second standup done-button countdown disabled while the underlying
  close flow was being debugged. Can be re-enabled later by reverting
  the script block in standup-popup.html.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 16:45:40 -05:00
cli feat(week): weekly summary view — CLI, daemon trigger, converter + sync 2026-04-11 14:05:59 -05:00
converter feat(week): weekly summary view — CLI, daemon trigger, converter + sync 2026-04-11 14:05:59 -05:00
desktop fix(desktop): popup buttons fire again — addEventListener + hide() + main-thread close 2026-04-11 16:45:40 -05:00
docs feat(week): weekly summary view — CLI, daemon trigger, converter + sync 2026-04-11 14:05:59 -05:00
server feat(week): weekly summary view — CLI, daemon trigger, converter + sync 2026-04-11 14:05:59 -05:00
.gitignore fix(desktop): popup dismiss, focus stealing, and standup re-fire loop 2026-04-09 12:29:01 -05:00
README.md docs: add weekly summary to README feature list 2026-04-11 14:39:34 -05:00

Pulse

Wellness + cadence daemon for the human meat-vehicle.

  • Hourly stand-up checks — bundled with water refill
  • 15-min phase popups — "What's the focus?" with inferred chips
  • Closing mode — open-loop scanner (dirty repos, unpushed commits, dangling topics)
  • EOD reflection — daily narrative via local LLM
  • Weekly summary — Monday rollup via Claude Opus, categorized, collapsible, regeneratable
  • Web view — pulse.pctbin.com (phase timeline, ECG day-line, Claude sessions, Week dropdown)

Architecture

  • desktop/ — Rust + Tauri v2 (Windows workstation daemon)
  • converter/ — Node.js (lifted from agent-journal, extended with phase-band + ECG SVG)
  • server/ — Node.js refresh server (port 3999, deploys to VMID 133)
  • cli/pulse today, pulse log, pulse suggestions, pulse week {generate,show,list,current}

Status

Live. Daemon running from %LOCALAPPDATA%\PCT\pulse\pulse-desktop.exe (Task Scheduler autostart on logon). Web view at https://pulse.pctbin.com refreshes every 2h via the Node.js refresh server. All v1 issues closed 2026-04-10.

See docs/pulse-design.md for full design spec.