feat(gsd-cloud): add macOS cloud monitor app and runtime telemetry#1399
Merged
Conversation
…ll running in background before test verification
…nd new GSD Cloud Monitor app
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_aa34ba1b-c63e-4994-a71c-59a4ae1e9a19) |
Contributor
🟡 PR Risk Report — MEDIUM
Affected Systems
File Breakdown
|
Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_d0de0d6f-2440-4cf0-8722-364bed645e35) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Intent
Build and publish a native macOS menu-bar app that monitors the gsd-cloud agent's connection state and traffic, including per-project request, error, byte, active-tool, and recent activity views. Add safe start, stop, and reconnect controls that preserve pairing, multiple runtime configurations including configs sharing a directory, distinct telemetry availability semantics, notifications, failure-safe diagnostics export, launch at login, and explicit update-check states. Make it distributable as universal Intel and Apple Silicon ZIP and DMG artifacts with Developer ID signing, notarization, checksums, and a tag-triggered GitHub Release workflow. The local status contract must remain token-free and never expose pairing credentials or malformed URL secrets. Apple credentials are intentionally supplied only through GitHub Actions secrets and are not present in the repository.
What Changed
apps/gsd-cloud-monitor, a new SwiftUI menu-bar app that displays runtime connection state and per-project request/error/byte/tool/activity metrics, with start/stop/reconnect controls, launch-at-login, notifications, diagnostics export, and update-check UI, plus build/package scripts and a tag-triggered GitHub Actions release workflow producing signed/notarized universal ZIP and DMG artifacts.packages/gsd-cloud/src/runtime-telemetry.tsandruntime-artifacts.ts, and substantially reworkedcli.ts,cloud-runtime.ts, andruntime-process.tsto support safe start/stop/reconnect, multiple runtime configurations (including configs sharing a directory), start-lock recovery, and telemetry availability tracking that keeps the local status contract token-free.README.md,docs/README.md, andpackages/gsd-cloud/README.mdto document the new monitor app and CLI behavior, and expanded TypeScript and Swift test suites to cover the new runtime, telemetry, and monitor logic.Risk Assessment
✅ Low: All four round-1 findings were fixed correctly and narrowly: disconnect now unlinks only the canonical config's telemetry file (stop still preserves it), AgentCommandRunner reads stdout/stderr on separate pipes with a DispatchGroup barrier (correct, no race, no deadlock, verified by an existing 1MB-output test), the app now uses a single AppMonitor.shared RuntimeMonitorStore for both preview and production scenes, and refresh() prunes projectTraffic to only currently-reported project IDs on successful decode while leaving the catch-path's full reset untouched. Each fix has a targeted regression test (Swift stderr-noise/failure-diagnostics tests, TS clearRuntimeTelemetry test, end-to-end disconnect status test), and no unrelated behavior changed.
Testing
Ran the Swift package's own CoreTests and ReleaseTests (both pass — the latter actually produces and checksum-verifies a signed ZIP/DMG locally), built and launched the staged app bundle in --preview-window mode against the repo's synthetic multi-project telemetry fixture and confirmed it stays running without crashing, and ran the full gsd-cloud TypeScript test suite (94/94 passing) which directly exercises token-free status persistence, credential redaction, multi-runtime configs sharing a directory, and telemetry availability semantics. I could not produce a real screenshot of the rendered DashboardView:
screencapturefailed ("could not create image from display") because this non-interactive session has no Screen Recording TCC permission, and a fallback off-screen SwiftUI ImageRenderer render (built by compiling the app's own source files into a throwaway harness) consistently substituted a red/yellow "blocked content" glyph instead of actual view content, regardless of code-signing — indicating this sandboxed session lacks functional WindowServer/GUI rendering access rather than any defect in the app itself. No source or test files were modified; only throwaway files in /tmp and evidence images that turned out non-representative were created and removed.Evidence: GSDCloudMonitorReleaseTests output — local signed ZIP/DMG packaging + checksum verification
Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
🔧 **Review** - 4 issues found → auto-fixed ✅
packages/gsd-cloud/src/cli.ts:74-disconnectstops the runtime and clears cloud config/credentials viaclearCloudConfig, but never clears the runtime telemetry file (runtime-telemetry.tsexposes no clear/remove export at all). After a user disconnects,gsd-cloud status— and the macOS menu-bar app's local status contract that reads from it — keeps returning the last-known telemetry snapshot (runtime_id,runtime_name, sanitizedgateway_url, and up to 50recent_activityentries with real project paths and tool names) indefinitely alongsideconfigured: false. This isn't a credential leak, but it contradicts the intended 'safe disconnect' semantics and there's no test asserting telemetry is cleared on disconnect.apps/gsd-cloud-monitor/Sources/GSDCloudMonitorCore/AgentCommandRunner.swift:82-execute()routes both stdout and stderr through the samePipe(lines 82-83), butruntimeIsRunning()(lines 70-74) JSON-decodes the combined buffer expecting pure JSON on stdout from thestatussubcommand. Any incidental stderr output from the externalgsd-cloudCLI (Node deprecation/experimental warnings, a future log line) would corrupt the buffer, causingJSONDecoderto throw. The only caller,RuntimeMonitorStore.validateRuntimeStatus(), swallows this withtry?, turning a legitimate running/stopped answer intonil, which maps to.stale— silently defeating the fallback validation path that exists specifically for when telemetry is unavailable.apps/gsd-cloud-monitor/Sources/GSDCloudMonitor/App/GSDCloudMonitorApp.swift:42- When launched with--preview-window(the app's own documented dev workflow viascript/build_and_run.sh --preview),AppDelegatecreates its ownRuntimeMonitorStorefor the preview window (line 14), butGSDCloudMonitorApp.bodystill constructs the production@StateObject monitor = RuntimeMonitorStore()(line 42) because SwiftUI evaluates the Scene body regardless. This yields two live stores polling telemetry every second, each capable of firing real desktop notifications and hitting the real update-check endpoint — confined to dev-preview tooling, not production launches.apps/gsd-cloud-monitor/Sources/GSDCloudMonitor/Stores/RuntimeMonitorStore.swift:117-refresh()adds/updatesprojectTraffic[project.id]for every project currently reported by telemetry but never removes entries for project ids that stop appearing (onlyresetSamples(), triggered on config switch, clears the dictionary wholesale). A long-running monitor watching an agent that cycles through many ephemeral project directories over days/weeks accumulates aTrafficSeriesentry per distinct id ever seen, for the life of the process. Each entry is bounded (60 samples), so impact is low, but it's unbounded in aggregate.🔧 Fix: Applying fixes for 4 review findings; pnpm install running in background before test verification
✅ Re-checked - no issues remain.
screencapturefailed with "could not create image from display" — this non-interactive test session has no Screen Recording TCC permission and I did not attempt to grant it since that would mean modifying system security state; (2) an off-screen SwiftUIImageRendererharness (compiled from the app's own unmodified source against the fixture telemetry) built and ran successfully but consistently rendered a red/yellow "blocked content" placeholder glyph instead of the actual dashboard content, with or without ad-hoc code signing — indicating this sandboxed session lacks functional WindowServer/GUI rendering access. The app itself builds, launches, and stays alive (verified via process check) against the repo's synthetic connected-telemetry fixture, and all automated Swift and TypeScript tests pass, but no reviewer-visible visual evidence of the actual rendered UI (per-project request/error/byte/tool views, connection states, etc.) could be captured in this environment. A human should verify the dashboard visually on a normal desktop session (e.g../script/build_and_run.sh --preview) before relying solely on this report for the UI-facing portions of the change.cd apps/gsd-cloud-monitor && swift run GSDCloudMonitorCoreTestscd apps/gsd-cloud-monitor && swift run GSDCloudMonitorReleaseTests (builds app, ad-hoc signs, packages ZIP+DMG, verifies checksums)cd apps/gsd-cloud-monitor && ./script/build_and_run.sh stage && open -n dist/GSDCloudMonitor.app --args --preview-window --telemetry-path Fixtures/connected-telemetry.json (manual launch check via pgrep -x GSDCloudMonitor)cd packages/gsd-cloud && pnpm run test (94 node --test cases across cloud-runtime, runtime-process, runtime-telemetry, background-cli, device-flow, cloud-config, cloud-gateway-lookup, inject-gateway, executors)✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.
Note
Medium Risk
Large new surface (native app controlling the cloud agent via CLI, plus signed release automation), but pairing secrets stay out of telemetry and tests cover disconnect telemetry clearing, status decoding, and packaging guards.
Overview
Introduces
apps/gsd-cloud-monitor, a macOS 14+ menu-bar and dashboard app that polls the agent’s token-freecloud-runtime-status.json(no device token), shows connection/traffic and per-project metrics, and exposes Start / Stop / Reconnect, diagnostics export, notifications, multi-runtime settings, and GitHub release update checks. Packaging scripts produce universal ZIP/DMG artifacts;gsd-cloud-monitor-v*tags trigger a GitHub Actions workflow for tests, Developer ID signing, notarization, and release upload.@opengsd/gsd-cloudgainsruntime-telemetryandruntime-artifacts(hashed paths when multiple configs share a directory), astopcommand that keeps pairing,statustelemetry anddisconnectclearing the telemetry snapshot, start-lock coordination for foreground vs background connect, andCloudRuntimehooks for connection lifecycle, byte/message counters, per-project tool activity, and flushed error state on startup failures.Repo docs now list
apps/and link the monitor from user docs and the gsd-cloud README.Reviewed by Cursor Bugbot for commit c5aadbc. Bugbot is set up for automated code reviews on this repo. Configure here.
Need help on this PR? Tag
/codesmithwith what you need. Autofix is enabled.