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)
23 lines
887 B
Python
23 lines
887 B
Python
"""modules/registry.py auto-discovery — no per-module registration required."""
|
|
from fastapi import APIRouter
|
|
|
|
from modules.registry import ROUTERS
|
|
|
|
|
|
def test_discovers_every_module_with_a_router():
|
|
prefixes = sorted(r.prefix for r in ROUTERS)
|
|
assert prefixes == ["/mail", "/network"]
|
|
assert all(isinstance(r, APIRouter) for r in ROUTERS)
|
|
|
|
|
|
def test_folder_without_router_py_is_skipped(tmp_path, monkeypatch):
|
|
# A module folder that hasn't grown a router.py yet (e.g. mid-scaffold)
|
|
# must not blow up discovery.
|
|
import modules.registry as registry
|
|
(tmp_path / "not_a_module").mkdir()
|
|
(tmp_path / "not_a_module" / "__init__.py").touch()
|
|
monkeypatch.setattr(registry, "_MODULES_DIR", tmp_path)
|
|
# No router.py in the folder, so discovery must skip it without raising
|
|
# (it never even attempts the import).
|
|
assert registry._discover() == []
|