Skip to content

fix(desktop): scope cron job calls by profile - #47429

Closed
necoweb3 wants to merge 1 commit into
NousResearch:mainfrom
necoweb3:fix/desktop-cron-profile-scope
Closed

fix(desktop): scope cron job calls by profile#47429
necoweb3 wants to merge 1 commit into
NousResearch:mainfrom
necoweb3:fix/desktop-cron-profile-scope

Conversation

@necoweb3

Copy link
Copy Markdown
Contributor

Summary

This scopes Desktop cron job REST helpers to the active API profile.

Why

The backend cron endpoints are profile-aware, but the Desktop helpers did not pass the active API profile. In a multi-profile Desktop session, the Cron page could show or mutate jobs against the default/launch profile instead of the selected profile.

The most visible case is creating or editing a cron job while another profile is active: the UI appears to operate on that profile, but the request can land in the default profile's cron store.

Changes

  • Add profileScoped() to cron job list/detail/run-history helpers.
  • Add profileScoped() to create/update/pause/resume/trigger/delete helpers.
  • Add regression coverage proving all cron helper calls include the active API profile.

Tests

npm --workspace apps/desktop run test:ui -- src/hermes.test.ts
1 passed, 4 tests

@alt-glitch alt-glitch added type/bug Something isn't working comp/cron Cron scheduler and job management P3 Low — cosmetic, nice to have labels Jun 16, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Related: #42654 (also scopes Desktop cron calls to the active profile). Same goal, different mechanism — #42654 threads an explicit profile arg through the call sites (cron/index.tsx, desktop-controller.tsx) for list+create driven by $profileScope, while this PR injects a profileScoped() helper spread inside the hermes.ts cron helpers themselves and covers the full surface (list/detail/run-history/create/update/pause/resume/trigger/delete). Worth consolidating; maintainer picks the approach.

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for covering the full cron helper surface.

Problems

  • profileScoped() routes Electron to a backend, but local and per-profile-remote paths retain the original URL (apps/desktop/electron/connection-config.ts:199-233). The cron API defaults list requests to all and creates to default (hermes_cli/web_server.py:10268-10270, 10376-10378), so the change does not establish the requested profile selection for those paths.
  • The added test currently fails Desktop type-checking: CI reports TS2353 for { paused: true } in apps/desktop/src/hermes.test.ts:84; CronJobUpdates exposes enabled, not paused (apps/desktop/src/types/hermes.ts:580-586).

Suggested changes

  • Keep backend routing, but add an endpoint-profile mechanism that handles local pools while preserving global/per-profile remote behavior; test those three routing shapes.
  • Use a valid update field and adapt the test to current getCronJobs() request shape.

Automated hermes-sweeper review.

@@ -523,18 +523,21 @@ export function testMessagingPlatform(platformId: string): Promise<MessagingPlat

export function getCronJobs(): Promise<CronJob[]> {
return window.hermesDesktop.api<CronJob[]>({

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

request.profile selects an Electron backend but does not set the cron endpoint's profile argument on local/per-profile-remote paths. Those paths retain this URL, whose list endpoint defaults to all and whose create endpoint defaults to default; scope the endpoint contract as well.

Comment thread apps/desktop/src/hermes.test.ts Outdated
await getCronJob('job 1')
await getCronJobRuns('job 1', 7)
await createCronJob({ name: 'Daily', prompt: 'say hi', schedule: '0 9 * * *' })
await updateCronJob('job 1', { paused: true })

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

CronJobUpdates has enabled?: boolean, not paused; the PR's Desktop TypeScript check fails with TS2353 here. Use a valid update field such as { enabled: false }.

@teknium1 teknium1 added sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 14, 2026
@necoweb3
necoweb3 force-pushed the fix/desktop-cron-profile-scope branch from 384d09b to d97bdb9 Compare July 14, 2026 17:56
@teknium1 teknium1 added the area/profiles Multi-profile isolation, HERMES_HOME scoping label Jul 19, 2026
@teknium1

Copy link
Copy Markdown
Contributor

Thanks @necoweb3 — you were the FIRST to submit the profileScoped() mechanism for the cron helpers (June 16, ahead of the June 21 and July submissions of the same fix). The identical approach landed on main via #67493, and a contract test covering all 9 helpers landed via #67602 — the sweep only surfaced your PR afterward, so belated but real credit: you had the right fix first. The sweeper-flagged local-pool gap (routing alone doesn't filter the list endpoint) is addressed in #67615. Closing as landed-on-main.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/profiles Multi-profile isolation, HERMES_HOME scoping comp/cron Cron scheduler and job management P3 Low — cosmetic, nice to have sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants