Omniscio documentation
Browse all documentation
  1. Getting Started13
  2. Sessions & Agents115
  3. Inbox & Notifications59
  4. Projects & Tasks95
  5. Automation & Scheduling75
  6. Knowledge & Memory26
  7. AI Features60
  8. Integrations100
  9. Plugins & Marketplace33
  10. Cloud & Teams56
  11. Settings & Customization58
  12. Account & Billing28
  13. Troubleshooting84
  14. CLI & API Reference22
  15. Legal & Policies4
  16. Uncategorised22

Rename a cron group header

How to override the label a group of cron jobs shows in the Cron Jobs view and its sidebar without renaming the project itself — the pencil on the group header, the 80-character limit, what the override does not touch, and how orphaned labels are cleaned up.

What it is

The Cron Jobs view groups jobs two ways — By Project (each group header shows the project's name) or By Frequency (each group header shows the cadence: hourly, daily, every-6-hours, etc.). In project mode, the group header label can feel wrong: a project called "Agent Orchestrator" shows up as a long sidebar header, you may want it to read "Orchestrator" or "Omniscio" inside the cron view without renaming the project everywhere else, and orphan UUIDs from soft-deleted projects sometimes briefly surface as group headers before the next prune sweep cleans them up.

Group rename lets you override the label that the cron view uses for any project group without touching the project's real name. The override is local to your install (lives in settings.cronGroupLabels), applies in both the Cron Jobs view (CronDashboard.tsx) and the Cron Jobs sidebar (CronJobsSidebar.tsx), and is automatically reset back to the canonical project name when you clear it. Frequency-mode headers are not renameable — those labels are derived from the cron expression itself and renaming hourly to "every hour" would just confuse the next reader.

Where to find it

The control lives in the Cron Jobs view — Omniscio's Cron Jobs virtual project in the sidebar — and in the smaller cron sidebar attached to a session that owns cron jobs. In both places the jobs are grouped either By Project or By Frequency, and the rename affordance appears only in the By Project grouping, as a small pencil at the right edge of a group header when you hover it.

How it behaves

How to use it

  1. Open the Cron Jobs view or sidebar. Either the Cron Jobs virtual project in the Omniscio sidebar, or the cron sidebar attached to a session that has cron jobs.
  2. Switch to By Project mode. The segmented By Project / By Frequency control at the top of either surface controls grouping. Rename only appears in By Project.
  3. Hover the group header. A small pencil icon fades in at the right edge of the row when you hover. The icon is also focus-revealed for keyboard users — Tab to the group header's row, then Tab again to the rename trigger.
  4. Click the pencil. The header label is replaced by an inline text input pre-filled with the current label (the project name or whatever you previously renamed it to). The input auto-focuses and selects the existing text, so just type to overwrite.
  5. Save with Enter (or click outside). Pressing Enter, or blurring the input by clicking elsewhere, commits the new label. Pressing Esc cancels without saving.
  6. Reset by saving an empty value. To go back to the canonical project name, open the rename input, clear it (or just press Enter on whitespace), and commit. The override is removed and the header reverts to project.name. Saving the same value as the live label also resets — there's no way to "save the current value as an override".

The label is clamped to 80 characters and trimmed before save. Anything longer is silently truncated. The "Unassigned" group (jobs whose project no longer exists) is also renameable using the same flow, in case you want to label your orphan jobs as "To triage" or similar.

What it doesn't do

  • Doesn't rename the project itself. Other Omniscio views — the sessions sidebar, project switcher, breadcrumbs, settings — all keep showing the real project.name. To rename the project everywhere, use the project's three-dot menu → Edit → Name.
  • Doesn't sync across machines. Overrides are per-install. If you use Omniscio on a desktop and a laptop, you'll need to rename groups on each.
  • Doesn't apply in By Frequency mode. Frequency labels (hourly, daily, weekly, etc.) are derived and never overrideable. The pencil icon is hidden in frequency mode by design.
  • Doesn't survive project deletion. When you delete a project (three-dot → Delete), Omniscio drops any cron group label override keyed by that project id as part of the cascade — so the override map stays in lockstep with the live project set. There's no "ghost label" left behind for an undelete to recover.

For agents

How it works

The override map

Overrides live in settings.cronGroupLabels, a Record<string, string> keyed by the group key (a project UUID, or the literal string 'Unassigned' for orphan jobs). The schema is registered in updateSettingsSchema (src/shared/ipc-schemas.ts) as z.record(z.string().min(1).max(64), z.string().min(1).max(80)).optional() — empty-string values are rejected at IPC boundary, so the renderer must drop the key (not write '') when resetting.

The resolver — single source of truth

Both the dashboard and the sidebar look up labels through the same resolver hook, useGroupLabelResolver(viewMode), in src/renderer/src/features/cron/cron-group-label.ts. The hook subscribes to the projects and settings.cronGroupLabels slices, then returns a (groupKey) => { label, renameable } closure that:

  • In frequency mode, returns { label: groupKey, renameable: false } — the cadence string is the label.
  • In project mode, looks up the override first, then falls back to the live project name, then to a UUID-shortened orphan label (abc12345…) if neither exists. Always returns renameable: true in project mode — even orphans are renameable so you can name an unfamiliar UUID before prune sweeps it away.

The Unassigned sentinel is a hardcoded literal 'Unassigned' shared between the renderer resolver and the cron-store producer (cron-store.ts:408) — drift between the two would silently break the rename round-trip.

The header component

The pencil affordance and inline input live in src/renderer/src/features/cron/CronJobGroupHeader.tsx. The component takes an optional onRename: (newLabel: string) => void prop — when omitted (frequency mode), the pencil and input are not rendered at all. When provided (project mode), the trigger button is hover/focus-revealed via a Tailwind group-hover:opacity-100 chain and e.stopPropagation() on its onClick prevents the toggle button from collapsing the group while you click the pencil.

The input itself stops propagation on onClick/onMouseDown so clicking inside it doesn't toggle the group either. Enter/Escape are handled inside the input's onKeyDown; the input also commits on onBlur, so clicking outside the row saves the same as pressing Enter.

handleCommit runs the trim → slice-to-80 → "is this a reset?" check before calling onRename. The reset condition fires when the trimmed value is empty or equal to the trimmed live label — both cases call onRename('') so the wiring layer can delete the override key. Non-reset values pass through verbatim.

The wiring layer

CronDashboard.tsx and CronJobsSidebar.tsx each define their own handleRenameGroup(groupKey, newLabel) callback. Both follow the same shape:

  1. Read the current settings.cronGroupLabels from the settings store (default {}).
  2. If newLabel === '', delete the key from a copy of the map (skip the IPC entirely if the key wasn't present — idempotent no-op).
  3. Otherwise, set the key to the new label (skip the IPC if the value didn't change — idempotent no-op).
  4. Call useSettingsStore.getState().updateSetting('cronGroupLabels', updated) — optimistic patch, rolls back on IPC error.

The two callbacks are intentionally duplicated rather than extracted into a shared helper. The shape is small enough (~10 lines), and centralizing it in cron-group-label.ts would create a renderer→store cycle in the resolver module that the linter would complain about.

Orphan key garbage collection

Two seams reap orphan keys (project UUIDs in the map that no longer correspond to a live project), both calling pruneOrphanCronGroupLabels():

  1. Startup hook in src/main/index.ts, inside app.whenReady() after the AHK clear-stale block — runs once per launch, before the renderer paints, so any orphan that accumulated across sessions is gone before the user sees the cron view.
  2. Project delete cascade in src/main/services/project-delete-service.ts, immediately after the ahkLinkedProjectId clear — so the override map shrinks the moment a project leaves the live set.

The prune is idempotent: when no orphan keys exist, it's a no-op (no settings write, no log line). When it does prune, it logs [cronGroupLabels] pruned N orphan keys (M remaining).

A soft-deleted project counts as missing — queries.listProjects() filters out is_deleted = 1, so the prune sees it as gone. This is intentional: undelete is rare enough that recovering a stale group label override would be more confusing than just letting the user re-rename.

Where the data lives

Layer File Purpose
Type src/shared/types.ts AppSettings.cronGroupLabels: Record<string, string>
Schema src/shared/ipc-schemas.ts Zod updateSettingsSchema field — rejects empty values
Resolver src/renderer/src/features/cron/cron-group-label.ts useGroupLabelResolver(viewMode) + MAX_GROUP_LABEL_LEN
Header src/renderer/src/features/cron/CronJobGroupHeader.tsx Inline rename input + pencil affordance
Wiring src/renderer/src/features/cron/CronDashboard.tsx handleRenameGroup on the main view
Wiring src/renderer/src/features/cron/CronJobsSidebar.tsx handleRenameGroup on the cron sidebar
GC src/main/services/cron-group-labels-service.ts pruneOrphanCronGroupLabels()

Tests

  • tests/unit/features/cron/cron-job-group-header.test.tsx — 14 RTL tests covering frequency-mode parity, rename trigger render, input pre-fill, propagation isolation, Enter / Ctrl+Enter save, MAX_GROUP_LABEL_LEN clamp, empty / whitespace / equal-to-live → reset, ESC cancel, orphan group renameability.
  • The resolver and prune service have their own unit tests — see the cron-group-label resolver test and the cron-group-labels-service test for the underlying behavior.

Related

How cron jobs are created and edited in the first place is on the create a cron job with AI page. What happens when one of them fails is on the cron failure alerts page, and the session Omniscio can start to repair a broken job automatically is on the cron self-healing page.

Last verified 2026-09-23