Skip to content

ADE-74: Fix platform budget and service hardening#497

Merged
arul28 merged 2 commits into
mainfrom
ade-74-platform-vm-deeplinks-budgetcap-per-run-miscount-dev-auto-update-noise-keychain-argv-cross-ref-and-platform-god-file-decomposition
Jun 1, 2026
Merged

ADE-74: Fix platform budget and service hardening#497
arul28 merged 2 commits into
mainfrom
ade-74-platform-vm-deeplinks-budgetcap-per-run-miscount-dev-auto-update-noise-keychain-argv-cross-ref-and-platform-god-file-decomposition

Conversation

@arul28
Copy link
Copy Markdown
Owner

@arul28 arul28 commented May 31, 2026

Refs ADE-74

Summary

  • Fix usd-per-run budget caps to count usage for the active automation run instead of all historical rule usage
  • Disable scheduled updater checks in dev/unpackaged Electron sessions
  • Split platform god-file helpers into focused modules for app control launch commands, browser navigation/permissions, macOS VM stores, onboarding suggestions, image dimensions, and local usage ledgers
  • Refresh docs for the new service boundaries and budget semantics

Validation

  • npm --prefix apps/desktop run typecheck
  • npm --prefix apps/desktop run lint
  • npm --prefix apps/desktop run build
  • npm --prefix apps/ade-cli run typecheck
  • npm --prefix apps/ade-cli run build
  • npm --prefix apps/web run typecheck
  • npm --prefix apps/web run build
  • npx vitest run affected desktop service tests
  • desktop vitest shards 1/8 through 8/8, with shard 7 rerun after session loss
  • npx vitest run src/tuiClient/tests/TerminalPane.test.tsx src/stdioRpcDaemon.test.ts
  • node scripts/validate-docs.mjs

Windows release/build jobs intentionally skipped per request.

Linked Linear issues

ADE   Open in ADE  ·  ade-74-platform-vm-deeplinks-budgetcap-per-run-miscount-dev-auto-update-noise-keychain-argv-cross-ref-and-platform-god-file-decomposition branch  ·  PR #497

Summary by CodeRabbit

  • New Features

    • Added browser URL validation and normalization for the built-in browser
    • Implemented Google Auth permission management for enhanced browser security
    • Extended budget cap checking with run-scoped context for improved cost tracking
    • Added macOS VM state persistence for managing virtual machine configuration
    • Introduced suggested project configuration generation for faster onboarding
    • Implemented comprehensive usage ledger scanning across multiple AI coding tools
  • Bug Fixes

    • Budget cap failures now properly update run status and emit events
    • Auto-update checks respect packaging configuration
  • Tests

    • Added coverage for browser URL handling, permissions, app control commands, and macOS VM storage

Greptile Summary

