From fd72768e0fbf57d18bf0eafe146f6c211cddb01b Mon Sep 17 00:00:00 2001 From: Julio Castillo Date: Wed, 11 Mar 2026 18:02:59 -0700 Subject: [PATCH 1/3] docs: add AI assistant configuration guidelines Add onboarding documentation for AI pair programmers: - .github/copilot-instructions.md for GitHub Copilot context - docs/ai-assistant-guide.md explaining all AI config files Closes #40 --- .github/copilot-instructions.md | 35 +++++++++++ docs/ai-assistant-guide.md | 108 ++++++++++++++++++++++++++++++++ 2 files changed, 143 insertions(+) create mode 100644 .github/copilot-instructions.md create mode 100644 docs/ai-assistant-guide.md diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000..640f929 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,35 @@ +# Copilot Instructions + +This is a modern C++ project template using CMake >= 3.20 and C++17. + +## Code Style + +- Follow Google C++ style with 4-space indentation and 100-character column limit +- Variables, locals, and members use `lower_case` naming +- Classes and structs use `CamelCase` naming +- Pointer alignment is left: `int* ptr` not `int *ptr` +- Brace style: K&R (attach opening brace to statement) +- Include sorting: main header first, then system headers, then project headers, separated by blank lines + +## Project Architecture + +- Each build target has its own subdirectory under `src/` with its own `CMakeLists.txt` +- Tests go in `tests/test_.cpp` using GoogleTest (GTest) +- Use `target_include_directories` and `target_link_libraries` with correct CMake visibility keywords (PUBLIC, PRIVATE, INTERFACE) +- Shared libraries use RPATH (`$ORIGIN/../lib`) for portable deployment +- Plugins use a C-compatible API with `extern "C"` exported factory functions + +## Build & Test + +- Build: `./scripts/build.sh` or `mkdir -p build && cd build && cmake .. && make` +- Test: `cd build && ctest --output-on-failure` +- Format: `./scripts/format.sh` +- Lint: `./scripts/lint.sh` (requires build first for compile_commands.json) + +## Conventions + +- Always use CMake target properties instead of raw compiler/linker flags +- Use `#pragma once` for header guards +- New libraries: create `src//CMakeLists.txt`, add via `add_subdirectory()` in root CMakeLists.txt +- New tests: create `tests/test_.cpp`, register in `tests/CMakeLists.txt` with `gtest_discover_tests()` +- Plugin implementations must export `create_plugin()` as `extern "C"` diff --git a/docs/ai-assistant-guide.md b/docs/ai-assistant-guide.md new file mode 100644 index 0000000..1fc1035 --- /dev/null +++ b/docs/ai-assistant-guide.md @@ -0,0 +1,108 @@ +# AI Assistant Configuration Guide + +This project includes configuration for **Claude Code** and **GitHub Copilot** +so AI tools generate code that matches the project's conventions out of the box. + +Think of these files as onboarding documentation for AI pair programmers. + +## What's Configured + +### Claude Code + +| File | Purpose | +|------|---------| +| `CLAUDE.md` | Project context: build commands, structure, conventions, anti-patterns | +| `.claude/settings.json` | Pre-approved commands and auto-format hook | +| `.claude/commands/*.md` | Custom slash commands (`/build`, `/test`, `/check`, `/add-library`) | + +### GitHub Copilot + +| File | Purpose | +|------|---------| +| `.github/copilot-instructions.md` | Code style, architecture patterns, naming conventions | + +## Claude Code Features Explained + +### CLAUDE.md (repository root) + +Automatically loaded into every Claude Code conversation. Contains build +commands, project structure, code conventions, and anti-patterns. Claude uses +this to generate code that matches `.clang-format` and `.clang-tidy` rules +without needing to run the formatters. + +Supports hierarchical placement — a `CLAUDE.md` in a subdirectory adds context +for that subtree (e.g., `tests/CLAUDE.md` could add test-specific instructions). + +### .claude/settings.json — Pre-approved Commands + +Without this file, Claude asks permission every time it runs `cmake`, `ctest`, +or `./scripts/build.sh`. The settings file pre-approves safe commands: + +```json +{ + "permissions": { + "allow": [ + "Bash(./scripts/build.sh*)", + "Bash(cmake *)", + "Bash(ctest *)", + ... + ] + } +} +``` + +This eliminates repetitive permission prompts and makes Claude significantly +faster to work with. Dangerous commands (`rm -rf /`, `sudo`) are explicitly denied. + +Personal overrides go in `.claude/settings.local.json` (gitignored). + +### .claude/settings.json — Auto-Format Hook + +The `PostToolUse` hook automatically runs `clang-format` on any `.cpp`, `.hpp`, +or `.h` file that Claude writes or edits. This means Claude's output always +matches the project's formatting rules — even if Claude's generation doesn't +perfectly follow `.clang-format`. + +### .claude/commands/ — Custom Slash Commands + +These are reusable workflows invoked with `/project:command-name`: + +| Command | What it does | +|---------|-------------| +| `/project:build [config]` | Build the project (default: Debug), run tests | +| `/project:test [filter]` | Run test suite, optionally filter by name | +| `/project:check` | Run full CI pipeline locally (format + build + lint + test) | +| `/project:add-library ` | Scaffold a new library target with CMake, source, header, and tests | + +Commands accept arguments via `$ARGUMENTS`. They're markdown files that tell +Claude what steps to follow — not shell scripts. + +### .github/copilot-instructions.md + +GitHub Copilot reads this for code generation context. It's intentionally more +concise than `CLAUDE.md` since Copilot uses it as supplementary context alongside +its own code analysis. Focused on naming conventions, architectural patterns, +and build commands. + +## How to Customize for Your Project + +When you fork this template: + +1. **Update `CLAUDE.md`** — Replace example library descriptions with your + actual architecture +2. **Update `.github/copilot-instructions.md`** — Adjust style rules to match +3. **Add slash commands** — Create `.claude/commands/your-workflow.md` for + project-specific workflows +4. **Adjust permissions** — Edit `.claude/settings.json` to pre-approve your + project's build tools + +**Tips:** +- Be specific: "Variables use `lower_case`" beats "write clean code" +- Document anti-patterns: "do not use X" prevents common AI mistakes +- Keep `CLAUDE.md` under 200 lines — longer files waste context and reduce adherence +- Test your instructions: ask the AI to generate a file and verify it follows conventions + +## Further Reading + +- [Claude Code documentation](https://docs.anthropic.com/en/docs/claude-code) +- [GitHub Copilot custom instructions](https://docs.github.com/en/copilot/customizing-copilot/adding-repository-custom-instructions-for-github-copilot) From 6253bdd8d6f764df7dc286364af2cf8fd5865f8c Mon Sep 17 00:00:00 2001 From: Julio Castillo Date: Wed, 11 Mar 2026 18:38:44 -0700 Subject: [PATCH 2/3] docs: address review feedback on AI assistant guidelines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix plugin factory function name: create_plugin → register_plugin (matches actual code in plugin_impl.cpp and plugin_api.hpp) - Mark .claude/settings.json and .claude/commands/ as recommended additions since they don't exist in the repo yet - Fix invalid JSON snippet: use jsonc fence with comment instead of ... - Clarify slash command invocation uses /project: prefix consistently --- .github/copilot-instructions.md | 2 +- CLAUDE.md | 2 +- docs/ai-assistant-guide.md | 18 ++++++++++++------ 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 640f929..b1d320c 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -32,4 +32,4 @@ This is a modern C++ project template using CMake >= 3.20 and C++17. - Use `#pragma once` for header guards - New libraries: create `src//CMakeLists.txt`, add via `add_subdirectory()` in root CMakeLists.txt - New tests: create `tests/test_.cpp`, register in `tests/CMakeLists.txt` with `gtest_discover_tests()` -- Plugin implementations must export `create_plugin()` as `extern "C"` +- Plugin implementations must export `register_plugin()` as `extern "C"` diff --git a/CLAUDE.md b/CLAUDE.md index f625bdc..d8a99ec 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -30,7 +30,7 @@ The template demonstrates four library patterns that build on each other: - **Interface library** (`example_interface`) — header-only, no compiled output; uses `INTERFACE` visibility so dependents get the include paths automatically - **Public/Private visibility** (`example_public_private`) — demonstrates how `PUBLIC` includes propagate to dependents while `PRIVATE` includes stay internal -The **plugin system** (`example_plugin_loader` + `example_plugin_impl`) shows runtime loading via `dlopen()`. Plugins implement a C-compatible API defined in `plugin_api.hpp` and must export `create_plugin()` as `extern "C"`. The loader discovers plugin `.so` files via RPATH. +The **plugin system** (`example_plugin_loader` + `example_plugin_impl`) shows runtime loading via `dlopen()`. Plugins implement a C-compatible API defined in `plugin_api.hpp` and must export `register_plugin()` as `extern "C"`. The loader discovers plugin `.so` files via RPATH. The main executable (`src/main/`) links against all libraries and demonstrates their usage together. diff --git a/docs/ai-assistant-guide.md b/docs/ai-assistant-guide.md index 1fc1035..9db1851 100644 --- a/docs/ai-assistant-guide.md +++ b/docs/ai-assistant-guide.md @@ -12,8 +12,13 @@ Think of these files as onboarding documentation for AI pair programmers. | File | Purpose | |------|---------| | `CLAUDE.md` | Project context: build commands, structure, conventions, anti-patterns | + +The following are **recommended additions** (not yet in the repo): + +| File | Purpose | +|------|---------| | `.claude/settings.json` | Pre-approved commands and auto-format hook | -| `.claude/commands/*.md` | Custom slash commands (`/build`, `/test`, `/check`, `/add-library`) | +| `.claude/commands/*.md` | Custom slash commands (e.g., `/project:build`, `/project:test`) | ### GitHub Copilot @@ -38,14 +43,14 @@ for that subtree (e.g., `tests/CLAUDE.md` could add test-specific instructions). Without this file, Claude asks permission every time it runs `cmake`, `ctest`, or `./scripts/build.sh`. The settings file pre-approves safe commands: -```json +```jsonc { "permissions": { "allow": [ "Bash(./scripts/build.sh*)", "Bash(cmake *)", - "Bash(ctest *)", - ... + "Bash(ctest *)" + // ... additional commands ] } } @@ -74,8 +79,9 @@ These are reusable workflows invoked with `/project:command-name`: | `/project:check` | Run full CI pipeline locally (format + build + lint + test) | | `/project:add-library ` | Scaffold a new library target with CMake, source, header, and tests | -Commands accept arguments via `$ARGUMENTS`. They're markdown files that tell -Claude what steps to follow — not shell scripts. +Commands are invoked with the `/project:` prefix (e.g., `/project:build`). +They accept arguments via `$ARGUMENTS` and are markdown files that tell Claude +what steps to follow — not shell scripts. ### .github/copilot-instructions.md From b31d7f4d1ce886e2b7853a4888a1de3d3c6f0613 Mon Sep 17 00:00:00 2001 From: Julio Castillo Date: Wed, 11 Mar 2026 20:29:25 -0700 Subject: [PATCH 3/3] docs: address second round of review feedback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix settings.local.json: clarify it's not gitignored yet, advise adding to .gitignore - Fix plugin terminology: "factory functions" → "entrypoints" to match actual register_plugin() ABI - Remove manual cmake build command from copilot instructions to avoid inconsistency with build.sh defaults --- .github/copilot-instructions.md | 4 ++-- docs/ai-assistant-guide.md | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index b1d320c..74dcbdd 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -17,11 +17,11 @@ This is a modern C++ project template using CMake >= 3.20 and C++17. - Tests go in `tests/test_.cpp` using GoogleTest (GTest) - Use `target_include_directories` and `target_link_libraries` with correct CMake visibility keywords (PUBLIC, PRIVATE, INTERFACE) - Shared libraries use RPATH (`$ORIGIN/../lib`) for portable deployment -- Plugins use a C-compatible API with `extern "C"` exported factory functions +- Plugins use a C-compatible API with `extern "C"` exported entrypoints ## Build & Test -- Build: `./scripts/build.sh` or `mkdir -p build && cd build && cmake .. && make` +- Build: `./scripts/build.sh` - Test: `cd build && ctest --output-on-failure` - Format: `./scripts/format.sh` - Lint: `./scripts/lint.sh` (requires build first for compile_commands.json) diff --git a/docs/ai-assistant-guide.md b/docs/ai-assistant-guide.md index 9db1851..dd928df 100644 --- a/docs/ai-assistant-guide.md +++ b/docs/ai-assistant-guide.md @@ -59,7 +59,8 @@ or `./scripts/build.sh`. The settings file pre-approves safe commands: This eliminates repetitive permission prompts and makes Claude significantly faster to work with. Dangerous commands (`rm -rf /`, `sudo`) are explicitly denied. -Personal overrides go in `.claude/settings.local.json` (gitignored). +Personal overrides should go in `.claude/settings.local.json`; add this path +to your `.gitignore` so local settings aren't committed. ### .claude/settings.json — Auto-Format Hook