Files
NexusOS/modules/registry.py
janvanwan 42eaed647a feat: sync with upstream — v1.2.0, in-app updates, Projects, modules
Brings the public tree back in line with the development repo after several
weeks of drift caused by a stale publish include list.

New:
- In-app update path: GET /update/check compares the checkout against
  origin/main and POST /update/apply runs `ncp upgrade` detached (pull,
  rebuild, restart). The sidebar shows the version, checks on click, and
  offers an "update available" pill.
- Projects: a project workspace groups chats and RAG documents, with
  per-project instructions and document retrieval scoped to the active
  project. Replaces the standalone Documents page.
- modules/: auto-discovered feature plugins (mail, network) with their
  frontend counterparts and tests.
- Memory curation runs in-process (synapse/memory/curator.py) on the chat
  model when a conversation goes idle. The separate memory service on :8001
  is gone, along with the launcher lines that started it.

Also: the KDE theme, panel and Promethean terminal assets, the full test
suite, and VERSION 1.2.0.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-08-25 09:13:55 -05:00

38 lines
1.2 KiB
Python

"""Auto-discovers backend modules under modules/ — any subpackage with a
router.py exposing `router` (an APIRouter) is mounted automatically. Drop a
new module folder in and it's picked up on next start; nothing here needs
editing.
A missing router.py just means the folder isn't a module (skipped quietly).
An import error *inside* an existing router.py is a real bug and is left to
raise — silently swallowing it would hide broken modules instead of
surfacing them at startup.
"""
from __future__ import annotations
import importlib
import pkgutil
from pathlib import Path
from typing import List
from fastapi import APIRouter
_MODULES_DIR = Path(__file__).resolve().parent
def _discover() -> List[APIRouter]:
routers = []
for info in sorted(pkgutil.iter_modules([str(_MODULES_DIR)]), key=lambda m: m.name):
if not info.ispkg:
continue
if not (_MODULES_DIR / info.name / "router.py").exists():
continue
mod = importlib.import_module(f"modules.{info.name}.router")
router = getattr(mod, "router", None)
if isinstance(router, APIRouter):
routers.append(router)
return routers
ROUTERS = _discover()