Skip to content

🤖 feat: add heartbeat settings section with global defaults#3114

Merged
ibetitsmike merged 4 commits intomainfrom
mike/heartbeat-9t9e
Apr 7, 2026
Merged

🤖 feat: add heartbeat settings section with global defaults#3114
ibetitsmike merged 4 commits intomainfrom
mike/heartbeat-9t9e

Conversation

@ibetitsmike
Copy link
Copy Markdown
Contributor

@ibetitsmike ibetitsmike commented Apr 2, 2026

Summary

Adds global heartbeat defaults (prompt and threshold) behind a dedicated Heartbeat settings section, gated by the Workspace Heartbeats experiment. The per-workspace heartbeat modal inherits the global default interval and shows the global default prompt as placeholder text.

Background

Heartbeats currently use hardcoded defaults unless each workspace overrides them individually. Users want global defaults they can configure once, so new workspaces inherit them automatically.

Implementation

  • New HeartbeatSection in Settings (bottom of the list, experiment-gated):
    • Default threshold: interval input in minutes (5 to 1440 min), saved on blur, clearable to return to hardcoded default
    • Default prompt: textarea for custom heartbeat instructions, saved on blur
  • Global config fields: heartbeatDefaultPrompt and heartbeatDefaultIntervalMs in AppConfigOnDiskSchema, persisted in ~/.mux/config.json.
  • IPC routes: config.updateHeartbeatDefaultPrompt and config.updateHeartbeatDefaultIntervalMs.
  • Per-workspace modal inheritance:
    • Interval: unconfigured workspaces default to the global interval
    • Prompt: shown as placeholder text in the message textarea (not pre-filled as a value, so saving without editing doesn't create a workspace override)
    • globalDefaultPrompt is cleared on load start and error to prevent stale placeholders across workspace switches
  • Backend precedence:
    • Prompt: per-workspace message > global heartbeatDefaultPrompt > hardcoded fallback
    • Interval: per-workspace intervalMs > global heartbeatDefaultIntervalMs > hardcoded fallback

Validation

  • IPC persistence tests for both config fields
  • HeartbeatSection UI tests (renders with experiment, loads values, saves on blur)
  • HeartbeatService scheduling tests (global interval fallback, workspace override wins)
  • Modal test (inherits global interval when no per-workspace config)

Mux working on behalf of Mike


Generated with mux • Model: anthropic:claude-opus-4-6 • Thinking: xhigh • Cost: $40.98

@ibetitsmike
Copy link
Copy Markdown
Contributor Author

@codex review

@ibetitsmike ibetitsmike force-pushed the mike/heartbeat-9t9e branch from 2580acb to b6d00d3 Compare April 2, 2026 22:22
@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Already looking forward to the next diff.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ibetitsmike ibetitsmike closed this Apr 2, 2026
@ibetitsmike ibetitsmike force-pushed the mike/heartbeat-9t9e branch from b6d00d3 to f3a2722 Compare April 2, 2026 23:11
@ibetitsmike ibetitsmike changed the title 🤖 refactor: rename heartbeat message to defaultPrompt 🤖 feat: add global heartbeat default prompt Apr 2, 2026
@ibetitsmike
Copy link
Copy Markdown
Contributor Author

@codex review

@ibetitsmike ibetitsmike reopened this Apr 2, 2026
@ibetitsmike
Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. More of your lovely PRs please.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ibetitsmike ibetitsmike force-pushed the mike/heartbeat-9t9e branch from 930eb37 to 8b882e6 Compare April 7, 2026 10:11
@ibetitsmike
Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Swish!

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ibetitsmike ibetitsmike changed the title 🤖 feat: add global heartbeat default prompt 🤖 feat: add heartbeat settings section with global defaults Apr 7, 2026
@ibetitsmike
Copy link
Copy Markdown
Contributor Author

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fda70f837a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ibetitsmike
Copy link
Copy Markdown
Contributor Author

@codex review

Added an edited-since-load guard to the prompt blur handler so stale values are not persisted after config load failures.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 215128aeb4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ibetitsmike
Copy link
Copy Markdown
Contributor Author

@codex review

The per-workspace modal now reads global config defaults (heartbeatDefaultIntervalMs, heartbeatDefaultPrompt) and uses them as initial values when no per-workspace settings exist. This means the global threshold setting takes effect immediately for unconfigured workspaces.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5883caee68

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ibetitsmike ibetitsmike force-pushed the mike/heartbeat-9t9e branch from 5883cae to f93dd67 Compare April 7, 2026 11:17
@ibetitsmike
Copy link
Copy Markdown
Contributor Author

@codex review

Global prompt is now only injected for workspaces with no heartbeat config at all. Workspaces that already have settings but no message override will not inherit the global prompt into form state, preserving future inheritance.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f93dd670de

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ibetitsmike
Copy link
Copy Markdown
Contributor Author

@codex review

Clearing the threshold field now sends intervalMs: null to remove the persisted global override, falling back to the hardcoded default.

@ibetitsmike ibetitsmike force-pushed the mike/heartbeat-9t9e branch from f93dd67 to 2384ae9 Compare April 7, 2026 11:27
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2384ae9aa0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ibetitsmike ibetitsmike force-pushed the mike/heartbeat-9t9e branch from 2384ae9 to 351899b Compare April 7, 2026 11:35
@ibetitsmike
Copy link
Copy Markdown
Contributor Author

@codex review

Global prompt is no longer seeded into the form state. The message field stays empty for unconfigured workspaces. Only the interval inherits the global default. Backend handles prompt fallback at execution time.

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. More of your lovely PRs please.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ibetitsmike ibetitsmike force-pushed the mike/heartbeat-9t9e branch from 351899b to 8b5a6ff Compare April 7, 2026 12:27
@ibetitsmike
Copy link
Copy Markdown
Contributor Author

@codex review

The per-workspace modal now shows the global default prompt as placeholder text in the message textarea. The field value stays empty so saving without editing doesn't persist the global prompt as a workspace override.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8b5a6ff8e0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ibetitsmike ibetitsmike force-pushed the mike/heartbeat-9t9e branch from 8b5a6ff to b911477 Compare April 7, 2026 12:35
@ibetitsmike
Copy link
Copy Markdown
Contributor Author

@codex review

Both the prompt and interval blur handlers now use the same guard pattern: skip only when the load failed AND the user hasn't edited. On successful load, blur-save proceeds because the loaded value is authoritative and re-persisting it is idempotent.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b9114770be

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ibetitsmike
Copy link
Copy Markdown
Contributor Author

Mux working on behalf of Mike

Resolving this thread: the blur-save-on-loaded pattern is consistent with how every other setting in GeneralSection works (e.g., llmDebugLogs, archive behaviors). Re-persisting an already-loaded value on blur is idempotent and matches the existing codebase convention. Changing this would require a broader refactor of the save-on-blur pattern across all settings.

@ibetitsmike
Copy link
Copy Markdown
Contributor Author

@codex review

Resolved the remaining thread. The blur-save pattern is consistent with existing settings behavior in GeneralSection.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b9114770be

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Use global heartbeat defaults in the workspace modal when no workspace override exists.
@ibetitsmike ibetitsmike force-pushed the mike/heartbeat-9t9e branch from b911477 to 1e8af71 Compare April 7, 2026 12:47
@ibetitsmike
Copy link
Copy Markdown
Contributor Author

@codex review

globalDefaultPrompt is now cleared on load start and in the error path, preventing stale placeholders across workspace switches or transient failures.

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Already looking forward to the next diff.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ibetitsmike ibetitsmike added this pull request to the merge queue Apr 7, 2026
Merged via the queue into main with commit b4ea427 Apr 7, 2026
24 checks passed
@ibetitsmike ibetitsmike deleted the mike/heartbeat-9t9e branch April 7, 2026 13:11
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.

1 participant