This PR fixes the usd-per-run budget cap to scope cost lookups against the active run ID rather than historical rule-level usage, disables scheduled auto-update polling in unpackaged/dev Electron sessions, and splits a large platform "god-file" into focused modules (browser navigation/permissions, macOS VM stores, onboarding suggested config, image dimensions, and local usage ledgers).

  • Budget cap fix: evaluateCap now uses context.runScopeId (the active run's DB ID) as the lookup key for usd-per-run, so accumulated cost is isolated per run; a missing runScopeId logs a warning and returns allowed: true rather than silently applying zero-cost logic.
  • Auto-update hardening: autoCheckEnabled: app.isPackaged prevents setTimeout/setInterval update timers from firing in dev/unpackaged sessions, eliminating noisy update-check noise during development.
  • Module decomposition: ~1,400 lines of ledger scanning code extracted from usageTrackingService.ts into ledgers/localUsageLedgers.ts; browser URL normalisation/permission helpers and macOS VM store helpers each moved into their own testable modules with new test coverage.

Confidence Score: 5/5

Safe to merge — the budget-cap fix is well-scoped, the refactoring is mechanical, and new test coverage validates the corrected per-run semantics.

The usd-per-run cost-lookup fix is targeted and the changed code path is covered by updated and new unit tests. The god-file splits are copy/paste extractions with no logic changes. The auto-update guard is a single boolean flag driven by app.isPackaged, a reliable Electron API. No correctness issues were found in the changed paths.

No files require special attention.

Important Files Changed

Filename Overview
apps/desktop/src/main/services/usage/budgetCapService.ts Core fix: usd-per-run cap now queries by runScopeId instead of scopeId; missing runScopeId safely returns allowed + emits a warning log.
apps/desktop/src/main/services/automations/automationService.ts Budget pre-check moved after insertRun so failed checks can update run status to failed and emit an event before throwing.
apps/desktop/src/main/services/updates/autoUpdateService.ts New autoCheckEnabled flag gates the startup and periodic update timers; dispose() guards added to avoid calling clearTimeout/clearInterval on null.
apps/desktop/src/main/services/builtInBrowser/builtInBrowserNavigation.ts Extracted from builtInBrowserService; hasScheme detection tightened to require :// (or about:), blocking schemes like data: more predictably.
apps/desktop/src/main/services/macosVm/macosVmStores.ts New module for VM state persistence; VNC credential store uses 0o600 file mode with atomic tmp-rename writes; generateVncPassword produces 8 base64url chars from 6 random bytes.
apps/desktop/src/main/services/onboarding/onboardingSuggestedConfig.ts Extracted from onboardingService; CI command tokenisation improved from naive split on whitespace to a proper shell-quote-aware splitShellCommand; YAML type assertion tightened from any to a concrete interface.
apps/desktop/src/main/services/usage/ledgers/localUsageLedgers.ts ~1,400 lines of ledger scanning extracted from usageTrackingService; logic identical to removed code; size limits and fallback guards unchanged.
apps/desktop/src/main/services/usage/budgetCapService.test.ts Tests updated to reflect per-run semantics; new test verifies historical rule-level usage does not block a fresh usd-per-run check; scoped-cap isolation test correctly relies on cap.scopeId filter before runScopeId lookup.

Sequence Diagram

sequenceDiagram
    participant AS as automationService
    participant DB as RunsDB
    participant BCS as budgetCapService
    participant EV as EventEmitter

    AS->>DB: insertRun(rule, trigger) → run.id
    AS->>BCS: "checkBudget(scope, rule.id, provider, {runScopeId: run.id})"
    BCS->>DB: getCumulativeUsage(scope, run.id, provider, weekKey)
    DB-->>BCS: accumulated cost for this run
    alt budget exceeded
        BCS-->>AS: "{allowed: false, reason}"
        AS->>DB: "updateRun(run.id, {status: failed})"
        AS->>EV: emit runs-updated
        AS-->>AS: throw Error(reason)
    else budget ok
        BCS-->>AS: "{allowed: true}"
        AS->>AS: continue run execution
    end
Loading

Reviews (6): Last reviewed commit: "Address ADE-74 review feedback" | Re-trigger Greptile

@linear-code
Copy link
Copy Markdown

linear-code Bot commented May 31, 2026

ADE-74

@vercel
Copy link
Copy Markdown

vercel Bot commented May 31, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
ade Ignored Ignored Preview Jun 1, 2026 1:17am

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 31, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

This PR refactors the desktop app by extracting scattered helper logic into modular, reusable components. It modularizes image dimension parsing, browser URL handling, app control command rewriting, VM persistence, and usage ledger scanning, while adding per-run budget cap scoping and conditional auto-update scheduling based on package state.

Changes

Service modularization and helper extraction

Layer / File(s) Summary
Shared utility modules and imports
apps/desktop/src/main/services/shared/imageDimensions.ts, apps/desktop/src/main/services/shared/imageDimensions.test.ts, apps/desktop/src/main/services/appControl/appControlService.ts, apps/desktop/src/main/services/ios/iosSimulatorService.ts, apps/desktop/src/main/services/usage/usagePricing.ts, apps/desktop/src/main/services/macosVm/macosVmService.ts
New imageDimensions module provides PNG/JPEG dimension extraction via pngDimensions(), jpegDimensions(), and dispatcher imageDimensions(). Services now import pngDimensions and isRecord from shared modules instead of defining local versions; dimensions are parsed from fixed byte offsets for PNG and scanned JPEG markers.
Browser navigation and permissions
apps/desktop/src/main/services/builtInBrowser/builtInBrowserNavigation.ts, apps/desktop/src/main/services/builtInBrowser/builtInBrowserNavigation.test.ts, apps/desktop/src/main/services/builtInBrowser/builtInBrowserPermissions.ts, apps/desktop/src/main/services/builtInBrowser/builtInBrowserPermissions.test.ts, apps/desktop/src/main/services/builtInBrowser/builtInBrowserService.ts
normalizeBrowserUrl() and isAllowedNavigationUrl() extracted to dedicated navigation module with scheme inference (defaulting to https:// except for localhost), validation of about:blank restriction, and protocol allowlisting. shouldAllowGoogleAuthPermissionCheck() and shouldAllowGoogleAuthPermissionRequest() implement Google Accounts surface validation in permissions module; builtInBrowserService now delegates to these modules.
App control launch command parsing
apps/desktop/src/main/services/appControl/appControlLaunchCommand.ts, apps/desktop/src/main/services/appControl/appControlLaunchCommand.test.ts, apps/desktop/src/main/services/appControl/appControlService.ts
New module provides shellQuote(), commandForwardsAppControlDebug(), insertDebugFlagsIntoDirectElectronCommand(), and rewritePackageScriptElectronLaunch() for parsing/rewriting Electron invocations with debug flag injection and PATH expansion via package.json-aware script rewriting. Detects direct vs package-script command shapes and rejects scripts already forwarding debug settings.
macOS VM persistence and credentials
apps/desktop/src/main/services/macosVm/macosVmStores.ts, apps/desktop/src/main/services/macosVm/macosVmStores.test.ts, apps/desktop/src/main/services/macosVm/macosVmService.ts
New macosVmStores module provides versioned JSON persistence for VM records, global lease state, and VNC credentials with atomic file writes (temp+rename), safe JSON parsing with fallbacks, and secure mode-restricted credential storage (chmod 0o600). Exports readStoreFile(), writeStoreFile(), readGlobalLeaseFile(), writeGlobalLeaseFile(), readVncCredentialStore(), writeVncCredentialStore(), vncCredentialKey(), and generateVncPassword(); macosVmService now imports these helpers.
Onboarding suggested config generation
apps/desktop/src/main/services/onboarding/onboardingSuggestedConfig.ts, apps/desktop/src/main/services/onboarding/onboardingService.ts
Extracts buildSuggestedConfig() and parseGithubWorkflowRuns() to dedicated module; buildSuggestedConfig() assembles ProjectConfigFile from detected indicators and workflow commands, deriving up to six CI tests and appending provider generators/conflict resolvers. parseGithubWorkflowRuns() reads and YAML-parses GitHub Actions workflows to extract run commands.
Local usage ledgers with per-provider scanners
apps/desktop/src/main/services/usage/ledgers/localUsageLedgers.ts, apps/desktop/src/main/services/usage/usageTrackingService.ts
New localUsageLedgers module implements per-provider token/cost scanning (Claude JSONL discovery via discoverClaudeProjectDirs()/scanClaudeLogs(), Codex session parsing, Cursor SQLite KV reads, OpenCode DB queries, Gemini JSON sessions, Copilot transcript discovery, Droid settings-based splitting, OpenClaw agent events). Exports TokenEntry type, per-provider scanners, and filesystem discovery (findRecentFiles(), findJsonlFiles()). usageTrackingService now imports these scanners and removed 1397 lines of inlined scanning logic.
Budget cap per-run scoping
apps/desktop/src/main/services/usage/budgetCapService.ts, apps/desktop/src/main/services/usage/budgetCapService.test.ts, apps/desktop/src/main/services/automations/automationService.ts, apps/desktop/src/main/services/automations/automationService.test.ts
Introduces BudgetCheckContext type with optional runScopeId field; checkBudget() now accepts context parameter passed to evaluateCap(). For usd-per-run caps, evaluation uses context.runScopeId (when provided) instead of cap's scopeId for usage lookup, enabling per-run budget enforcement. dispatchAgentSessionRun() now passes { runScopeId: run.id } and explicitly updates run state (ended_at, status, error_message) and emits "runs-updated" event when budget blocks the run.
Auto-update conditional scheduling
apps/desktop/src/main/services/updates/autoUpdateService.ts, apps/desktop/src/main/services/updates/autoUpdateService.test.ts, apps/desktop/src/main/main.ts
createAutoUpdateService() now supports optional autoCheckEnabled flag (defaults to true) controlling whether startup and periodic update-check timers are created. dispose() conditionally clears timers only when set. main.ts now passes autoCheckEnabled: app.isPackaged to skip update checks in development builds.
Workspace configuration
apps/desktop/pnpm-workspace.yaml
Added opencode-ai entry (commented) to allowBuilds configuration.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related issues

  • arul28/ADE#463: Main changes directly address usd-per-run budget scoping via runScopeId, conditional auto-update checks, and centralized helper extraction (imageDimensions, appControl launch commands, browser navigation/permissions, macOS VM persistence, and usage ledgers).

Possibly related PRs

  • arul28/ADE#276: Both PRs refactor usageTrackingService to use dedicated ledger modules—this PR extracts local cost scanning into localUsageLedgers while the related PR extends Cursor integration with Admin API polling and provider-based pacing.

Suggested labels

desktop

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 2.61% 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
Title check ✅ Passed The title clearly identifies a specific issue (ADE-74) and summarizes the main changes: fixing platform budget and service hardening, which aligns with the PR objectives.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ade-74-platform-vm-deeplinks-budgetcap-per-run-miscount-dev-auto-update-noise-keychain-argv-cross-ref-and-platform-god-file-decomposition

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@capy-ai
Copy link
Copy Markdown

capy-ai Bot commented May 31, 2026

Capy auto-review is paused for this organization because the monthly auto-review limit has been reached. Increase the limit or turn it off in billing settings to resume automatic reviews.

@arul28
Copy link
Copy Markdown
Owner Author

arul28 commented May 31, 2026

@copilot review but do not make fixes

Copy link
Copy Markdown
Contributor

Copilot AI commented Jun 1, 2026

@copilot review but do not make fixes

Reviewed the latest commit and didn’t find any significant bugs, security issues, or logic regressions to fix.

Copilot finished work on behalf of arul28 June 1, 2026 00:05
Copy link
Copy Markdown

@capy-ai capy-ai Bot left a comment

Choose a reason for hiding this comment

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

Added 1 comment

Comment thread apps/desktop/pnpm-workspace.yaml Outdated
Comment thread apps/desktop/pnpm-workspace.yaml Outdated
Comment thread apps/desktop/src/main/services/usage/budgetCapService.ts Outdated
Comment thread apps/desktop/src/main/services/automations/automationService.ts
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 9

🧹 Nitpick comments (4)
apps/desktop/src/main/services/onboarding/onboardingSuggestedConfig.ts (1)

121-131: 💤 Low value

Naive whitespace split can mangle quoted/-- CI commands.

cmd.split(/\s+/) will fragment arguments like npm test -- --grep "a b", producing a semantically incorrect command array. Since these are user-reviewed suggestions the impact is limited, but a quote-aware tokenizer (or keeping the matched commands shell-form and letting the runner parse them) would yield more accurate suggestions.

🤖 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 `@apps/desktop/src/main/services/onboarding/onboardingSuggestedConfig.ts`
around lines 121 - 131, The code in onboardingSuggestedConfig.ts builds
ciCandidates and calls addTest(id, `CI: ${cmd}`, cmd.split(/\s+/), ".",
["custom"]) which incorrectly splits quoted or `--` arguments (e.g., npm test --
--grep "a b"); change the third argument so it is produced by a quote-aware
tokenizer or keep the command as a single shell string for the runner to parse:
replace cmd.split(/\s+/) with a proper shell-words parse (or pass cmd unchanged)
when calling addTest, updating tests and imports as needed to use the chosen
tokenizer and preserving the id (`ci-${idx + 1}`), addTest, and ciCandidates
flow.
apps/desktop/src/main/services/automations/automationService.test.ts (1)

1101-1163: ⚡ Quick win

Consider verifying checkBudget call signature for consistency.

The test at line 1391 now verifies that checkBudget is called with the new runScopeId parameter (lines 1454-1456). For consistency and better test coverage, this test should also verify the same signature to document the contract and ensure the parameter is threaded correctly in both code paths.

📋 Suggested addition

Add this assertion after line 1158:

  await expect(service.triggerManually({ id: "agent-budget" })).rejects.toThrow("Budget exceeded");
+ expect(budgetCapService.checkBudget).toHaveBeenCalledWith(
+   "automation-rule",
+   "agent-budget",
+   expect.any(String),
+   { runScopeId: expect.any(String) }
+ );
  expect(createSession).not.toHaveBeenCalled();
🤖 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 `@apps/desktop/src/main/services/automations/automationService.test.ts` around
lines 1101 - 1163, The test omits asserting the checkBudget call signature;
after creating the service via createAutomationService and invoking
service.triggerManually({ id: "agent-budget" }), add an assertion that
budgetCapService.checkBudget was called with the expected run scope argument
(e.g. include a check that budgetCapService.checkBudget was calledWith an object
containing runScopeId matching the new run id or scope used by triggerManually).
Locate the mock on budgetCapService (budgetCapService: { checkBudget: vi.fn(...)
}) and add the expectation alongside the existing createSession assertion so the
test verifies the new runScopeId parameter is threaded through triggerManually →
checkBudget.
apps/desktop/src/main/services/appControl/appControlLaunchCommand.ts (2)

54-54: 💤 Low value

Consider documenting the complex regex.

The regex on line 54 is quite complex with multiple named groups. Adding a comment explaining the pattern structure would improve maintainability.

📝 Example documentation
+// Matches: [cd ... &&] [ENV=val ...] <manager> [run] <script>
+// Groups: prefix (cd commands), env (environment vars), manager (npm/pnpm/yarn/bun), script (script name)
 const match = command.trim().match(/^(?<prefix>.*?)(?<env>(?:[A-Za-z_][A-Za-z0-9_]*=(?:"[^"]*"|'[^']*'|[^\s;&|]+)\s+)*)(?<manager>npm|pnpm|yarn|bun)\s+(?:run\s+)?(?<script>[A-Za-z0-9:_./-]+)\s*$/);
🤖 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 `@apps/desktop/src/main/services/appControl/appControlLaunchCommand.ts` at line
54, Add a concise explanatory comment above the complex regex used to parse
launch commands (the pattern assigned to the "match" variable in
appControlLaunchCommand.ts) that describes its purpose, the named capture groups
(prefix, env, manager, script), what each group matches (e.g., prefix = leading
text, env = zero-or-more env VAR=VALUE pairs with quoted/unquoted support,
manager = package manager names npm|pnpm|yarn|bun, script = script name allowing
characters A-Za-z0-9:_./-), and a couple of example input strings and expected
captures; place the comment immediately above the regex so future readers can
quickly understand/maintain it.

79-81: 💤 Low value

Consider logging parse failures for debugging.

The catch block silently returns null on any error (file read, JSON parse, etc.). While the fallback behavior is correct, logging parse failures would help diagnose issues when rewriting unexpectedly fails.

🤖 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 `@apps/desktop/src/main/services/appControl/appControlLaunchCommand.ts` around
lines 79 - 81, The catch block in
apps/desktop/src/main/services/appControl/appControlLaunchCommand.ts currently
swallows all errors and returns null; update that catch to capture the error
(e.g., catch (err)) and log the failure before returning null so parse/read
failures are visible for debugging — use the module's existing logger (or
console.error if no logger is available) and include context like "failed to
parse launch command" plus the error and any relevant input (refer to the
try/catch in appControlLaunchCommand where the parse/read happens).
🤖 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/desktop/pnpm-workspace.yaml`:
- Line 7: Replace the placeholder string values with boolean literals: set
allowBuilds.opencode-ai to either true or false (not the text "set this to true
or false") in the desktop workspace, and in the ade-cli workspace set
allowBuilds entries for esbuild, node-pty, opencode-ai, and sqlite3 to explicit
true or false booleans; update the YAML keys named allowBuilds.opencode-ai,
allowBuilds.esbuild, allowBuilds.node-pty and allowBuilds.sqlite3 accordingly so
they are valid booleans before merging.

In `@apps/desktop/src/main/services/builtInBrowser/builtInBrowserNavigation.ts`:
- Around line 5-13: The code treats inputs like "example.com:3000" as having a
scheme because hasScheme uses /^[a-zA-Z][a-zA-Z\d+.-]*:/. Fix this by only
recognizing true URI schemes (those followed by "//") so host:port is treated as
scheme-less: change the hasScheme test to require :// (e.g.
/^[a-zA-Z][a-zA-Z\d+.-]*:\/\//) and keep the existing localhostLike and
candidate logic so that inputs without a true scheme (including host:port) get
prefixed with "https://" before calling new URL().

In `@apps/desktop/src/main/services/macosVm/macosVmStores.test.ts`:
- Around line 59-80: Add assertions to the "round-trips VNC credentials under
stable keys" test to verify malformed entries are filtered by
readVncCredentialStore: after the existing happy-path write/read, overwrite the
store file with a JSON object that contains both a malformed credential (missing
required fields or wrong types) and a valid credential keyed by
vncCredentialKey("lane-2","vm-2"); then call readVncCredentialStore and assert
the malformed key is undefined and the valid key returns the expected password.
This ensures readVncCredentialStore validation logic correctly removes invalid
entries.
- Around line 17-81: Add unit test coverage for generateVncPassword in the
macosVmStores.test.ts suite: create a new it block (e.g., "generates 8-character
base64url passwords") that calls generateVncPassword(), asserts the returned
string has length 8, and asserts it matches the base64url-safe character class
/^[A-Za-z0-9_-]+$/. Place the test alongside the existing cases (near other
VNC-related tests) and import or reference generateVncPassword and any necessary
test helpers so the test runs in CI.

In `@apps/desktop/src/main/services/macosVm/macosVmStores.ts`:
- Around line 89-99: readVncCredentialStore currently unsafely casts
parsed.credentials; instead validate that parsed.credentials is a record and
that each entry has the expected shape (e.g., an object with required fields
like id and other credential properties of the correct types) before casting.
Update readVncCredentialStore to use isRecord(parsed.credentials) and then
iterate Object.entries(parsed.credentials), filter or map only entries where the
value passes a shape-check (e.g., typeof value === "object" && typeof value.id
=== "string"), and build the returned credentials object from those validated
entries; keep the same return signature and fallback to an empty credentials
object on parse/validation failure. Ensure you reference readVncCredentialStore
and reuse the existing isRecord helper or the same validation logic used by
readStoreFile for consistency.
- Around line 113-115: The vncCredentialKey function currently builds keys as
`${laneId}:${vmName}` which can collide if inputs contain colons; update
vncCredentialKey to produce an unambiguous key (for example by returning a
JSON-stringified array of [laneId, vmName] or by URL-safe encoding/escaping both
laneId and vmName and joining with a delimiter) so that inputs containing ":"
cannot create identical keys — locate the vncCredentialKey function and replace
the string interpolation with a collision-free encoding approach.

In `@apps/desktop/src/main/services/shared/imageDimensions.ts`:
- Around line 6-13: pngDimensions currently only checks bytes 1–3 for "PNG" and
can accept malformed buffers; update pngDimensions to validate the full 8‑byte
PNG signature (\x89 P N G \r \n \x1a \n) before reading dimensions, i.e., ensure
buffer.length is at least 24 and then compare buffer[0..7] against the exact
signature (or Buffer.from([0x89,0x50,0x4E,0x47,0x0D,0x0A,0x1A,0x0A])) and only
then call buffer.readUInt32BE(16) and readUInt32BE(20) to return width/height.

In `@apps/desktop/src/main/services/usage/budgetCapService.ts`:
- Around line 225-230: The IPC handler in registerIpc.ts is calling
ctx.budgetCapService.checkBudget(...) without the context object so
budgetCapService’s usd-per-run branch (which reads context.runScopeId) never
sees the run id; update the call site in registerIpc.ts (the call to
ctx.budgetCapService.checkBudget) to pass a context object containing the run
scope id (e.g. { runScopeId: arg.runScopeId } or the appropriate arg field) so
budgetCapService (which reads context.runScopeId) can evaluate usd-per-run caps
correctly, and adjust types/signature usage if needed to match
checkBudget(...)’s expected second/context parameter.

In `@apps/desktop/src/main/services/usage/ledgers/localUsageLedgers.ts`:
- Around line 812-854: discoverCopilotTranscriptFiles collects candidate files
then slices by LOCAL_COST_SCAN_MAX_FILES in traversal order, which can drop
newer files; change it to collect entries as objects with their stat.mtimeMs
(use the existing LOCAL_COST_SCAN_MAX_FILE_BYTES check before pushing), then
after all discovery sort the array by mtimeMs descending and slice to
LOCAL_COST_SCAN_MAX_FILES, finally return the sliced paths; apply the identical
change to the analogous discovery helpers referenced in the review (the other
discovery blocks at the ranges called out) so they also sort by stat.mtimeMs
before trimming.

---

Nitpick comments:
In `@apps/desktop/src/main/services/appControl/appControlLaunchCommand.ts`:
- Line 54: Add a concise explanatory comment above the complex regex used to
parse launch commands (the pattern assigned to the "match" variable in
appControlLaunchCommand.ts) that describes its purpose, the named capture groups
(prefix, env, manager, script), what each group matches (e.g., prefix = leading
text, env = zero-or-more env VAR=VALUE pairs with quoted/unquoted support,
manager = package manager names npm|pnpm|yarn|bun, script = script name allowing
characters A-Za-z0-9:_./-), and a couple of example input strings and expected
captures; place the comment immediately above the regex so future readers can
quickly understand/maintain it.
- Around line 79-81: The catch block in
apps/desktop/src/main/services/appControl/appControlLaunchCommand.ts currently
swallows all errors and returns null; update that catch to capture the error
(e.g., catch (err)) and log the failure before returning null so parse/read
failures are visible for debugging — use the module's existing logger (or
console.error if no logger is available) and include context like "failed to
parse launch command" plus the error and any relevant input (refer to the
try/catch in appControlLaunchCommand where the parse/read happens).

In `@apps/desktop/src/main/services/automations/automationService.test.ts`:
- Around line 1101-1163: The test omits asserting the checkBudget call
signature; after creating the service via createAutomationService and invoking
service.triggerManually({ id: "agent-budget" }), add an assertion that
budgetCapService.checkBudget was called with the expected run scope argument
(e.g. include a check that budgetCapService.checkBudget was calledWith an object
containing runScopeId matching the new run id or scope used by triggerManually).
Locate the mock on budgetCapService (budgetCapService: { checkBudget: vi.fn(...)
}) and add the expectation alongside the existing createSession assertion so the
test verifies the new runScopeId parameter is threaded through triggerManually →
checkBudget.

In `@apps/desktop/src/main/services/onboarding/onboardingSuggestedConfig.ts`:
- Around line 121-131: The code in onboardingSuggestedConfig.ts builds
ciCandidates and calls addTest(id, `CI: ${cmd}`, cmd.split(/\s+/), ".",
["custom"]) which incorrectly splits quoted or `--` arguments (e.g., npm test --
--grep "a b"); change the third argument so it is produced by a quote-aware
tokenizer or keep the command as a single shell string for the runner to parse:
replace cmd.split(/\s+/) with a proper shell-words parse (or pass cmd unchanged)
when calling addTest, updating tests and imports as needed to use the chosen
tokenizer and preserving the id (`ci-${idx + 1}`), addTest, and ciCandidates
flow.
🪄 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: CHILL

Plan: Pro

Run ID: 38e97b12-7d39-4f2b-95b9-69b0befffaf1

📥 Commits

Reviewing files that changed from the base of the PR and between 840acb7 and 7091de4.

⛔ Files ignored due to path filters (6)
  • docs/ARCHITECTURE.md is excluded by !docs/**
  • docs/features/automations/guardrails.md is excluded by !docs/**
  • docs/features/chat/README.md is excluded by !docs/**
  • docs/features/computer-use/README.md is excluded by !docs/**
  • docs/features/computer-use/app-control.md is excluded by !docs/**
  • docs/features/onboarding-and-settings/README.md is excluded by !docs/**
📒 Files selected for processing (27)
  • apps/desktop/pnpm-workspace.yaml
  • apps/desktop/src/main/main.ts
  • apps/desktop/src/main/services/appControl/appControlLaunchCommand.test.ts
  • apps/desktop/src/main/services/appControl/appControlLaunchCommand.ts
  • apps/desktop/src/main/services/appControl/appControlService.ts
  • apps/desktop/src/main/services/automations/automationService.test.ts
  • apps/desktop/src/main/services/automations/automationService.ts
  • apps/desktop/src/main/services/builtInBrowser/builtInBrowserNavigation.test.ts
  • apps/desktop/src/main/services/builtInBrowser/builtInBrowserNavigation.ts
  • apps/desktop/src/main/services/builtInBrowser/builtInBrowserPermissions.test.ts
  • apps/desktop/src/main/services/builtInBrowser/builtInBrowserPermissions.ts
  • apps/desktop/src/main/services/builtInBrowser/builtInBrowserService.ts
  • apps/desktop/src/main/services/ios/iosSimulatorService.ts
  • apps/desktop/src/main/services/macosVm/macosVmService.ts
  • apps/desktop/src/main/services/macosVm/macosVmStores.test.ts
  • apps/desktop/src/main/services/macosVm/macosVmStores.ts
  • apps/desktop/src/main/services/onboarding/onboardingService.ts
  • apps/desktop/src/main/services/onboarding/onboardingSuggestedConfig.ts
  • apps/desktop/src/main/services/shared/imageDimensions.test.ts
  • apps/desktop/src/main/services/shared/imageDimensions.ts
  • apps/desktop/src/main/services/updates/autoUpdateService.test.ts
  • apps/desktop/src/main/services/updates/autoUpdateService.ts
  • apps/desktop/src/main/services/usage/budgetCapService.test.ts
  • apps/desktop/src/main/services/usage/budgetCapService.ts
  • apps/desktop/src/main/services/usage/ledgers/localUsageLedgers.ts
  • apps/desktop/src/main/services/usage/usagePricing.ts
  • apps/desktop/src/main/services/usage/usageTrackingService.ts

Comment thread apps/desktop/pnpm-workspace.yaml Outdated
Comment thread apps/desktop/src/main/services/macosVm/macosVmStores.test.ts
Comment thread apps/desktop/src/main/services/macosVm/macosVmStores.test.ts
Comment thread apps/desktop/src/main/services/macosVm/macosVmStores.ts
Comment thread apps/desktop/src/main/services/macosVm/macosVmStores.ts
Comment thread apps/desktop/src/main/services/shared/imageDimensions.ts
Comment thread apps/desktop/src/main/services/usage/budgetCapService.ts Outdated
Comment thread apps/desktop/src/main/services/usage/ledgers/localUsageLedgers.ts
@arul28 arul28 force-pushed the ade-74-platform-vm-deeplinks-budgetcap-per-run-miscount-dev-auto-update-noise-keychain-argv-cross-ref-and-platform-god-file-decomposition branch 4 times, most recently from fd787d4 to 1bfc83a Compare June 1, 2026 01:07
@vercel
Copy link
Copy Markdown

vercel Bot commented Jun 1, 2026

Deployment failed with the following error:

Resource is limited - try again in 24 hours (more than 100, code: "api-deployments-free-per-day").

Learn More: https://vercel.com/arul28s-projects?upgradeToPro=build-rate-limit

@arul28 arul28 force-pushed the ade-74-platform-vm-deeplinks-budgetcap-per-run-miscount-dev-auto-update-noise-keychain-argv-cross-ref-and-platform-god-file-decomposition branch from 1bfc83a to 2235d25 Compare June 1, 2026 01:17
@arul28 arul28 merged commit 2dcfabc into main Jun 1, 2026
27 checks passed
@arul28 arul28 deleted the ade-74-platform-vm-deeplinks-budgetcap-per-run-miscount-dev-auto-update-noise-keychain-argv-cross-ref-and-platform-god-file-decomposition branch June 1, 2026 01:25
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.

2 participants