feat(desktop): bridge auto-starts non-IM services on boot (L4 cron)

The reflect/scheduler.py service drives the L4 archive cron every 12h,

but was only registered in the catalog and never auto-started. The UI

panel also wasn't surfacing it (WS snapshot filters to IM only), so

there was effectively no user-facing way to turn L4 archiving on.

Net effect: every GA deployment (local Tauri, Squishy, kw, etc.) had

L4_raw_sessions/ permanently empty. compress_session.py never ran.

Fix: on bridge startup, autostart everything in _catalog that isn't an

IM service. Currently that's just reflect/scheduler.py. IM services stay

manual because they need mykey.py config + explicit user opt-in.

After this lands:

  - bridge boots -> scheduler subprocess spawned

  - ~2 min later -> first L4 archive runs (since _l4_t starts at 0)

  - every 12h thereafter -> next L4 archive cycle

  - users get L4 with zero config
This commit is contained in:
dd3xp committed 2026-06-05 22:37:43 +08:00
1 parent 8e37028370
commit 5ade9841d2
1 file changed
+13
+13
View File
@@ -875,6 +875,18 @@ class ServiceManager:
return {"ok": False, "error": item["lastError"] or "start_failed", "service": item}
return {"ok": True, "service": item}
def autostart_extras(self) -> None:
"""Auto-start non-IM services on bridge boot. Currently:
- reflect/scheduler.py (drives L4 archive cron every 12h).
IM services stay manual (need explicit mykey.py config + user opt-in)."""
for sid in sorted(set(self._catalog) - set(self._im_catalog)):
try:
res = self.start_service(sid)
tag = "ok" if res.get("ok") else f"fail: {res.get('error')}"
except Exception as e:
tag = f"exception {type(e).__name__}: {e}"
print(f"[autostart] {sid}: {tag}", file=sys.stderr)
def stop_service(self, sid: str) -> dict:
if sid not in self._catalog:
raise KeyError(sid)
@@ -1508,6 +1520,7 @@ def create_app():
async def on_startup(app):
hub.loop = asyncio.get_running_loop()
services.autostart_extras()
app.on_startup.append(on_startup)
return app