Skip to content

[companion] fix(notifications): mark a notification read when its toast is opened - #93

Open
andrebrait wants to merge 8 commits into
companion/toast-click-marks-read-basefrom
fix/toast-click-marks-read
Open

andrebrait wants to merge 8 commits into
companion/toast-click-marks-read-basefrom
fix/toast-click-marks-read

Conversation

@andrebrait

@andrebrait andrebrait commented Oct 9, 2026 •

Copy link
Copy Markdown
Owner

Review companion for kahme247#242: same head branch, base pinned to the same upstream/main commit (cf64eb8), so the diff is identical. Bot reviews only; merge happens upstream.

Summary by CodeRabbit

  • Notifications
    • Opening a toast by clicking it or pressing Enter marks its notification as read and removes it from the unread count. Interacting with controls inside the toast does not mark it as read.
    • Repeated notifications with the same ID are unread again by default. Update notices remain read when shown again after being marked read.

@coderabbitai

coderabbitai Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: b77a7434-fea6-44fe-b31f-fd79537841b4

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 0c537bd5-40a7-40c2-bc35-36212428201b


📥 Commits

Reviewing files that changed from the base of the PR and between cf64eb8 and e42d0f7.



📒 Files selected for processing (6)
  • AGENTS.md
  • CHANGELOG.md
  • components/AppShell.tsx
  • components/ui/toast.click.test.mjs
  • components/ui/toast.test.mjs
  • components/ui/toast.tsx


Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.




📝 Walkthrough
📝 Walkthrough

Walkthrough

Toast card activation now marks its history entry as read. Reused toast IDs become unread unless keepRead preserves a previously read state. Update availability toasts now pass keepRead: true.

Changes

Toast history and activation

Layer / File(s) Summary
History read-state rules
components/ui/toast.tsx, components/ui/toast.test.mjs
toastHistory.record preserves a reused entry’s read state only when keepRead is true. The add helper forwards the option. Tests cover re-announcing entries.
Toast activation marks entries read
components/ui/toast.tsx, components/ui/toast.click.test.mjs
Clicking or pressing Enter on a toast card marks its history entry read before closing it. Tests check that inner-button Enter and other non-activating interactions leave the entry unread.
Update notices retain read state
components/AppShell.tsx, AGENTS.md, CHANGELOG.md
Both update availability toasts pass keepRead: true. The documentation describes toast activation and reused-ID read-state behavior.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Suggested reviewers: kahme247



Merge Risk: ⚪ Minimal · up to e42d0

