Skip to content

feat: ship packaged macOS menu bar companion#387

Open
jaycho46 wants to merge 16 commits into
lidge-jun:devfrom
jaycho46:feat/menubar-app
Open

feat: ship packaged macOS menu bar companion#387
jaycho46 wants to merge 16 commits into
lidge-jun:devfrom
jaycho46:feat/menubar-app

Conversation

@jaycho46

@jaycho46 jaycho46 commented Jul 24, 2026

Copy link
Copy Markdown

Summary

  • Adds a native OpenCodex macOS menu bar companion under apps/macos-menu-bar for proxy running/health status and common actions.
  • Extends ocx status --json with structured health metadata consumed by the companion.
  • Packages the macOS app in the existing Release workflow and attaches .zip + checksum assets to GitHub Releases.
  • Documents the companion and first-launch Gatekeeper path across docs locales.

Closes #386

Verification

  • bun x tsc --noEmit
  • bun test --isolate tests/cli-status-json.test.ts
  • Rebased onto current upstream/dev; merge-tree check is clean
  • Release flow kept on existing jawcode-style path: main/preview only, dry-run first, expected-sha retained

Checklist

  • Scope stays focused and avoids unrelated cleanup.
  • Docs or release notes were updated when needed.
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults.

Summary by CodeRabbit

  • New Features
    • Added a native macOS 12+ menu bar companion for proxy monitoring and start/restart/stop controls.
    • Added macOS universal packaging support (ZIP + SHA-256) with integrity checks.
  • Documentation
    • Published new macOS companion guides (including multi-language build/use instructions and app signing/notarization expectations).
  • Bug Fixes
    • Enhanced ocx status --json with proxy.health.version and proxy.health.uptimeSeconds, including when the proxy is unreachable.
  • Release & CI
    • Updated CI to run macOS-specific tests/build steps and expanded workflow triggers; release workflow now builds, verifies, and attaches the macOS asset.

@github-actions github-actions Bot added the enhancement New feature or request label Jul 24, 2026
@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Changes

Adds a native Swift macOS menu bar companion that reads ocx status --json, displays proxy state, and delegates lifecycle operations to the CLI. The PR adds app bundling and universal release packaging, extends health JSON with version and uptime, updates CI, and documents the feature in supported languages.

macOS companion

