Date: 2026-05-22
Scope: macOS Remodex Menu Bar companion, remodex bridge CLI, macOS launchd bridge lifecycle, and the bridge RPC surface that should or should not be exposed through the Menu Bar.
The Remodex Menu Bar should be a clean macOS control surface over the stable remodex CLI, not a second implementation of bridge lifecycle logic. The current direction is good: the Menu Bar now reads status --json, controls the daemon, displays pairing state, and avoids direct bridge internals. The main remaining issue is that some responsibilities are still split between Swift and Node in ways that will become costly as the bridge grows.
The strongest recommendation is to make the CLI the single control-plane facade for companion apps:
- Keep lifecycle commands in the CLI.
- Add machine-readable contracts for every Menu Bar action.
- Move npm update/version lookup logic out of Swift and into the CLI/bridge package.
- Keep developer/internal commands out of the Menu Bar.
- Add a diagnostic command so the Menu Bar can show actionable local setup issues without duplicating shell checks.
The CLI currently exposes:
remodex upremodex runremodex run-serviceremodex startremodex restartremodex qrremodex pairremodex stopremodex statusremodex reset-pairingremodex resumeremodex watch [threadId]remodex --version
Several commands support --json: start, restart, pair/qr, stop, status, reset-pairing, resume, and --version.
The Menu Bar currently exposes the useful end-user actions:
- Start
- Restart
- Stop
- Pair QR
- Resume
- Refresh
- Reset Pair
- Update, when an update is available
- Open logs folder/stdout/stderr
- Relay override
- Pairing QR display
- CLI availability blocker
This is mostly the correct surface. The commands that should not be shown in the Menu Bar are run, run-service, and watch.
The Menu Bar currently runs npm install -g remodex@latest from Swift. The bridge already has a more robust update-and-restart path through desktop/bridge/updateAndRestart, including timeout handling and delayed restart after the response returns to the client.
Risk:
- Divergent update behavior between iOS and Menu Bar.
- Different timeout/error behavior depending on the entry point.
- Swift must know npm details that belong to the Node package.
- Future package-manager changes would require editing multiple clients.
Recommended fix:
Add remodex update --json and make the Menu Bar call that command. The Node CLI should own:
- npm command construction
- shell environment setup
- timeout
- output truncation
- restart scheduling
- JSON response
Suggested JSON result:
{
"ok": true,
"currentVersion": "1.5.6",
"command": "npm install -g remodex@latest",
"restartScheduled": true,
"restartDelayMs": 750
}The Menu Bar currently infers availability mostly from installed version and fallback behavior. That is workable, but it makes the app guess what the bridge supports.
Recommended fix:
Add a capabilities block to remodex status --json.
Suggested shape:
{
"currentVersion": "1.5.6",
"capabilities": {
"statusJson": true,
"pairJson": true,
"restart": true,
"selfUpdate": true,
"doctorJson": true,
"logsJson": true
}
}This lets the Menu Bar show/hide actions without hardcoding version checks or parsing human-readable output.
The Menu Bar currently calls npm view remodex version --json. The bridge already has a cached package version reader for mobile status paths.
Risk:
- Slow network/npm calls can affect Menu Bar refresh.
- Swift duplicates registry lookup behavior.
- Offline/error behavior may diverge from mobile/bridge behavior.
Recommended fix:
Expose latest package version through status --json or a dedicated remodex version --json, backed by the existing cached package-version reader.
Preferred:
{
"currentVersion": "1.5.6",
"latestVersion": "1.5.7",
"latestVersionCheckedAt": "2026-05-22T18:00:00.000Z"
}up, start, pair, and restart overlap:
up: human flow, start service and print QR.start: service lifecycle, no guaranteed fresh QR.pair: pairing flow, starts/restarts enough to publish a fresh QR.restart: launchd lifecycle, not necessarily a pairing action.
Recommended policy:
- Menu Bar should use
start --json,restart --json,pair --json,stop --json, andstatus --json. - Terminal users can keep using
up. - Documentation should call
paircanonical andqran alias.
run-service is required by launchd, but it is not an end-user command. watch is diagnostic/development-oriented.
Recommended fix:
Keep both commands for compatibility, but split CLI help into:
- User commands
- Maintenance commands
- Developer/internal commands
run-service should not appear in primary usage text.
The Menu Bar currently checks CLI availability and status, but setup failures can come from many layers:
remodexmissing- Node missing
- npm unavailable
- relay missing
- launchd missing/stale
- state directory unavailable
- stale pid/status files
- pairing file absent/expired
- logs missing
Recommended fix:
Add remodex doctor --json.
Suggested checks:
- CLI path
- Node path
- npm path
- package version
- latest known version
- relay config source
- launchd plist path
- launchd loaded/pid
- bridge status file
- pairing session status
- stdout/stderr log paths
- last error
The Menu Bar can then show a compact diagnostic section without duplicating shell logic.
The parser currently recognizes --json and otherwise treats tokens as positionals. Unknown flags do not produce structured guidance.
Recommended fix:
Keep the dependency-free parser, but make it explicit:
--help- unknown flag error
- command-specific allowed flags
- JSON error format when
--jsonis passed
The Menu Bar has a fallback parser for older human-readable status output. That is useful for compatibility, but should not become a long-term contract.
Recommended fix:
Keep fallback only behind a legacy compatibility path and remove it once the minimum supported bridge guarantees status --json.
remodex upremodex pairremodex statusremodex stopremodex resume
remodex status --jsonremodex start --jsonremodex restart --jsonremodex pair --jsonremodex stop --jsonremodex reset-pairing --jsonremodex update --jsonremodex doctor --jsonremodex logs --json
remodex runremodex run-serviceremodex watch [threadId]
Use only bordered sections and controls, matching the latest UI direction:
-
Status
- Daemon
- Connection
- PID
- Relay
- Installed/latest version
-
Actions
- Start
- Restart
- Stop
-
Pairing
- Pair QR
- Reset Pair
- QR preview
-
Maintenance
- Update
- Doctor
- Logs
-
Utility
- Resume Last Thread
- Refresh
Avoid exposing run, run-service, and watch in the Menu Bar.
- Add
update --json. - Add
doctor --json. - Add
logs --json. - Add
capabilitiestostatus --json. - Add tests for each JSON contract.
- Replace direct
npm install -g remodex@latestwithremodex update --json. - Replace direct
npm view remodex version --jsonwithstatus --jsonlatest-version fields. - Use
capabilitiesto enable/disable buttons. - Keep legacy fallback parser only for old bridge versions.
- Add
help. - Hide
run-servicefrom primary usage. - Mark
qras alias ofpair. - Separate user, maintenance, and developer/internal commands.
The repository already includes these local changes:
pair --json/qr --jsonsupport in the CLI.- Menu Bar actions for
RestartandPair QR. - Border-only Menu Bar presentation with smaller 8px radii.
- CLI test coverage for
pair --json.
Bridge test status:
npm testinphodex-bridgepasses.- 369 tests passing.
Xcode test status:
- Xcode tests were not run, respecting the repository guardrail.
Package.resolvedis modified in the worktree and should be reviewed separately before committing.- Menu Bar build/run should be checked visually on macOS after the Swift package graph has settled.
- The current Menu Bar still performs npm update/version work directly; this should be removed once
update --jsonand latest-version status fields exist.