docs: split context into layered, agent-oriented files
Replace the single file-structure.md with a stratified layout designed
for AI/agent skill consumption: tables and concrete identifiers over
prose, files loaded on demand, content separated by churn rate.
Layers:
- architecture/ stable structural reference (overview, source-map,
test-map, data-flow)
- patterns/ memory, commands, autocomplete, events, xmpp,
encryption, ui, plugins
- testing/ unit-tests, stubs, functional-tests, bench
- build/ local, docker, ci
- playbooks/ add-command, add-test, add-autocomplete,
add-event-handler, add-encryption
- gotchas.md append-only dated entries (seven seed entries)
- wip/ branch-specific notes; deleted on merge to master
Stable layers describe cproof on master only. In-flight feature
branches (currently feat/ai) get a single file under wip/.
INDEX.md is the entry map with churn labels; SKILL.md is the
always-loaded skill hint pointing to it.
This commit is contained in:
76
architecture/data-flow.md
Normal file
76
architecture/data-flow.md
Normal file
@@ -0,0 +1,76 @@
|
||||
# Data flow
|
||||
|
||||
High-level paths through the codebase. Use this when reasoning about where a
|
||||
change should land or where a bug originates.
|
||||
|
||||
## User input → action
|
||||
|
||||
```
|
||||
keypress
|
||||
→ src/ui/inputwin.c (line editor, key dispatch)
|
||||
→ src/command/cmd_ac.c (autocomplete on Tab)
|
||||
→ src/command/cmd_defs.c (parse / lookup)
|
||||
→ src/command/cmd_funcs.c (handler: cmd_<name>)
|
||||
→ side effects: src/xmpp/, src/config/, src/ui/, src/event/
|
||||
```
|
||||
|
||||
- Tab triggers autocomplete via `cmd_ac.c` lookup in `ac_funcs` hash table
|
||||
(key: `/cmd`, value: per-command `_<cmd>_autocomplete` function).
|
||||
- Enter parses input via `parse_args()` (`src/tools/parser.c`), looks up the
|
||||
`Command*` via `cmd_get()` (`src/command/cmd_defs.c`), invokes the handler
|
||||
declared with `CMD_MAINFUNC` or one of the `CMD_SUBFUNCS`.
|
||||
|
||||
## Outgoing chat message
|
||||
|
||||
```
|
||||
cmd_msg / typing-into-chatwin
|
||||
→ src/xmpp/message.c (build message stanza)
|
||||
→ src/xmpp/stanza.c (assemble XML)
|
||||
→ libstrophe (send)
|
||||
→ src/chatlog.c (persist locally)
|
||||
→ src/ui/chatwin.c (echo into window)
|
||||
```
|
||||
|
||||
Encryption injects between message build and send:
|
||||
|
||||
- OMEMO via `src/xmpp/omemo.c` → `src/omemo/omemo.c` (libsignal-protocol).
|
||||
- OTR via `src/otr/otr.c` (libotr).
|
||||
- PGP / OX via `src/pgp/gpg.c` / `src/pgp/ox.c` → `src/xmpp/ox.c`.
|
||||
|
||||
## Incoming stanza
|
||||
|
||||
```
|
||||
libstrophe callback
|
||||
→ src/xmpp/{message,presence,iq,muc,roster}.c (parse, validate)
|
||||
→ src/event/server_events.c (sv_ev_*)
|
||||
→ src/ui/{chatwin,mucwin,console,...}.c (render)
|
||||
→ src/chatlog.c (persist)
|
||||
```
|
||||
|
||||
`server_events.c` is the chokepoint — every inbound XMPP event flows through a
|
||||
`sv_ev_*` function. UI updates and persistence fan out from there.
|
||||
|
||||
## Client-initiated events
|
||||
|
||||
`src/event/client_events.c` mirrors `server_events.c` for events that
|
||||
originate locally (UI actions, command-driven state changes) but need the
|
||||
same downstream fan-out.
|
||||
|
||||
## Connection state
|
||||
|
||||
- `src/xmpp/connection.c` owns the `jabber_conn_status_t` (declared in
|
||||
`connection.h`).
|
||||
- `connection_get_status()` returns the current state. Many code paths gate
|
||||
on `JABBER_CONNECTED` — see `patterns/xmpp.md`.
|
||||
- Tests must `will_return(connection_get_status, JABBER_CONNECTED)` (or the
|
||||
desired state) before exercising any code path that consults it. See
|
||||
`gotchas.md`.
|
||||
|
||||
## Plugin hook points
|
||||
|
||||
Plugin callbacks (`src/plugins/callbacks.c`) sit on:
|
||||
- Pre/post message send and receive (around `src/xmpp/message.c` flow).
|
||||
- Connection lifecycle (around `src/xmpp/session.c`).
|
||||
- Window-switch events (around `src/ui/window_list.c`).
|
||||
|
||||
See `patterns/plugins.md`.
|
||||
59
architecture/overview.md
Normal file
59
architecture/overview.md
Normal file
@@ -0,0 +1,59 @@
|
||||
# Overview
|
||||
|
||||
## What cproof is
|
||||
|
||||
- Terminal-based XMPP (chat) client written in C.
|
||||
- Fork of [Profanity](https://github.com/profanity-im/profanity); rename to
|
||||
cproof is **work in progress** — many internal symbols, copyright headers,
|
||||
and identifiers still say "Profanity".
|
||||
- Heavy GLib usage (strings, lists, hash tables, key files).
|
||||
- Optional integrations: OMEMO (libsignal-protocol), OTR (libotr), PGP/OX
|
||||
(gpgme), Python plugins, libnotify, libgcrypt, libreadline, ncurses.
|
||||
|
||||
## Build system
|
||||
|
||||
- Autotools: `configure.ac` + a top-level `Makefile.am`. No CMake.
|
||||
- `autogen.sh` regenerates the configure script.
|
||||
- `configure-debug` is a thin helper that invokes `./configure` with
|
||||
debug-friendly flags.
|
||||
- Canonical build environment: Docker (`Dockerfile.debian` at repo root).
|
||||
See `build/docker.md`.
|
||||
|
||||
## Test framework
|
||||
|
||||
- **Unit tests:** cmocka, run via `make check`. Live in `tests/unittests/`.
|
||||
- **Functional tests:** custom runner in `tests/functionaltests/` against a
|
||||
real running cproof instance.
|
||||
- **Benches:** custom runners in `tests/bench/<runner>/` for database /
|
||||
flatfile / long-message workloads.
|
||||
- See `architecture/test-map.md` and the `testing/` directory for detail.
|
||||
|
||||
## High-level module split
|
||||
|
||||
Source lives under `src/` in module directories — see
|
||||
`architecture/source-map.md` for the full table. Major chunks:
|
||||
|
||||
- **Command layer** (`src/command/`) — `/foo`-style commands the user types.
|
||||
- **XMPP layer** (`src/xmpp/`) — protocol, sessions, stanza building.
|
||||
- **UI layer** (`src/ui/`) — windows, buffers, status bar, input.
|
||||
- **Event layer** (`src/event/`) — bridges between XMPP and UI / commands.
|
||||
- **Encryption** (`src/omemo/`, `src/otr/`, `src/pgp/`) — three independent
|
||||
encryption stacks.
|
||||
- **Plugins** (`src/plugins/`) — C and Python plugin APIs.
|
||||
- **Tools** (`src/tools/`) — generic utilities (parser, autocomplete, HTTP,
|
||||
clipboard, editor).
|
||||
|
||||
Active feature branches (e.g. `feat/ai`, which adds `src/ai/`) are not
|
||||
described in the stable architecture files. See `wip/` for branch-specific
|
||||
notes.
|
||||
|
||||
## Entry points
|
||||
|
||||
| File | Role |
|
||||
|---|---|
|
||||
| `src/main.c` | Process entry. |
|
||||
| `src/profanity.c` | Application init/shutdown lifecycle. |
|
||||
| `src/common.h` | Project-wide macros (`auto_*`, `FREE_SET_NULL`, `ARRAY_SIZE`). |
|
||||
| `src/database.c` / `src/database.h` | Database (SQLite + flatfile) abstraction. |
|
||||
| `src/chatlog.c` | Chat history persistence. |
|
||||
| `src/log.c` | Application log. |
|
||||
38
architecture/source-map.md
Normal file
38
architecture/source-map.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# Source map
|
||||
|
||||
## `src/` module directories
|
||||
|
||||
| Path | Purpose | Key files |
|
||||
|---|---|---|
|
||||
| `src/command/` | `/command` definition, dispatch, autocompletion. | `cmd_defs.c/h`, `cmd_funcs.c/h`, `cmd_ac.c/h` |
|
||||
| `src/config/` | Persistent configuration: accounts, prefs, themes, colors, CA file, scripts. | `accounts.c/h`, `preferences.c/h`, `theme.c/h`, `color.c/h`, `cafile.c/h`, `scripts.c/h`, `tlscerts.c/h`, `conflists.c/h`, `files.c/h`, `account.c/h` |
|
||||
| `src/event/` | Mediates between XMPP layer and UI/commands. | `client_events.c/h`, `server_events.c/h`, `common.c/h` |
|
||||
| `src/omemo/` | OMEMO encryption (libsignal-protocol). | `omemo.c/h`, `crypto.c/h`, `store.c/h` |
|
||||
| `src/otr/` | OTR encryption (libotr v4). | `otr.c/h`, `otrlib.h`, `otrlibv4.c` |
|
||||
| `src/pgp/` | OpenPGP / OX (gpgme). | `gpg.c/h`, `ox.c/h` |
|
||||
| `src/plugins/` | C and Python plugin support. | `plugins.c/h`, `c_plugins.c/h`, `python_plugins.c/h`, `c_api.c/h`, `python_api.c/h`, `api.c/h`, `profapi.c/h`, `callbacks.c/h`, `autocompleters.c/h`, `disco.c/h`, `settings.c/h`, `themes.c/h` |
|
||||
| `src/tools/` | Generic utilities. | `parser.c/h`, `autocomplete.c/h`, `clipboard.c/h`, `editor.c/h`, `http_*.c/h`, `aesgcm_download.c/h`, `bookmark_ignore.c/h`, `plugin_download.c/h` |
|
||||
| `src/ui/` | Windows, buffers, status bar, input. | `window.c/h`, `window_list.c/h`, `chatwin.c`, `mucwin.c`, `console.c`, `confwin.c`, `privwin.c`, `xmlwin.c`, `vcardwin.c`, `rosterwin.c`, `occupantswin.c`, `inputwin.c/h`, `statusbar.c/h`, `titlebar.c/h`, `tray.c/h`, `screen.c/h`, `notifier.c`, `core.c`, `buffer.c/h`, `ui.h`, `win_types.h` |
|
||||
| `src/xmpp/` | XMPP protocol layer. | `connection.c/h`, `session.c/h`, `roster.c/h`, `roster_list.c/h`, `muc.c/h`, `presence.c/h`, `message.c/h`, `iq.c/h`, `stanza.c/h`, `vcard.c/h`, `vcard_funcs.h`, `jid.c/h`, `capabilities.c/h`, `omemo.c/h`, `ox.c/h`, `blocking.c/h`, `bookmark.c/h`, `chat_session.c/h`, `chat_state.c/h`, `avatar.c/h`, `contact.c/h`, `form.c/h`, `resource.c/h` |
|
||||
|
||||
## Top-level files in `src/`
|
||||
|
||||
| File | Role |
|
||||
|---|---|
|
||||
| `main.c` | Process entry. |
|
||||
| `profanity.c` / `profanity.h` | Application init/shutdown. |
|
||||
| `common.h` / `common.c` | Project-wide macros and small helpers. |
|
||||
| `database.c` / `database.h` | Database facade (SQLite + flatfile). |
|
||||
| `chatlog.c` / `chatlog.h` | Chat log writer/reader. |
|
||||
| `log.c` / `log.h` | Application log. |
|
||||
| `config.h.in` | autoconf-generated config header (do not edit `config.h`). |
|
||||
| `gitversion.h.in` | Generated `gitversion.h` carrying build-time SHA. |
|
||||
|
||||
## Naming notes
|
||||
|
||||
- The fork-rename (Profanity → cproof) is incomplete. Many symbols, file
|
||||
paths, and headers still carry "Profanity" / "prof_" prefixes. Treat them as
|
||||
current and authoritative; do not rename opportunistically.
|
||||
- Encryption modules under `src/omemo/`, `src/otr/`, `src/pgp/` use module-
|
||||
internal helpers; the XMPP-side bridges live in `src/xmpp/omemo.c` and
|
||||
`src/xmpp/ox.c` (separate files with the same names — be precise about path).
|
||||
69
architecture/test-map.md
Normal file
69
architecture/test-map.md
Normal file
@@ -0,0 +1,69 @@
|
||||
# Test map
|
||||
|
||||
## Top-level test directories
|
||||
|
||||
| Path | Runner | Purpose |
|
||||
|---|---|---|
|
||||
| `tests/unittests/` | cmocka via `make check` | Unit tests with stubbed dependencies. |
|
||||
| `tests/functionaltests/` | custom binary, runs against a real cproof | End-to-end behaviour tests. |
|
||||
| `tests/bench/` | custom benches, one binary per runner | Database / flatfile / long-message benchmarks. |
|
||||
| `tests/prof_cmocka.h` | — | Thin cmocka wrapper used by all unit tests. |
|
||||
|
||||
## `tests/unittests/` layout
|
||||
|
||||
- `unittests.c` — single test runner. Registers every test via
|
||||
`cmocka_unit_test()` / `cmocka_unit_test_setup_teardown()`.
|
||||
- `helpers.c` / `helpers.h` — shared test utilities.
|
||||
- `test_<topic>.c` + `test_<topic>.h` — paired test files. The header
|
||||
declares each test function; the runner includes the header to register it.
|
||||
- Per-module subdirectories carry **stubs** for that module's public symbols:
|
||||
|
||||
| Stub directory | Stubs for |
|
||||
|---|---|
|
||||
| `tests/unittests/chatlog/` | `src/chatlog.c` |
|
||||
| `tests/unittests/command/` | `src/command/` |
|
||||
| `tests/unittests/config/` | `src/config/` (accounts, cafile, etc.) |
|
||||
| `tests/unittests/database/` | `src/database.c` |
|
||||
| `tests/unittests/event/` | `src/event/` |
|
||||
| `tests/unittests/log/` | `src/log.c` |
|
||||
| `tests/unittests/omemo/` | `src/omemo/` |
|
||||
| `tests/unittests/otr/` | `src/otr/` |
|
||||
| `tests/unittests/pgp/` | `src/pgp/` |
|
||||
| `tests/unittests/plugins/` | `src/plugins/` |
|
||||
| `tests/unittests/tools/` | `src/tools/` |
|
||||
| `tests/unittests/ui/` | `src/ui/` |
|
||||
| `tests/unittests/xmpp/` | `src/xmpp/` |
|
||||
| `tests/unittests/unittests/` | top-level utility stubs |
|
||||
|
||||
Branch-specific stubs (e.g. `tests/unittests/ai/` on `feat/ai`) are not
|
||||
listed here — see `wip/` for branch notes.
|
||||
|
||||
Each stub file is named `stub_<module>.c`. See `testing/stubs.md` for when
|
||||
to add or extend a stub.
|
||||
|
||||
## `tests/functionaltests/` layout
|
||||
|
||||
- `functionaltests.c` — runner.
|
||||
- `proftest.c` / `proftest.h` — fixture: spawns cproof under PTY, talks XMPP.
|
||||
- `test_<feature>.c` — feature suites: connect, disconnect, message, presence,
|
||||
carbons, roster, history, ping, autoping, lastactivity, software, disco,
|
||||
receipts, rooms, muc, chat_session, export_import.
|
||||
|
||||
Functional tests require:
|
||||
- A test XMPP server reachable from the test harness.
|
||||
- A pre-baked `.profrc` (see recent perf work).
|
||||
- See `testing/functional-tests.md` for prerequisites and runner flags.
|
||||
|
||||
## `tests/bench/` layout
|
||||
|
||||
Each runner is a separate directory + binary:
|
||||
|
||||
| Runner | Measures |
|
||||
|---|---|
|
||||
| `bench_runner` | Combined runner for general bench scenarios. |
|
||||
| `bench_export_import` | Database export/import throughput. |
|
||||
| `bench_failure_modes` | Flatfile parser failure / recovery paths. |
|
||||
| `bench_long_messages` | Flatfile parser with very long messages. |
|
||||
| `gen_history` | Generates synthetic chat history for benches. |
|
||||
|
||||
See `testing/bench.md` for invocation and interpretation.
|
||||
Reference in New Issue
Block a user