Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@ ports/posix/build/
# macOS Finder metadata
.DS_Store

# Personal LLM coding-assistant configs; see CONTRIBUTING.md.
CLAUDE.md
# Personal LLM coding-assistant configs; AGENTS.md and CLAUDE.md are tracked.
# See CONTRIBUTING.md.
CLAUDE.local.md
AGENTS.md
GEMINI.md
.claude/
.cursor/
Expand Down
43 changes: 43 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# cpp-sdk

Instructions for LLM coding assistants working in this repository. Personal additions go in a gitignored local file (`CLAUDE.local.md` for Claude Code); see [CONTRIBUTING.md](CONTRIBUTING.md#llm-coding-assistants).

## What this is

A portable C++17 core for devices and controllers on the Electrification Bus (eBus), which builds on the [Homie 5 MQTT convention](https://homieiot.github.io/). It depends only on the C and C++ standard libraries and ArduinoJson; a port supplies the MQTT client, the console and the clock. [esp32-firmware](https://github.com/electrification-bus/esp32-firmware) consumes it as a git submodule, pinned to a release tag.

## Layout

| Path | Contents |
|---|---|
| `mqtt/` | `ebus_mqtt`: the transport interface, publishes held while disconnected, the reconnect order ([doc/mqtt.md](doc/mqtt.md)) |
| `discovery/` | `ebus_discovery`: mDNS TXT records, the `MdnsBackend` interface, broker discovery ([doc/discovery.md](doc/discovery.md)) |
| `homie/` | `ebus_homie`: Device, Node, Property, `/set` dispatch, the controller, validation ([doc/core.md](doc/core.md)) |
| `link/` | `ebus_link`: property links ([doc/link.md](doc/link.md)) |
| `include/` | The pre-split header paths (`<homie/Device.h>`), forwarding to the components |
| `ports/posix/` | The POSIX reference port (Paho MQTT C), its demo programs and end-to-end tests |
| `test/` | Unity suites, one directory per suite; `test/support/` holds the fakes that stand in for a port |

## Commands

```sh
cmake -S . -B build && cmake --build build -j && ctest --test-dir build --output-on-failure
cmake -S ports/posix -B ports/posix/build && cmake --build ports/posix/build -j && ctest --test-dir ports/posix/build --output-on-failure
```

The first runs the core's suites; the second builds the POSIX port and runs its end-to-end tests, which need `mosquitto` installed. A change to what goes on the wire needs the end-to-end tests too, not only a unit test.

## House style for the core

`mqtt/`, `discovery/`, `homie/`, `link/` and `include/` run on microcontrollers:

- No dynamic allocation in steady state: fixed-size buffers and static or caller-owned storage. What allocates today is listed in [doc/core.md](doc/core.md) ("Rules for code in the core"); new code adds nothing to that list.
- No STL, no Arduino `String`, no lambdas. Use `snprintf`, and C function pointers with a `void*` context for callbacks. Members are underscore-prefixed.
- No Arduino, ESP-IDF, FreeRTOS or OS header. Each component includes only standard headers, its own, and those of the components it depends on; CI compiles each with only those include directories.
- C++17, GCC and Clang, warnings as errors in CI.
- Ports (`ports/`) may use their platform's facilities but keep the contract in [doc/core.md](doc/core.md).
- The Homie 5 convention and the [eBus specification](https://github.com/electrification-bus/specification) decide wire behavior: where code and spec disagree, fix the code. On a spec sync, update `.ebus-spec.json`.
- Comments explain a non-obvious why, not what the code does.
- User-visible changes get an entry under `## [Unreleased]` in [CHANGELOG.md](CHANGELOG.md).

Markdown prose is written one paragraph per line, without hard wraps.
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@AGENTS.md
6 changes: 4 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,11 @@ Pull requests are welcome.
- **Don't hard-wrap Markdown prose.** Write each paragraph in docs as a single continuous line; reserve hard breaks for list items, headings, code fences, and tables.
- One commit per logical change is fine; we don't require squash or any particular branch naming.

## Keep your personal LLM config out of the repo
## LLM coding assistants

If you use an LLM coding assistant (Claude Code, Cursor, Aider, etc.), do **not** commit your personal LLM config files (`CLAUDE.md`, `AGENTS.md`, `.claude/`, `.cursor/`, etc.). Different contributors have different setups. Keep them in a separate shadow repo symlinked into your working tree, or add the paths to `.git/info/exclude`. The project `.gitignore` already lists the common ones defensively. If you have a use case for project-wide LLM context that *should* be tracked, discuss with the maintainers first.
[`AGENTS.md`](AGENTS.md) holds the shared instructions for LLM coding assistants (Codex, Cursor, GitHub Copilot and others read it; [`CLAUDE.md`](CLAUDE.md) imports it for Claude Code). Change it by pull request when the project's conventions change.

Keep your personal configuration out of the repo: `CLAUDE.local.md` (which Claude Code loads alongside `CLAUDE.md`), `.claude/`, `.cursor/` and the like are gitignored. To version them anyway, keep them in a separate private "shadow" repository and symlink them into your working tree, for example `ln -s ~/path/to/shadow-repo/cpp-sdk/CLAUDE.local.md CLAUDE.local.md`; for a file you don't need to version, `.git/info/exclude` works too.

## Code of conduct

Expand Down
Loading