Skip to content

[codex] Refactor control-plane server lifecycle#153

Merged
roackb2 merged 2 commits into
mainfrom
codex/server-lifecycle-split
Jun 2, 2026
Merged

[codex] Refactor control-plane server lifecycle#153
roackb2 merged 2 commits into
mainfrom
codex/server-lifecycle-split

Conversation

@roackb2
Copy link
Copy Markdown
Owner

@roackb2 roackb2 commented Jun 2, 2026

Summary

Splits reusable control-plane server startup from daemon command behavior.

  • Adds startHeddleControlPlaneServer as the real src/server lifecycle owner for app creation, asset validation, HTTP listen/close, global live-server registration/heartbeat, known-workspace registration, and heartbeat scheduler coordination.
  • Changes heddle daemon into a CLI adapter that detects a fresh live server, prints its address, and exits successfully instead of throwing or starting another daemon.
  • Keeps signal handling and process.exit() in CLI/dev entrypoints rather than the reusable server lifecycle.
  • Documents the new server lifecycle boundary and adds focused lifecycle/daemon tests, including embedded-chat mode and ownership-safe shutdown.

Expected behavior change

After this slice, starting heddle daemon while a fresh control-plane server is already registered no longer fails with a second-daemon conflict. It reports the existing server endpoint and exits successfully.

A standalone daemon still starts the same control-plane server path when no fresh server exists, registers itself globally, refreshes its live-server heartbeat, and clears only its own live-server record on shutdown.

Embedded chat-v2 is not wired yet, but it can now use the same lifecycle API later without introducing a TUI-only server path or inheriting daemon-specific process-exit behavior.

Validation

  • yarn typecheck
  • yarn test
  • focused vitest for daemon/lifecycle/registry/runtime-host tests

@roackb2 roackb2 marked this pull request as ready for review June 2, 2026 07:08
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: d8371bd91f

ℹ️ 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".

Comment thread src/server/lifecycle.ts

heartbeat = setInterval(() => {
try {
registerServer();
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Avoid stealing newer live-server ownership

When two lifecycle handles coexist (for example an embedded-chat server starts after a daemon, or a daemon is started with the owner guard bypassed), this heartbeat keeps calling registerServer() unconditionally. That lets the older server overwrite the global live-server record after a newer server has registered, so clients can attach to the wrong endpoint until another heartbeat or shutdown changes it; the close path only protects clearLiveServer and does not prevent this refresh from stealing ownership. Check the current serverId before refreshing, or stop the heartbeat once this handle no longer owns the live-server record.

Useful? React with 👍 / 👎.

@roackb2 roackb2 merged commit 9a75290 into main Jun 2, 2026
5 checks passed
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