The changed toast read-state behavior and update-notice exception are consistent with the documented rules; no concrete merge-blocking risk remains.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 4 files. (2 skipped: 2 … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the primary change: opening a notification toast marks it as read.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.


Full details: Docstring Coverage

Explanation

Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 4 files. (2 skipped: 2 unsupported.)




✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR


🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR



  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@andrebrait

Copy link
Copy Markdown
Owner Author

@codex review

@andrebrait

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-09T07:33:29.046809Z e42d0f7 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. More of your lovely PRs please.

Reviewed commit: e42d0f794d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

kahme247 and others added 3 commits October 9, 2026 20:09
… panel

Closes kahme247#239, kahme247#232, kahme247#237, kahme247#234, kahme247#235, kahme247#236.

## Password hashes, and keeping them out of child processes (kahme247#239)

A plaintext web password now stops the server at startup instead of starting
it, and omp-web refuses every request while one is configured. Every omp
session inherits omp-web's environment, so an agent running `env` could print
the password into its session file and send it to the model provider.

- `OMP_WEB_PASSWORD_HASH` is the only accepted credential, in a self-describing
  scrypt format (`scrypt$ln$r$p$salt$digest`, N = 2^15 by default). The cost is
  floored on read, so a hand-written weak hash cannot be walked back.
- `ompweb hash-password` reads the password from stdin (never argv) with the
  echo off, so it stays out of shell history and out of `ps`.
- Sessions are signed with a per-installation random key created on first start
  at `~/.omp/agent/omp-web/web-auth-secret.json` (mode 0600) mixed with the
  hash: a copied hash cannot forge a cookie, and changing the password still
  signs every browser out.
- omp-web's own secrets are stripped from every child environment through
  `createChildProcessEnvironment` (lib/project-command-env.ts): omp sessions
  and one-shot RPCs, plugin install/upgrade, skill install/update/search,
  update checks and the self-update worker, agent unpack, the Git commands the
  file panel and workspace list run, and the spawned PowerShell helpers.
  Configuration such as `OMP_WEB_OMP_BIN` still reaches the processes that read
  it.
- The service installers hash what they are given: systemd, launchd, the Linux
  tray's Set Web Password and the Windows service/tray scripts write only the
  hash, and the tray prompts for a password when exposing past loopback.

## Queue by default, and stop aborting on a running shell command (kahme247#237)

Submitting while the agent works now queues the message instead of steering:
steering a long tool or shell command could abort the turn mid-task and left
the new message undelivered. `getSubmitDuringRunBehavior()` defaults to
`queue`; only a stored choice overrides it.

Sending during omp-web's own `!!` shell command no longer fails with "Cannot
send a prompt while a shell command is running": the wrapper degrades the frame
into omp's `follow_up` queue (`queueWhileShellRunning`) and reports
`{queued:true, reason:"shellRunning"}`, which the hook surfaces as a notice
while withdrawing the phantom optimistic turn. The queue chips still come from
omp's own snapshot.

## Expand thinking blocks by default (kahme247#232)

An off-by-default switch next to **Keep tool calls collapsed**, the same shape
as that preference: `omp-web:expand-thinking` in AppShell, a Settings toggle,
and a `MessageView` prop that seeds `ThinkingBlock` as an initial value only,
so manual collapse/expand keeps working. It deliberately covers a streaming
block too, and a historical block that is `deferred` loads its text through the
same loader the click path uses.

## Fit the agent's question panel on a phone (kahme247#234, kahme247#235, kahme247#236)

- Pin the `ask` grids to `minmax(0, 1fr)` with `min-width: 0` on the panel, its
  scroller, the option rows and their text, so a long question, header or
  preview can no longer widen the panel past the composer column and clip the
  answer text; previews wrap instead of scrolling sideways (kahme247#234).
- Stop the composer-attached focus effect from pulling focus into the answer box
  on touch input or a phone width, which raised the on-screen keyboard over the
  unread question. Desktop focus behavior is unchanged (kahme247#235).
- Keep the footer reachable with the keyboard up by capping the panel to the
  visual viewport while it is open, plus an inline send button beside the typed
  answer that shares the footer's validation; the dialog's buttons follow the
  **Touch Targets** setting (kahme247#236).

BREAKING CHANGE: `OMP_WEB_PASSWORD` and `ompweb --password` no longer work and
refuse to start. Generate a hash with `ompweb hash-password` and set
`OMP_WEB_PASSWORD_HASH`. Existing sessions are invalidated.
@andrebrait
andrebrait force-pushed the fix/toast-click-marks-read branch from e42d0f7 to 4bec966 Compare October 10, 2026 07:33
kahme247#238)

* feat(auth): skip the password for requests a trusted proxy vouches for

OMP_WEB_TRUSTED_HEADER_SHA256 holds the SHA-256 digest of a secret a reverse
proxy sends in X-Omp-Web-Auth for trusted client ranges; a matching request
counts as signed in. omp-web never holds the secret, and the digest is stripped
from child processes like the other omp-web secrets. Service installers and the
Windows launchers pass it on.

The Windows tray (native and PowerShell) and background service now read
OMP_WEB_PASSWORD_HASH, the legacy OMP_WEB_PASSWORD and the digest fresh from
the user, then system, environment on every server start, so rotating or
removing them with setx takes effect at the next restart. bin/omp-web-tray.exe
is rebuilt from native/tray.

README documents the nginx setup (realip for Cloudflare, Cloudflare Tunnel and
other proxies, DNS-rebinding guard) and generating the secret without it
reaching shell history.

* docs(auth): drop reusing a chosen proxy secret; require the generated one

The digest is a fast unsalted SHA-256, safe only for a long random secret.

* fix(auth): keep stripping the legacy trusted-proxy secret name from child processes
…me247#243)

* fix(sessions): find the first user message past injected context

omp writes rules, skills and memory-recall entries before the first user
message, which pushes it past the 4 KiB list-scan prefix. The sidebar then
showed "(no messages)" and auto-name refused with no messages to name until
omp set a title. When the prefix has no user message, scan up to 256 KiB.

* fix(sessions): scan for the first user message without a fixed window

Injected context larger than 256 KiB still hid the first user message.
Stream lines until the first textual user entry instead; forEachFileLineSync
now stops when onLine returns false.

* fix(sessions): skip the first-message scan for files past the load ceiling

The streaming scan read oversized files whose prefix has no user message,
and a line past the JS string cap threw, so scanSessionInfo dropped the
session and its route returned 404 instead of 413.
…h hash-password on Enter (kahme247#244)

* fix(hash-password): finish the hidden prompt on Enter

A terminal in raw mode sends Enter as a carriage return, so the prompt
waited for a newline that never came. End the line at \r or \n.

* feat(auth): migrate a plaintext OMP_WEB_PASSWORD to a hash at startup

ompweb hashes OMP_WEB_PASSWORD, removes it from the environment before
starting the server, and logs a warning with the hash to set as
OMP_WEB_PASSWORD_HASH. --password, or both variables set, still stops it.

* fix(auth): test the password migration end to end and document its limits

Inline the migration in the launcher and replace the source-text security
test with one that runs the launcher against a stub server and checks the
environment it receives. Refuse both variables with a direct message, and
note in the warning and docs that the launcher process still holds the
plaintext.

* fix(auth): word the OMP_WEB_PASSWORD warning as a deprecation
…from the Notifications tab (kahme247#240)

* fix(notifications): list OS-shown notifications and open their session from the Notifications tab

* test(notifications): pin the row's Enter, expand and selection guards and the OS kind

* fix(notifications): list Web Push notifications shown while a tab is open
…ks-read

# Conflicts:
#	CHANGELOG.md
#	components/ui/toast.tsx
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants