feat(register): auto hot-reload service after channel register/deregister

Making a channel registration live no longer depends on an operator/agent
remembering to restart. setup/register.ts and scripts/deregister-room.ts now
call signalEjclawReload() after the DB write, which sends SIGHUP to the running
service's main PID (→ runtimeState.reloadRoomBindings). Best-effort and
injectable-for-tests; no-ops when the service isn't running.

Also document the canonical rule in the committed, agent-loaded platform prompt
(prompts/claude-platform.md): prefer these paths, never fake a restart, verify
via the "Room bindings reloaded" log; a plain in-turn systemctl restart is
forbidden (it kills the agent).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Codex
2026-08-23 19:50:24 +09:00
parent 9020d2c8c5
commit f74536a8b2
5 changed files with 137 additions and 2 deletions

View File

@@ -34,6 +34,7 @@ import path from 'path';
import { Database } from 'bun:sqlite';
import { DATA_DIR, GROUPS_DIR, STORE_DIR } from '../src/config.js';
import { signalEjclawReload } from '../src/runtime-reload-signal.js';
const args = process.argv.slice(2);
const dryRun = args.includes('--dry-run');
@@ -355,5 +356,15 @@ try {
/* ignore */
}
console.log('\nDone. Restart ejclaw to drop the room(s) from live bindings:');
console.log(' systemctl --user restart ejclaw.service');
// Make the deregistration live immediately by hot-reloading the running
// service's room bindings (no full restart needed).
const reloaded = signalEjclawReload();
if (reloaded) {
console.log(
'\nDone. Signaled ejclaw to hot-reload room bindings (SIGHUP) — the room(s) are now dropped from live bindings.',
);
} else {
console.log(
'\nDone. ejclaw was not running (or MainPID unavailable); the change applies on next start.',
);
}