Layer / File(s) Summary
Structured proxy health contract
src/cli/status.ts, tests/cli-status-json.test.ts, docs-site/src/content/docs/*/reference/cli.md
proxy.health now includes nullable version and uptimeSeconds values populated from /healthz, with success and failure coverage.
Swift core status and CLI control
apps/macos-menu-bar/Package.swift, apps/macos-menu-bar/Sources/OpenCodexMenuBarCore/*, apps/macos-menu-bar/Tests/*
Defines status models, lifecycle command plans, CLI discovery and persistence, subprocess execution, and core tests.
Menu bar status and actions
apps/macos-menu-bar/Sources/OpenCodexMenuBar/*
Creates the AppKit status item, renders status details, polls asynchronously, and handles dashboard, lifecycle, refresh, CLI selection, reset, and quit actions.
App bundle and release artifacts
apps/macos-menu-bar/Info.plist, scripts/*macos*, .github/workflows/*, package.json
Builds and ad-hoc signs the app, supports universal binaries, creates ZIP/checksum artifacts, verifies them, and attaches them to releases.
Companion documentation and architecture
README.md, docs-site/src/content/docs/*/guides/macos-menu-bar.md, structure/*.md
Documents build, packaging, CLI delegation, menu behavior, CLI discovery, and login-item integration.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant AppDelegate
  participant OcxClient
  participant OcxCLI
  participant Proxy
  User->>AppDelegate: open menu bar companion
  AppDelegate->>OcxClient: fetchStatus()
  OcxClient->>OcxCLI: run status --json
  OcxCLI->>Proxy: request /healthz
  Proxy-->>OcxCLI: return health metadata
  OcxCLI-->>OcxClient: return status JSON
  OcxClient-->>AppDelegate: return OcxStatus
  AppDelegate-->>User: render proxy status and details
Loading

Possibly related PRs

Suggested reviewers: ingwannu, lidge-jun

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 1.85% which is insufficient. The required threshold is 80.00%. 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 is concise and accurately captures the main change: shipping a packaged macOS menu bar companion.
Linked Issues check ✅ Passed The PR implements the macOS companion, structured status, actions, release packaging, ad-hoc signing, and Gatekeeper docs requested in #386.
Out of Scope Changes check ✅ Passed The shown changes stay focused on the macOS companion, release packaging, status contract, and related documentation/testing.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@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: 03c4e8ac91

ℹ️ 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 apps/macos-menu-bar/Sources/OpenCodexMenuBarCore/StatusModels.swift

@coderabbitai coderabbitai 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.

Actionable comments posted: 6

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/release.yml:
- Around line 34-35: Restrict workflow permissions by removing workflow-level
id-token: write and granting it only in the gated publish job; keep
package-macos limited to its minimum required permissions, and set
persist-credentials: false on its checkout step. Treat these .github/**
security-boundary changes as requiring escalation review for any new secret
usage or permission increase.

In `@apps/macos-menu-bar/Sources/OpenCodexMenuBarCore/OcxClient.swift`:
- Around line 84-103: The run(_:arguments:) method currently waits for process
termination before draining pipes, allowing deadlocks and indefinite blocking.
Update run to concurrently drain stdout and stderr while the process runs,
enforce a finite timeout, and terminate the process when the deadline is
exceeded; preserve the existing successful output and commandFailed handling for
normal exits.

In `@docs-site/src/content/docs/guides/macos-menu-bar.md`:
- Around line 36-37: The macOS menu-bar guide needs explicit first-launch
Gatekeeper approval steps in both locales. In
docs-site/src/content/docs/guides/macos-menu-bar.md at lines 36-37, add
instructions to Control-click the app, choose Open, and use Privacy & Security →
Open Anyway if prompted; add the equivalent Japanese instructions in
docs-site/src/content/docs/ja/guides/macos-menu-bar.md at lines 27-28.

In `@docs-site/src/content/docs/reference/cli.md`:
- Around line 114-115: Qualify the healthy metadata documentation to state that
version and uptimeSeconds are populated only when /healthz provides valid
values; otherwise each is null. Apply the same clarification in
docs-site/src/content/docs/reference/cli.md:114-115,
docs-site/src/content/docs/ja/reference/cli.md:111-112,
docs-site/src/content/docs/ko/reference/cli.md:114-115,
docs-site/src/content/docs/ru/reference/cli.md:120-120, and
docs-site/src/content/docs/zh-cn/reference/cli.md:112-113, keeping all locale
pages consistent with the English CLI documentation.

In `@README.md`:
- Around line 75-85: Update README.md lines 75-85 and the macOS menu bar guides
in docs-site/src/content/docs/ko/guides/macos-menu-bar.md lines 14-34,
docs-site/src/content/docs/ru/guides/macos-menu-bar.md lines 14-29, and
docs-site/src/content/docs/zh-cn/guides/macos-menu-bar.md lines 13-27 to use bun
run build:macos-app and the exact release filename
OpenCodex-<version>-macos-universal.zip.

In `@scripts/package-macos-release.sh`:
- Line 56: Update the archive_name assignment in the macOS release packaging
flow to use lowercase “macos” in the published filename, producing
OpenCodex-<version>-macos-<architecture>.zip while preserving the existing
version and architecture_label components.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: f0149fd9-c6d6-42aa-967c-796ae6e5cd6c

📥 Commits

Reviewing files that changed from the base of the PR and between 3b766d9 and 03c4e8a.

📒 Files selected for processing (33)
  • .github/workflows/ci.yml
  • .github/workflows/release.yml
  • .gitignore
  • README.md
  • apps/macos-menu-bar/Info.plist
  • apps/macos-menu-bar/Package.swift
  • apps/macos-menu-bar/Sources/OpenCodexMenuBar/MenuText.swift
  • apps/macos-menu-bar/Sources/OpenCodexMenuBar/StatusBarIcon.swift
  • apps/macos-menu-bar/Sources/OpenCodexMenuBar/main.swift
  • apps/macos-menu-bar/Sources/OpenCodexMenuBarCore/OcxClient.swift
  • apps/macos-menu-bar/Sources/OpenCodexMenuBarCore/OcxLocator.swift
  • apps/macos-menu-bar/Sources/OpenCodexMenuBarCore/StatusModels.swift
  • apps/macos-menu-bar/Tests/OpenCodexMenuBarCoreTests/OpenCodexMenuBarCoreTests.swift
  • docs-site/astro.config.mjs
  • docs-site/src/content/docs/guides/macos-menu-bar.md
  • docs-site/src/content/docs/ja/guides/macos-menu-bar.md
  • docs-site/src/content/docs/ja/reference/cli.md
  • docs-site/src/content/docs/ko/guides/macos-menu-bar.md
  • docs-site/src/content/docs/ko/reference/cli.md
  • docs-site/src/content/docs/reference/cli.md
  • docs-site/src/content/docs/ru/guides/macos-menu-bar.md
  • docs-site/src/content/docs/ru/reference/cli.md
  • docs-site/src/content/docs/zh-cn/guides/macos-menu-bar.md
  • docs-site/src/content/docs/zh-cn/reference/cli.md
  • package.json
  • scripts/build-macos-app.sh
  • scripts/package-macos-release.sh
  • scripts/release.ts
  • src/cli/status.ts
  • structure/00_overview.md
  • structure/01_runtime.md
  • structure/05_gui-and-management-api.md
  • tests/cli-status-json.test.ts

Comment thread .github/workflows/release.yml Outdated
Comment thread apps/macos-menu-bar/Sources/OpenCodexMenuBarCore/OcxClient.swift
Comment thread docs-site/src/content/docs/guides/macos-menu-bar.md Outdated
Comment thread docs-site/src/content/docs/reference/cli.md Outdated
Comment thread README.md
Comment thread scripts/package-macos-release.sh Outdated
jaycho46 added 2 commits July 24, 2026 15:26
Keep package-macos on contents:read with persist-credentials disabled so
macOS packaging cannot request the npm OIDC token before release gates.
Prevent hung or chatty ocx subprocesses from deadlocking the serial CLI queue by draining stdout/stderr while the process runs and terminating after a deadline.

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/macos-menu-bar/Sources/OpenCodexMenuBarCore/OcxClient.swift`:
- Around line 98-119: Update the command execution flow around process.run,
group.wait, and process.waitUntilExit to use process.terminationHandler as the
process-exit signal, waiting up to Self.commandTimeout for termination rather
than using pipe EOF or process.isRunning. Drain stdout and stderr separately
after process termination; on timeout, terminate the process, apply a bounded
force-kill fallback if needed, and wait for confirmed exit before throwing
OcxClientError.commandFailed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 00db1b83-ef17-4fb0-bdf5-90f19a737d66

📥 Commits

Reviewing files that changed from the base of the PR and between fbc9c84 and 1454a92.

📒 Files selected for processing (1)
  • apps/macos-menu-bar/Sources/OpenCodexMenuBarCore/OcxClient.swift

Comment thread apps/macos-menu-bar/Sources/OpenCodexMenuBarCore/OcxClient.swift Outdated
jaycho46 added 5 commits July 24, 2026 15:43
Avoid treating "installed, but stale" as startable. Route start/restart
through service install repair, surface a repair label, and mark the
phase as failed until the service is fixed.
Healthy `/healthz` responses may omit version/uptimeSeconds, so
status --json docs now state those fields can be null.
Rename the package script and docs from build:macos to build:macos-app,
and document the lowercase macos release asset name.
Publish OpenCodex-<version>-macos-<arch>.zip so the artifact name matches
the documented release contract.

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docs-site/src/content/docs/ko/guides/macos-menu-bar.md (1)

36-37: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Add the first-launch Gatekeeper procedure to all translated guides.

The English guide explains how to approve the ad-hoc-signed app, but these translations only warn that approval may be required:

  • docs-site/src/content/docs/ko/guides/macos-menu-bar.md#L36-L37: add Control-click → Open and System Settings → Privacy & Security → Open Anyway.
  • docs-site/src/content/docs/ru/guides/macos-menu-bar.md#L28-L29: add the equivalent Russian instructions.
  • docs-site/src/content/docs/zh-cn/guides/macos-menu-bar.md#L27-L27: add the equivalent Chinese instructions.

As per path instructions, translated locale pages must stay in sync with the English source.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs-site/src/content/docs/ko/guides/macos-menu-bar.md` around lines 36 - 37,
Update the translated macOS menu-bar guides to include the complete first-launch
Gatekeeper procedure: in docs-site/src/content/docs/ko/guides/macos-menu-bar.md
lines 36-37, add Control-click → Open and System Settings → Privacy & Security →
Open Anyway in Korean; apply the equivalent Russian instructions in
docs-site/src/content/docs/ru/guides/macos-menu-bar.md lines 28-29 and
equivalent Chinese instructions in
docs-site/src/content/docs/zh-cn/guides/macos-menu-bar.md line 27. Keep all
translated pages synchronized with the English guide.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/macos-menu-bar/Sources/OpenCodexMenuBarCore/StatusModels.swift`:
- Around line 58-62: Update the phase computation in the phase property to
require both proxy.running and proxy.health.ok before returning .running.
Preserve .failed for stale services, and ensure a live but unhealthy proxy
reaches .degraded; add a regression test covering running=true with
health.ok=false.

In `@docs-site/src/content/docs/ko/reference/cli.md`:
- Around line 114-115: Update the Korean nullable-field sentence in the CLI
documentation to use grammatically correct endpoint wording and clarify that
version and uptimeSeconds may each independently be null when omitted by the
endpoint, consistent with the API contract and English documentation.

---

Outside diff comments:
In `@docs-site/src/content/docs/ko/guides/macos-menu-bar.md`:
- Around line 36-37: Update the translated macOS menu-bar guides to include the
complete first-launch Gatekeeper procedure: in
docs-site/src/content/docs/ko/guides/macos-menu-bar.md lines 36-37, add
Control-click → Open and System Settings → Privacy & Security → Open Anyway in
Korean; apply the equivalent Russian instructions in
docs-site/src/content/docs/ru/guides/macos-menu-bar.md lines 28-29 and
equivalent Chinese instructions in
docs-site/src/content/docs/zh-cn/guides/macos-menu-bar.md line 27. Keep all
translated pages synchronized with the English guide.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 3c2379fe-d80d-49a4-ad9f-774a4cee40a7

📥 Commits

Reviewing files that changed from the base of the PR and between 1454a92 and 3560e56.

📒 Files selected for processing (17)
  • README.md
  • apps/macos-menu-bar/Sources/OpenCodexMenuBar/MenuText.swift
  • apps/macos-menu-bar/Sources/OpenCodexMenuBar/main.swift
  • apps/macos-menu-bar/Sources/OpenCodexMenuBarCore/StatusModels.swift
  • apps/macos-menu-bar/Tests/OpenCodexMenuBarCoreTests/OpenCodexMenuBarCoreTests.swift
  • docs-site/src/content/docs/guides/macos-menu-bar.md
  • docs-site/src/content/docs/ja/guides/macos-menu-bar.md
  • docs-site/src/content/docs/ja/reference/cli.md
  • docs-site/src/content/docs/ko/guides/macos-menu-bar.md
  • docs-site/src/content/docs/ko/reference/cli.md
  • docs-site/src/content/docs/reference/cli.md
  • docs-site/src/content/docs/ru/guides/macos-menu-bar.md
  • docs-site/src/content/docs/ru/reference/cli.md
  • docs-site/src/content/docs/zh-cn/guides/macos-menu-bar.md
  • docs-site/src/content/docs/zh-cn/reference/cli.md
  • package.json
  • scripts/package-macos-release.sh

Comment thread apps/macos-menu-bar/Sources/OpenCodexMenuBarCore/StatusModels.swift
Comment thread docs-site/src/content/docs/ko/reference/cli.md Outdated
jaycho46 added 3 commits July 24, 2026 16:30
Track ocx termination with terminationHandler instead of pipe EOF, then
drain pipes separately and force-kill hung processes on timeout.
Treat a live process with failed /healthz as degraded instead of green
running, while keeping stale services as failed/repairable.
Make the Korean status docs say each healthy field may independently be
null when /healthz omits it.

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/macos-menu-bar/Sources/OpenCodexMenuBarCore/OcxClient.swift`:
- Around line 105-124: Synchronize pipe-reading completion before consuming the
buffers in the command execution flow around exitGroup. Track both stdout and
stderr readDataToEndOfFile tasks with a separate DispatchGroup, enter and leave
it around each reader, then wait for that group after process completion and
before assigning stdout and stderr from their boxes; preserve the existing
timeout and termination behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: a3936a80-c3f1-4cd7-89f9-01bf7582f5d6

📥 Commits

Reviewing files that changed from the base of the PR and between 3560e56 and 560b6f0.

📒 Files selected for processing (3)
  • apps/macos-menu-bar/Sources/OpenCodexMenuBarCore/OcxClient.swift
  • apps/macos-menu-bar/Sources/OpenCodexMenuBarCore/StatusModels.swift
  • docs-site/src/content/docs/ko/reference/cli.md

Comment thread apps/macos-menu-bar/Sources/OpenCodexMenuBarCore/OcxClient.swift
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant