Skip to content

Omarchy: hey omarchy poll, the engine under the 37signals.hey bar plugin - #236

Closed
jeremy wants to merge 4 commits into
mainfrom
omarchy-poll
Closed

Omarchy: hey omarchy poll, the engine under the 37signals.hey bar plugin#236
jeremy wants to merge 4 commits into
mainfrom
omarchy-poll

Conversation

@jeremy

@jeremy jeremy commented Aug 21, 2026

Copy link
Copy Markdown
Member

What

basecamp/omarchy-hey-plugin (Jason, Rob) is a Quickshell bar widget that shells out to hey for the Imbox; hey setup omarchy installed an inline hey-unread module in the same bar. Neither knew of the other — both installed meant two HEY icons and two Imbox pollers. Decision: the CLI is the engine, the plugin is the face. One Imbox fetch serves the panel, the icon and the toasts.

  • hey omarchy poll --limit N [--notify] (visible; replaces the hidden bar-status, which never shipped). Same envelope as hey box imbox --json, byte for byte. --notify diffs the unseen set against the fingerprint file and toasts at most once, under a flock (the shell builds its bar once per monitor, so two instances poll concurrently). Errors are errors: auth envelope when logged out, config_error on an unloadable global config, a failed later page fails the poll (the toasts still get the pages that were read). A poll without --notify deletes the fingerprints, so toasts turned on by any route — setup, the plugin's toggle, omarchy bar set — start from a silent seed.
  • hey setup omarchy no longer installs a bar module. It removes a legacy hey-unread (own step, notify preference carried over to the plugin when the plugin is silent) and flips notify on the plugin's shell.json entry. No plugin → skipped with the install command; setup never clones.
  • TUI pushes omarchy-shell -q 37signals.hey refresh after every posting mutation and Screener decision. No-op off Omarchy.
  • Smoke: tests/smoke/omarchy_test.go (poll matches box imbox, --notify seeds under an isolated XDG_STATE_HOME, bad --limit).

Companion plugin PR: basecamp/omarchy-hey-plugin hey-cli-engine (draft, off plugin-design). Docs: docs/omarchy.md records the decision and the new contract.

Release note

Do not release 0.2.0 until the plugin repo is public and its PR is merge-approved — the README now points users at it.

Verified

make build && make test && make lint, make check-surface-compat (additions only: hey omarchy, hey omarchy poll --limit/--notify). Plugin: ./tests/run (11 node + 15 QML) and omarchy plugin validate green against this branch.


Summary by cubic

Unifies HEY bar behavior: the CLI is the engine and the bar plugin is the face. hey omarchy poll now powers the 37signals.hey plugin so one Imbox fetch drives the panel, icon, and toasts, eliminating duplicate icons and pollers.

  • Old vs new setup: hey setup omarchy no longer installs a bar module. It removes a legacy hey-unread on sight and configures notify on the 37signals.hey plugin if present; without the plugin it skips with install guidance.
  • Poll behavior: hey omarchy poll --limit N [--notify] returns the exact hey box imbox --json data shape; the response envelope also carries box breadcrumbs. With --notify, it diffs unseen threads against fingerprints and toasts each at most once under an advisory read-only flock on a stable lock file; without --notify, it clears fingerprints under the same lock. If HOME/XDG_STATE_HOME does not resolve to an absolute state dir, the poll refuses to read/write state and skips notifications. Errors surface as envelopes: auth when logged out, config_error on an unreadable global config; a failed later page fails the poll (already-read pages may still toast).
  • Immediate UI updates: the TUI nudges the bar via omarchy-shell -q 37signals.hey refresh after posting mutations and Screener decisions.

Review and rollout

  • Review: internal/cmd/omarchy_poll.go (engine), internal/cmd/omarchy_lock_unix.go (serialized notify; lock inode stable), internal/cmd/omarchy_notify.go (state guarded and refuses relative dirs), and TUI refresh in internal/tui/omarchy_refresh.go. Tests cover JSON parity with box imbox, breadcrumbs, locking, and notify seeding.
  • Migration:
    • Install the plugin: omarchy plugin add https://github.com/basecamp/omarchy-hey-plugin.git --enable
    • Configure toasts: hey setup omarchy --notify or --no-notify
  • Release hold: do not release until basecamp/omarchy-hey-plugin is public and its PR is approved; the README points to it.

Written for commit d1f0f5f. Summary will update on new commits.

Review in cubic

basecamp/omarchy-hey-plugin is a Quickshell bar widget that shells out to
hey for the Imbox; hey setup omarchy installed an inline hey-unread module
in the same bar. Neither knew of the other, and both installed meant two
HEY icons and two Imbox pollers in one slot. Decision: the CLI is the
engine, the plugin is the face. One Imbox fetch serves the panel, the icon
and the toasts.

hey omarchy poll --limit N [--notify] replaces the hidden bar-status. It
answers in the shape of hey box imbox --json, byte for byte, so the plugin's
parser does not change; with --notify the same read diffs the unseen
postings against the fingerprint file and sends at most one toast, under a
flock because the shell builds its bar once per monitor and two instances
poll at once. Errors are errors now -- logged out is the auth envelope the
plugin turns into its sign-in button, a global config that cannot load is
config_error, and a later page that fails fails the poll rather than handing
the panel a short list to replace its last complete one (the toasts still
get the pages that were read). A poll without --notify deletes the
fingerprints, so toasts turned on by any route -- hey setup omarchy, the
plugin's toggle, omarchy bar set -- start from a silent seed.

hey setup omarchy no longer installs a bar module. It removes a legacy
hey-unread on sight, reported as its own step, and configures the plugin's
entry in shell.json instead: --notify sets notify true, --no-notify deletes
the key, a plain run leaves it, and a legacy module's --notify carries over
when the plugin has not been told either way. Without the plugin the step
skips and says how to install it; setup never clones on the user's behalf.

The TUI pushes omarchy-shell -q 37signals.hey refresh after every posting
mutation and Screener decision, so the icon goes dark the moment a thread
is archived instead of at the next poll. A no-op off Omarchy.
@jeremy
jeremy requested a review from a team as a code owner August 21, 2026 07:16
Copilot AI balanced review requested due to automatic review settings August 21, 2026 07:16
Comment thread internal/cmd/omarchy_lock_unix.go Fixed

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Makes hey omarchy poll the data and notification engine for the Omarchy HEY bar plugin.

Changes:

  • Adds paginated Imbox polling, notification state, and cross-monitor locking.
  • Migrates setup from the legacy inline bar module to plugin configuration.
  • Pushes plugin refreshes after relevant TUI mutations and expands tests/docs.

Tip

If you aren't ready for review, convert to a draft PR.
Click "Convert to draft" or run gh pr ready --undo.
Click "Ready for review" or run gh pr ready to reengage.

Reviewed changes

Copilot reviewed 20 out of 20 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
.surface Registers the new command surface.
README.md Documents plugin installation and setup.
docs/omarchy.md Defines the plugin/CLI integration contract.
internal/cmd/box.go Extracts shared box table rendering.
internal/cmd/omarchy.go Migrates setup to plugin configuration.
internal/cmd/omarchy_lock_other.go Adds non-Unix lock fallback.
internal/cmd/omarchy_lock_unix.go Adds Unix poll serialization.
internal/cmd/omarchy_lock_unix_test.go Tests lock serialization.
internal/cmd/omarchy_notify.go Updates notification state handling.
internal/cmd/omarchy_notify_test.go Updates notification/setup tests.
internal/cmd/omarchy_poll.go Implements hey omarchy poll.
internal/cmd/omarchy_poll_test.go Tests polling, pagination, and errors.
internal/cmd/omarchy_test.go Tests plugin setup migration.
internal/cmd/root.go Preserves configuration-load errors for polling.
internal/tui/mail.go Refreshes the plugin after mail mutations.
internal/tui/omarchy_refresh.go Adds Omarchy refresh IPC.
internal/tui/omarchy_refresh_test.go Tests refresh behavior.
internal/tui/screener.go Refreshes after Screener changes.
tests/smoke/helpers_test.go Isolates smoke-test state.
tests/smoke/omarchy_test.go Adds poll smoke coverage.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread internal/cmd/omarchy_poll.go Outdated
Comment thread internal/cmd/omarchy_poll.go
Comment thread internal/cmd/omarchy.go Outdated
Comment thread internal/cmd/omarchy_notify.go
Comment thread tests/smoke/helpers_test.go
Comment thread docs/omarchy.md Outdated
Comment thread docs/omarchy.md Outdated
jeremy added 2 commits August 21, 2026 00:20
…n change

The lock sidecar is no longer unlinked by non-notify polls -- a poller
holding the old inode and one locking a fresh one would diff at once -- and
state deletion happens under the lock. The bar plugin step says installed
only when its notify setting changed; a legacy removal in the same pass is
the bar indicator step's news. Stale bar-status fixture, smoke state dir
cleanup, and the docs now say what is byte-identical (the data, not the
envelope), which file is flocked, and that the toast's N counts arrivals.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2251fb0c20

ℹ️ 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".

Comment thread internal/cmd/omarchy_poll.go Outdated
Comment thread internal/cmd/omarchy_poll.go Outdated
…te dir

Without HOME and XDG_STATE_HOME (or with a relative XDG_STATE_HOME) the
state path resolved into the working directory, where a non-notify poll
would have deleted a bystander omarchy-poll.json and a notify poll written
one. The poll now leaves fingerprints alone entirely in that case and the
toasts stay off, as they do when the identity is unknown; save and remove
refuse outright. The poll envelope carries hey box's breadcrumbs too.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d1f0f5f535

ℹ️ 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".

switch {
case !omarchyPollStateUsable():
case !c.notify:
_ = removeOmarchyPollState()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Prevent in-flight notify polls from restoring disabled state

When per-monitor polls straddle disabling notifications, this deletion can finish while an older --notify poll is still fetching; that older poll subsequently takes the lock, observes no state, and silently writes a new seed. If notifications are re-enabled before another non-notifying poll runs, mail accumulated while they were off is compared against this resurrected seed and can be toasted, violating the documented silent re-enable behavior. Keep the disable decision ordered with in-flight notifying polls, for example with a persisted disabled generation/tombstone or a lock covering the relevant poll lifecycle.

Useful? React with 👍 / 👎.

Comment thread internal/cmd/omarchy.go
// The lock sidecar goes only here, at teardown: a live poller holding it
// would otherwise be left with an unlinked inode while the next poll
// locks a fresh one, and the two would diff at once.
_, _ = removeFileIfPresent(omarchyPollLockPath())

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Refuse to unlink a relative poll lock during teardown

With an absolute HOME but relative XDG_STATE_HOME, hey setup omarchy --remove passes its home check and removeOmarchyPollState() correctly refuses the unsafe state path, but this direct cleanup still resolves the lock path relative to the process working directory and unlinks it. Fresh evidence beyond the earlier state-path fix is this teardown-only bypass of the validated helper, which can delete an unrelated state/hey-cli/omarchy-poll.json.lock; only remove the sidecar after confirming the state directory is absolute.

Useful? React with 👍 / 👎.

@jeremy

jeremy commented Aug 21, 2026

Copy link
Copy Markdown
Member Author

Superseded by #243: hey watch --notify (a generic flag on a generic command) plus the plugin running hey watch as a one-per-shell service, in place of the hey omarchy group. The hey setup omarchy changes from this PR carry over unchanged; the poll, its state file and lock, and the TUI's IPC nudge do not.

@jeremy jeremy closed this Aug 21, 2026
@jeremy
jeremy deleted the omarchy-poll branch August 21, 2026 16:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants