7 documents covering stack, integrations, architecture, structure, conventions, testing, and concerns.
210 lines
10 KiB
Markdown
210 lines
10 KiB
Markdown
# Codebase Structure
|
|
|
|
**Analysis Date:** 2026-04-01
|
|
|
|
## Directory Layout
|
|
|
|
```
|
|
surfaces-bot/
|
|
├── adapter/
|
|
│ ├── __init__.py
|
|
│ └── matrix/ # matrix-nio adapter (merged to main)
|
|
│ ├── __init__.py
|
|
│ ├── bot.py # Entry point, MatrixBot class, send_outgoing()
|
|
│ ├── converter.py # nio Event → IncomingEvent
|
|
│ ├── reactions.py # Emoji constants, skills text builder
|
|
│ ├── room_router.py # room_id → chat_id resolution
|
|
│ ├── store.py # Matrix-specific StateStore helpers (room meta, user meta)
|
|
│ └── handlers/
|
|
│ ├── __init__.py # register_matrix_handlers()
|
|
│ ├── auth.py # handle_invite (invite member event)
|
|
│ ├── chat.py # Chat creation (creates real Matrix rooms)
|
|
│ ├── confirm.py # Confirmation flow callbacks
|
|
│ └── settings.py # Settings sub-commands and toggle_skill
|
|
├── core/
|
|
│ ├── auth.py # AuthManager: start_flow, confirm, is_authenticated
|
|
│ ├── chat.py # ChatManager: get_or_create, list_active, rename, archive
|
|
│ ├── handler.py # EventDispatcher: register, dispatch, _routing_key
|
|
│ ├── protocol.py # All shared dataclasses and type aliases
|
|
│ ├── settings.py # SettingsManager: get (cached), apply (invalidates cache)
|
|
│ ├── store.py # StateStore Protocol, InMemoryStore, SQLiteStore
|
|
│ └── handlers/
|
|
│ ├── __init__.py # register_all() — binds all core handlers to dispatcher
|
|
│ ├── callback.py # handle_confirm, handle_cancel, handle_toggle_skill
|
|
│ ├── chat.py # handle_new_chat, handle_rename, handle_archive, handle_list_chats
|
|
│ ├── message.py # handle_message — auth guard + platform.send_message
|
|
│ ├── settings.py # handle_settings — displays settings menu
|
|
│ └── start.py # handle_start — get_or_create_user + welcome message
|
|
├── sdk/
|
|
│ ├── __init__.py
|
|
│ ├── interface.py # PlatformClient Protocol, WebhookReceiver Protocol, Pydantic models
|
|
│ └── mock.py # MockPlatformClient — full in-memory implementation
|
|
├── tests/
|
|
│ ├── __init__.py
|
|
│ ├── conftest.py # (root conftest — sys.path fix for local sdk/ shadowing stdlib)
|
|
│ ├── adapter/
|
|
│ │ ├── __init__.py
|
|
│ │ ├── matrix/
|
|
│ │ │ ├── __init__.py
|
|
│ │ │ ├── test_converter.py
|
|
│ │ │ ├── test_dispatcher.py
|
|
│ │ │ ├── test_reactions.py
|
|
│ │ │ └── test_store.py
|
|
│ │ └── test_forum_db.py # untracked — forum DB exploration
|
|
│ ├── core/
|
|
│ │ ├── test_auth.py
|
|
│ │ ├── test_chat.py
|
|
│ │ ├── test_dispatcher.py
|
|
│ │ ├── test_integration.py
|
|
│ │ ├── test_protocol.py
|
|
│ │ ├── test_settings.py
|
|
│ │ ├── test_store.py
|
|
│ │ └── test_voice_slot.py
|
|
│ └── platform/
|
|
│ └── test_mock.py
|
|
├── docs/ # All human documentation
|
|
├── .planning/ # GSD planning artefacts
|
|
│ └── codebase/ # Codebase map documents (this directory)
|
|
├── .claude/
|
|
│ └── agents/ # Agent configuration files
|
|
├── .worktrees/
|
|
│ └── telegram/ # Telegram adapter on feat/telegram-adapter branch
|
|
│ └── ... # Mirrors main layout; merged separately
|
|
├── conftest.py # Root pytest conftest: sys.path hack for local sdk/
|
|
├── pyproject.toml # Project metadata, dependencies, ruff + pytest config
|
|
├── uv.lock # Lockfile (uv)
|
|
├── lambda_matrix.db # SQLite DB written by Matrix bot (gitignored)
|
|
└── .env.example # Environment variable template
|
|
```
|
|
|
|
## Directory Purposes
|
|
|
|
**`core/`:**
|
|
- Purpose: Platform-neutral business logic. Never imports from `adapter/`.
|
|
- Key files: `protocol.py` (all shared types), `handler.py` (dispatcher), `store.py` (persistence interface)
|
|
- Add new domain logic here; keep it free of aiogram/matrix-nio imports
|
|
|
|
**`core/handlers/`:**
|
|
- Purpose: One async function per command/callback/message type. Each returns `list[OutgoingEvent]`.
|
|
- Registration: `register_all()` in `core/handlers/__init__.py` binds them to the dispatcher
|
|
- Adapters can override any key by calling `dispatcher.register(event_type, key, fn)` after `register_all()`
|
|
|
|
**`sdk/`:**
|
|
- Purpose: Contract (`interface.py`) and mock (`mock.py`) for the Lambda AI platform SDK
|
|
- Note: The directory is named `sdk/` in actual code (not `platform/` as CLAUDE.md describes); `handler.py` imports from `sdk.interface`
|
|
- When real SDK arrives: replace `sdk/mock.py` only; `sdk/interface.py` must not change unless the contract changes
|
|
|
|
**`adapter/matrix/`:**
|
|
- Purpose: Everything matrix-nio-specific. Translates between nio and core protocol.
|
|
- `bot.py` owns `MatrixBot`, `build_runtime()`, `send_outgoing()`, and `main()`
|
|
- `store.py` provides key-namespaced helpers on top of `StateStore` (not a separate store implementation)
|
|
- `room_router.py` maintains the `room_id → chat_id` mapping persisted in `StateStore`
|
|
|
|
**`adapter/telegram/`:**
|
|
- Purpose: aiogram 3.x adapter. Lives in `.worktrees/telegram/` on `feat/telegram-adapter` branch.
|
|
- Uses aiogram FSM states (`states.py`) and inline keyboards (`keyboards/`)
|
|
- Not yet merged to `main`
|
|
|
|
**`tests/`:**
|
|
- Purpose: pytest test suite mirroring the source tree
|
|
- `tests/core/` — unit tests for each core module
|
|
- `tests/adapter/matrix/` — Matrix adapter tests (converter, dispatcher, reactions, store)
|
|
- `tests/platform/` — MockPlatformClient tests
|
|
|
|
**`docs/`:**
|
|
- Purpose: Human-readable design documents; not consumed by code
|
|
- Key docs: `docs/surface-protocol.md` (unification rationale), `docs/api-contract.md` (SDK contract), `docs/telegram-prototype.md`, `docs/matrix-prototype.md`
|
|
|
|
## Key File Locations
|
|
|
|
**Entry Points:**
|
|
- `adapter/matrix/bot.py` — Matrix bot `main()`, run via `python -m adapter.matrix.bot`
|
|
- `.worktrees/telegram/adapter/telegram/bot.py` — Telegram bot entry (feature branch)
|
|
|
|
**Shared Protocol:**
|
|
- `core/protocol.py` — single source of truth for all inter-layer data types
|
|
|
|
**SDK Contract:**
|
|
- `sdk/interface.py` — `PlatformClient` Protocol; defines the API surface for the real SDK
|
|
- `sdk/mock.py` — `MockPlatformClient`; current runtime implementation
|
|
|
|
**Dispatcher Registration:**
|
|
- `core/handlers/__init__.py` — `register_all()` for platform-agnostic handlers
|
|
- `adapter/matrix/handlers/__init__.py` — `register_matrix_handlers()` for Matrix overrides
|
|
|
|
**Persistence:**
|
|
- `core/store.py` — `StateStore` Protocol, `InMemoryStore`, `SQLiteStore`
|
|
- `adapter/matrix/store.py` — Matrix-specific store helper functions (not a store implementation)
|
|
|
|
**Configuration:**
|
|
- `pyproject.toml` — dependencies, pytest config (`asyncio_mode = "auto"`, `pythonpath = ["."]`), ruff config
|
|
- `conftest.py` — `sys.path` insert so local `sdk/` shadows stdlib `platform` module
|
|
|
|
## Naming Conventions
|
|
|
|
**Files:**
|
|
- Modules: `snake_case.py`
|
|
- Entry points: `bot.py` per adapter
|
|
- Converter: `converter.py` per adapter
|
|
- Handlers directory: `handlers/` per layer
|
|
|
|
**Classes:**
|
|
- Managers: `{Domain}Manager` (e.g. `ChatManager`, `AuthManager`, `SettingsManager`)
|
|
- Bot runtime: `{Platform}Bot` (e.g. `MatrixBot`)
|
|
- Protocol types: PascalCase dataclasses (e.g. `IncomingMessage`, `OutgoingUI`)
|
|
- SDK types: PascalCase Pydantic models (e.g. `MessageResponse`, `UserSettings`)
|
|
|
|
**Handler functions:**
|
|
- `handle_{command}` for command handlers (e.g. `handle_start`, `handle_new_chat`)
|
|
- `make_handle_{command}` for factory functions that close over adapter state (e.g. `make_handle_new_chat(client, store)`)
|
|
|
|
**State keys:**
|
|
- `"{namespace}:{discriminator}"` — always use the prefix constants defined in `adapter/matrix/store.py`
|
|
|
|
## Where to Add New Code
|
|
|
|
**New core command handler:**
|
|
1. Add `async def handle_{cmd}(event, chat_mgr, auth_mgr, settings_mgr, platform) -> list` in `core/handlers/{category}.py`
|
|
2. Register it in `core/handlers/__init__.py:register_all()` with `dispatcher.register(IncomingCommand, "{cmd}", handle_{cmd})`
|
|
3. Write tests in `tests/core/test_dispatcher.py` or a dedicated `tests/core/test_{category}.py`
|
|
|
|
**New Matrix-specific handler (needs nio client or matrix store):**
|
|
1. Add handler in `adapter/matrix/handlers/{category}.py`
|
|
2. Register in `adapter/matrix/handlers/__init__.py:register_matrix_handlers()` — this overrides the core handler for that key
|
|
|
|
**New protocol type:**
|
|
- Add dataclass to `core/protocol.py`; update `IncomingEvent` or `OutgoingEvent` union aliases if it crosses layer boundaries
|
|
- Update `EventDispatcher._routing_key()` if it requires a new dispatch strategy
|
|
|
|
**New StateStore key namespace:**
|
|
- Add prefix constant and helper functions in `adapter/matrix/store.py` (for Matrix-specific state) or directly in the relevant manager (for core state)
|
|
|
|
**New test:**
|
|
- Unit tests for core logic: `tests/core/test_{module}.py`
|
|
- Adapter tests: `tests/adapter/matrix/test_{module}.py`
|
|
- Use `InMemoryStore` as the store; use `MockPlatformClient` as the platform client
|
|
|
|
## Special Directories
|
|
|
|
**`.worktrees/telegram/`:**
|
|
- Purpose: Git worktree for `feat/telegram-adapter` branch; full copy of the repo root
|
|
- Generated: Yes (via `git worktree add`)
|
|
- Committed: No (worktrees are local)
|
|
|
|
**`.planning/`:**
|
|
- Purpose: GSD planning artefacts — phase plans and codebase maps
|
|
- Generated: Yes (by `/gsd:` commands)
|
|
- Committed: Yes (tracked with the repo)
|
|
|
|
**`.claude/agents/`:**
|
|
- Purpose: Agent role configuration files for the multi-agent workflow
|
|
- Committed: Yes
|
|
|
|
**`src/`:**
|
|
- Purpose: Contains only `surfaces_bot.egg-info/` (setuptools build artefact); no source code
|
|
- Generated: Yes
|
|
- Committed: No
|
|
|
|
---
|
|
|
|
*Structure analysis: 2026-04-01*
|