Skip to content

feat: macOS menubar app that provides network ingress/egress filtering and better UX#60

Open
lox wants to merge 10 commits intomainfrom
codex/macos-menubar-mvp
Open

feat: macOS menubar app that provides network ingress/egress filtering and better UX#60
lox wants to merge 10 commits intomainfrom
codex/macos-menubar-mvp

Conversation

@lox
Copy link
Contributor

@lox lox commented Mar 1, 2026

Summary

  • add a new macOS menubar app (macos/main.swift) with a one-click Enable Cleanroom onboarding flow
  • default to user LaunchAgent management for cleanroom serve, with advanced controls for restart/stop and optional system daemon install
  • add Run Server At Login toggle persisted in app preferences and reflected in generated LaunchAgent plist
  • bundle runtime assets into Cleanroom.app: cleanroom, cleanroom-darwin-vz, linux guest-agent artifact, app icon + menubar template icons
  • add build/install scripts and mise tasks for building/installing the app bundle
  • update darwin-vz binary discovery so helper/guest-agent resolution works when CLI is symlinked to app-bundled binary
  • document architecture and rollout plan in docs/macos-app.md

Testing

  • mise exec go -- go test ./internal/backend/darwinvz ./internal/cli -run 'Test|ServeInstall|ServeCommand|DaemonRunArgs'
  • mise run build:macos-app
  • mise run install:macos-app
  • mise run lint-shell
  • manual check: app-bundled CLI resolves helper + guest-agent and cleanroom doctor reports 0 fail for helper_binary / guest_agent_binary

Notes

  • intentionally did not commit macos/app-icon.pxd (source design artifact); PNG assets used by build are committed

Copy link

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

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: d5cc6b65b6

ℹ️ 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 on lines +241 to +243
if queryUserServiceLoaded() {
_ = try runCommand("/bin/launchctl", ["kickstart", "-k", serviceTarget])
return

Choose a reason for hiding this comment

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

P2 Badge Re-bootstrap launch agent after updating its plist

startOrRestartUserService always rewrites the LaunchAgent plist, but when the job is already loaded this branch only runs launchctl kickstart -k and returns. That means changes in the plist (notably ProgramArguments when Cleanroom.app moves or is reinstalled, and KeepAlive/RunAtLoad toggles) are not reloaded into launchd, so the service can keep using stale settings or fail to restart after an app path change. Reloading with bootout + bootstrap when the plist is updated avoids this stale-config path.

Useful? React with 👍 / 👎.

@lox lox changed the title Add macOS menubar app onboarding flow and bundle darwin-vz runtime helpers feat: macOS menubar app that provides network ingress/egress filtering and better UX Mar 1, 2026
@lox
Copy link
Contributor Author

lox commented Mar 1, 2026

@codex review please

Copy link

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

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: f0248d295d

ℹ️ 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 on lines +1378 to +1382
tempPath := path + ".tmp"
if err := os.WriteFile(tempPath, data, 0o644); err != nil {
return fmt.Errorf("write network filter policy snapshot temp file: %w", err)
}
if err := os.Rename(tempPath, path); err != nil {

Choose a reason for hiding this comment

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

P1 Badge Use per-write temp files for policy snapshot updates

writeNetworkFilterPolicySnapshot always writes through the fixed path path + ".tmp", but SyncNetworkFilterPolicy() is invoked from multiple execution lifecycle paths and can run concurrently. Two overlapping syncs can overwrite each other’s temp file and cause one os.Rename to fail (or publish stale content), leaving outdated allow/process_rules in place until a later sync, which can make host filtering inconsistent with currently running executions.

Useful? React with 👍 / 👎.

Comment on lines +13 to +14
func evaluateNetworkPolicyForDoctor(networkDefault string, allowCount int, allowlistSupported bool) (string, error) {
return evaluateNetworkPolicy(networkDefault, allowCount, allowlistSupported, false)

Choose a reason for hiding this comment

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

P2 Badge Enforce allowlist availability in doctor policy checks

evaluateNetworkPolicyForDoctor explicitly disables allowlist enforcement, so when sandbox.network.allow is present and host filtering is unavailable, doctor only warns even though the run path rejects that same configuration as an error. This creates a misleading diagnostic path where cleanroom doctor can appear healthy but execution still fails immediately for policy reasons.

Useful? React with 👍 / 👎.

@lox lox force-pushed the codex/macos-menubar-mvp branch from f0248d2 to c2f6957 Compare March 3, 2026 03:10
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.

1 participant