{"id":"2e6922d0-3cd6-4b8f-a6ce-cf1be44ec3c7","shortId":"W7zZFQ","kind":"skill","title":"cpp","tagline":"Use when editing C++ files, .cpp, .hpp, .cc, .hh, .cxx, CMakeLists.txt, modern C++ APIs, resource ownership, error handling, concurrency, build systems, or native extension code.","description":"# C++ Development\n\n## Overview\n\nUse this skill for modern C++ extension and backend work: safe, maintainable design choices plus a reliable build-and-release pipeline. Covers resource ownership, API boundaries, error handling, concurrency, local builds, git workflow, and CI/CD.\n\n## Quick Reference\n\n### Key Design Principles\n\n| Principle | Rule |\n|---|---|\n| Resource management | RAII for all resource lifetimes; no raw `new`/`delete` |\n| Ownership | `std::unique_ptr` for exclusive, `std::shared_ptr` only when truly shared |\n| Error handling | Explicit policy per module (exceptions or error codes); never mix ad hoc |\n| Immutability | `const` by default on variables, parameters, and methods |\n| API boundaries | Small, stable headers; hide implementation in `.cpp` files |\n| Concurrency | Message passing or clear lock ownership; document thread-safety per type |\n| Performance | Measure first; avoid allocations in hot loops; keep data cache-friendly |\n\n### CMake Setup Pattern\n\n```cmake\ncmake_minimum_required(VERSION 3.20)\nproject(mylib VERSION 1.0.0 LANGUAGES CXX)\n\nset(CMAKE_CXX_STANDARD 20)\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\nset(CMAKE_CXX_EXTENSIONS OFF)\nset(CMAKE_EXPORT_COMPILE_COMMANDS ON)\n\n# Library target\nadd_library(mylib src/mylib.cpp)\ntarget_include_directories(mylib PUBLIC include)\n\n# Tests\noption(BUILD_TESTS \"Build tests\" ON)\nif(BUILD_TESTS)\n    enable_testing()\n    add_subdirectory(tests)\nendif()\n```\n\n### Build Commands\n\n| Action | Command |\n|---|---|\n| Configure (debug) | `cmake -B build -DCMAKE_BUILD_TYPE=Debug` |\n| Configure (release) | `cmake -B build -DCMAKE_BUILD_TYPE=Release` |\n| Build | `cmake --build build -j$(nproc)` |\n| Test | `ctest --test-dir build --output-on-failure` |\n| Tidy check | `clang-tidy src/*.cpp -- -I include` |\n| Sanitizer build | `cmake -B build -DCMAKE_CXX_FLAGS=\"-fsanitize=address,undefined\"` |\n\n<workflow>\n\n## Workflow\n\n### Step 1: Set Up the Build System\n\nCreate `CMakeLists.txt` with C++20 standard, `CMAKE_EXPORT_COMPILE_COMMANDS ON` (for tooling), and separate library/executable/test targets.\n\n### Step 2: Design the API\n\nDefine public headers in `include/`. Keep headers minimal — forward-declare where possible, use the Pimpl idiom for implementation hiding. Document thread-safety guarantees on public types.\n\n### Step 3: Implement with RAII\n\nUse smart pointers for heap allocations, RAII wrappers for file handles / sockets / locks. Never use raw `new`/`delete`. Prefer value types and references over pointers.\n\n### Step 4: Write Tests\n\nUse a testing framework (GoogleTest, Catch2). Write tests alongside implementation. Focus on behavior and edge cases, not line coverage.\n\n### Step 5: Configure CI\n\nBuild matrix across supported OS/arch. Run clang-tidy and sanitizers (ASan, UBSan) in CI. Separate fast unit tests from slower integration tests. Cache dependencies/toolchains.\n\n</workflow>\n\n<guardrails>\n\n## Guardrails\n\n- **No raw `new`/`delete`** — use `std::make_unique` / `std::make_shared`; if you need custom allocation, wrap it in an RAII type\n- **Prefer `std::` algorithms** over hand-written loops — `std::ranges::find`, `std::transform`, `std::accumulate` are safer and often faster\n- **Use sanitizers in CI** — always run AddressSanitizer and UndefinedBehaviorSanitizer; add ThreadSanitizer for concurrent code\n- **Do not throw across C ABI boundaries** — catch exceptions at the boundary and convert to error codes\n- **Avoid global mutable state** — it creates hidden dependencies and makes testing and concurrency harder\n- **Keep critical sections short** — hold locks for the minimum duration; prefer lock-free designs when measured to be necessary\n- **Validate inputs early** — check preconditions at API boundaries and return actionable diagnostics\n\n</guardrails>\n\n<validation>\n\n### Validation Checkpoint\n\nBefore delivering code, verify:\n\n- [ ] No raw `new`/`delete` — all allocations use smart pointers or RAII wrappers\n- [ ] `CMakeLists.txt` sets C++ standard, exports compile commands, and has test targets\n- [ ] Public headers are minimal (forward declarations, no implementation details)\n- [ ] Thread-safety guarantees are documented on public types\n- [ ] CI configuration includes sanitizers (ASan + UBSan at minimum)\n- [ ] Error handling policy is consistent within the module\n\n</validation>\n\n<example>\n\n## Example\n\nCMakeLists.txt and a class demonstrating RAII:\n\n```cmake\n# CMakeLists.txt\ncmake_minimum_required(VERSION 3.20)\nproject(sensor_reader VERSION 0.1.0 LANGUAGES CXX)\n\nset(CMAKE_CXX_STANDARD 20)\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\nset(CMAKE_CXX_EXTENSIONS OFF)\nset(CMAKE_EXPORT_COMPILE_COMMANDS ON)\n\nadd_library(sensor_reader src/sensor_reader.cpp)\ntarget_include_directories(sensor_reader PUBLIC include)\n```\n\n```cpp\n// include/sensor_reader/sensor_reader.hpp\n#pragma once\n\n#include <cstdint>\n#include <memory>\n#include <span>\n#include <string>\n#include <string_view>\n\n/// Thread-safety: NOT thread-safe. Each instance must be used from one thread.\nclass SensorReader {\npublic:\n    /// Opens a connection to the sensor at the given device path.\n    /// Throws std::runtime_error if the device cannot be opened.\n    explicit SensorReader(std::string_view device_path);\n\n    /// RAII: closes the connection on destruction.\n    ~SensorReader();\n\n    // Non-copyable, moveable\n    SensorReader(const SensorReader&) = delete;\n    SensorReader& operator=(const SensorReader&) = delete;\n    SensorReader(SensorReader&&) noexcept;\n    SensorReader& operator=(SensorReader&&) noexcept;\n\n    /// Read up to `buffer.size()` bytes. Returns the number of bytes read.\n    [[nodiscard]] std::size_t read(std::span<std::uint8_t> buffer) const;\n\n    /// Device path this reader is connected to.\n    [[nodiscard]] std::string_view device_path() const noexcept;\n\nprivate:\n    struct Impl;\n    std::unique_ptr<Impl> impl_;\n};\n```\n\n```cpp\n// src/sensor_reader.cpp\n#include \"sensor_reader/sensor_reader.hpp\"\n\n#include <fcntl.h>\n#include <unistd.h>\n\n#include <stdexcept>\n#include <utility>\n\nstruct SensorReader::Impl {\n    std::string device_path;\n    int fd = -1;\n\n    ~Impl() {\n        if (fd >= 0) {\n            ::close(fd);\n        }\n    }\n};\n\nSensorReader::SensorReader(std::string_view device_path)\n    : impl_(std::make_unique<Impl>()) {\n    impl_->device_path = std::string(device_path);\n    impl_->fd = ::open(impl_->device_path.c_str(), O_RDONLY);\n    if (impl_->fd < 0) {\n        throw std::runtime_error(\"Failed to open device: \" + impl_->device_path);\n    }\n}\n\nSensorReader::~SensorReader() = default;\nSensorReader::SensorReader(SensorReader&&) noexcept = default;\nSensorReader& SensorReader::operator=(SensorReader&&) noexcept = default;\n\nstd::size_t SensorReader::read(std::span<std::uint8_t> buffer) const {\n    const auto n = ::read(impl_->fd, buffer.data(), buffer.size());\n    if (n < 0) {\n        throw std::runtime_error(\"Read failed on device: \" + impl_->device_path);\n    }\n    return static_cast<std::size_t>(n);\n}\n\nstd::string_view SensorReader::device_path() const noexcept {\n    return impl_->device_path;\n}\n```\n\n</example>\n\n---\n\n## References Index\n\nFor detailed guides, refer to the following documents in `references/`:\n\n- **[Design Best Practices](references/design.md)**\n  - Modern C++ design and implementation: resource ownership (RAII), API conventions, error handling, performance hygiene, and concurrency.\n- **[Build & CI Workflow](references/ci_workflow.md)**\n  - Local developer workflow, git branching strategy, CI pipeline design, release and compatibility flow.\n\n---\n\n## Official References\n\n1. C++ Core Guidelines: <https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines>\n2. C++ reference (language/library): <https://en.cppreference.com/>\n3. CMake docs: <https://cmake.org/cmake/help/latest/>\n4. Clang-Tidy checks: <https://clang.llvm.org/extra/clang-tidy/>\n5. GitHub Actions docs: <https://docs.github.com/actions>\n6. GitHub Actions security hardening: <https://docs.github.com/actions/security-guides/security-hardening-for-github-actions>\n7. Conventional Commits: <https://www.conventionalcommits.org/>\n8. SemVer: <https://semver.org/>\n\n## Shared Styleguide Baseline\n\n- Use shared styleguides for generic language/framework rules to reduce duplication in this skill.\n- [General Principles](https://github.com/cofin/flow/blob/main/templates/styleguides/general.md)\n- Keep this skill focused on tool-specific workflows, edge cases, and integration details.","tags":["cpp","flow","cofin","agent-skills","ai-agents","beads","claude-code","codex","cursor","developer-tools","gemini-cli","opencode"],"capabilities":["skill","source-cofin","skill-cpp","topic-agent-skills","topic-ai-agents","topic-beads","topic-claude-code","topic-codex","topic-cursor","topic-developer-tools","topic-gemini-cli","topic-opencode","topic-plugin","topic-slash-commands","topic-spec-driven-development"],"categories":["flow"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/cofin/flow/cpp","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add cofin/flow","source_repo":"https://github.com/cofin/flow","install_from":"skills.sh"}},"qualityScore":"0.455","qualityRationale":"deterministic score 0.46 from registry signals: · indexed on github topic:agent-skills · 11 github stars · SKILL.md body (8,396 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-18T19:07:35.990Z","embedding":null,"createdAt":"2026-04-23T13:03:58.542Z","updatedAt":"2026-05-18T19:07:35.990Z","lastSeenAt":"2026-05-18T19:07:35.990Z","tsv":"'+20':291 '-1':799 '/actions':991 '/actions/security-guides/security-hardening-for-github-actions':999 '/cmake/help/latest/':976 '/cofin/flow/blob/main/templates/styleguides/general.md)':1027 '/cppcoreguidelines/cppcoreguidelines':965 '/extra/clang-tidy/':984 '0':803,835,880 '0.1.0':620 '1':281,959 '1.0.0':168 '2':305,966 '20':175,627 '3':338,971 '3.20':164,615 '4':368,977 '5':391,985 '6':992 '7':1000 '8':1004 'abi':481 'accumul':456 'across':396,479 'action':223,537,987,994 'ad':109 'add':195,217,471,645 'address':277 'addresssanit':468 'algorithm':444 'alloc':147,347,435,550 'alongsid':379 'alway':466 'api':15,55,120,308,533,932 'asan':405,590 'auto':871 'avoid':146,493 'b':228,237,271 'backend':38 'baselin':1009 'behavior':383 'best':921 'boundari':56,121,482,487,534 'branch':948 'buffer':757,868 'buffer.data':876 'buffer.size':742,877 'build':21,48,61,207,209,213,221,229,231,238,240,243,245,246,254,269,272,285,394,940 'build-and-releas':47 'byte':743,748 'c':5,14,27,35,290,480,559,925,960,967 'cach':154,417 'cache-friend':153 'cannot':702 'case':386,1038 'cast':894 'catch':483 'catch2':376 'cc':9 'check':260,530,981 'checkpoint':540 'choic':43 'ci':393,408,465,586,941,950 'ci/cd':65 'clang':262,401,979 'clang-tidi':261,400,978 'clang.llvm.org':983 'clang.llvm.org/extra/clang-tidy/':982 'class':606,681 'clear':134 'close':713,804 'cmake':156,159,160,172,177,183,188,227,236,244,270,293,609,611,624,629,635,640,972 'cmake.org':975 'cmake.org/cmake/help/latest/':974 'cmakelists.txt':12,288,557,603,610 'code':26,106,475,492,543 'command':191,222,224,296,563,643 'commit':1002 'compat':955 'compil':190,295,562,642 'concurr':20,59,130,474,505,939 'configur':225,234,392,587 'connect':686,715,764 'consist':598 'const':112,724,729,758,772,869,870,902 'convent':933,1001 'convert':489 'copyabl':721 'core':961 'cover':52 'coverag':389 'cpp':1,7,128,265,657,781 'creat':287,498 'critic':508 'ctest':250 'custom':434 'cxx':11,170,173,178,184,274,622,625,630,636 'data':152 'dcmake':230,239,273 'debug':226,233 'declar':319,573 'default':114,849,854,860 'defin':309 'delet':83,359,423,548,726,731 'deliv':542 'demonstr':607 'depend':500 'dependencies/toolchains':418 'design':42,69,306,521,920,926,952 'destruct':717 'detail':576,911,1041 'develop':28,945 'devic':693,701,710,759,770,795,811,818,822,828,843,845,888,890,900,906 'diagnost':538 'dir':253 'directori':201,652 'doc':973,988 'docs.github.com':990,998 'docs.github.com/actions':989 'docs.github.com/actions/security-guides/security-hardening-for-github-actions':997 'document':137,329,582,917 'duplic':1019 'durat':516 'earli':529 'edg':385,1037 'edit':4 'en.cppreference.com':970 'enabl':215 'endif':220 'error':18,57,97,105,491,594,698,839,884,934 'exampl':602 'except':103,484 'exclus':89 'explicit':99,705 'export':189,294,561,641 'extens':25,36,185,637 'fail':840,886 'failur':258 'fast':410 'faster':461 'fd':798,802,805,825,834,875 'file':6,129,351 'find':452 'first':145 'flag':275 'flow':956 'focus':381,1031 'follow':916 'forward':318,572 'forward-declar':317 'framework':374 'free':520 'friend':155 'fsanit':276 'general':1023 'generic':1014 'git':62,947 'github':986,993 'github.com':1026 'github.com/cofin/flow/blob/main/templates/styleguides/general.md)':1025 'given':692 'global':494 'googletest':375 'guarante':333,580 'guardrail':419 'guid':912 'guidelin':962 'hand':447 'hand-written':446 'handl':19,58,98,352,595,935 'harden':996 'harder':506 'header':124,311,315,569 'heap':346 'hh':10 'hidden':499 'hide':125,328 'hoc':110 'hold':511 'hot':149 'hpp':8 'hygien':937 'idiom':325 'immut':111 'impl':776,780,792,800,813,817,824,827,833,844,874,889,905 'implement':126,327,339,380,575,928 'includ':200,204,267,313,588,651,656,661,662,663,664,665,783,786,787,788,789 'include/sensor_reader/sensor_reader.hpp':658 'index':909 'input':528 'instanc':674 'int':797 'integr':415,1040 'isocpp.github.io':964 'isocpp.github.io/cppcoreguidelines/cppcoreguidelines':963 'j':247 'keep':151,314,507,1028 'key':68 'languag':169,621 'language/framework':1015 'language/library':969 'librari':193,196,646 'library/executable/test':302 'lifetim':79 'line':388 'local':60,944 'lock':135,354,512,519 'lock-fre':518 'loop':150,449 'maintain':41 'make':426,429,502,815 'manag':74 'matrix':395 'measur':144,523 'messag':131 'method':119 'minim':316,571 'minimum':161,515,593,612 'mix':108 'modern':13,34,924 'modul':102,601 'moveabl':722 'must':675 'mutabl':495 'mylib':166,197,202 'n':872,879,895 'nativ':24 'necessari':526 'need':433 'never':107,355 'new':82,358,422,547 'nodiscard':750,766 'noexcept':734,738,773,853,859,903 'non':720 'non-copy':719 'nproc':248 'number':746 'o':830 'offici':957 'often':460 'one':679 'open':684,704,826,842 'oper':728,736,857 'option':206 'os/arch':398 'output':256 'output-on-failur':255 'overview':29 'ownership':17,54,84,136,930 'paramet':117 'pass':132 'path':694,711,760,771,796,812,819,823,846,891,901,907 'path.c_str':829 'pattern':158 'per':101,141 'perform':143,936 'pimpl':324 'pipelin':51,951 'plus':44 'pointer':344,366,553 'polici':100,596 'possibl':321 'practic':922 'pragma':659 'precondit':531 'prefer':360,442,517 'principl':70,71,1024 'privat':774 'project':165,616 'ptr':87,92,779 'public':203,310,335,568,584,655,683 'quick':66 'raii':75,341,348,440,555,608,712,931 'rang':451 'raw':81,357,421,546 'rdon':831 'read':739,749,754,865,873,885 'reader':618,648,654,762 'reader/sensor_reader.hpp':785 'reduc':1018 'refer':67,364,908,913,919,958,968 'references/ci_workflow.md':943 'references/design.md':923 'releas':50,235,242,953 'reliabl':46 'requir':162,180,613,632 'resourc':16,53,73,78,929 'return':536,744,892,904 'rule':72,1016 'run':399,467 'runtim':697,838,883 'safe':40,672 'safer':458 'safeti':140,332,579,668 'sanit':268,404,463,589 'section':509 'secur':995 'semver':1005 'semver.org':1006 'sensor':617,647,653,689,784 'sensorread':682,706,718,723,725,727,730,732,733,735,737,791,806,807,847,848,850,851,852,855,856,858,864,899 'separ':301,409 'set':171,176,182,187,282,558,623,628,634,639 'setup':157 'share':91,96,430,1007,1011 'short':510 'size':752,862 'skill':32,1022,1030 'skill-cpp' 'slower':414 'small':122 'smart':343,552 'socket':353 'source-cofin' 'span':756,867 'specif':1035 'src':264 'src/mylib.cpp':198 'src/sensor_reader.cpp':649,782 'stabl':123 'standard':174,179,292,560,626,631 'state':496 'static':893 'std':85,90,425,428,443,450,453,455,696,707,751,755,767,777,793,808,814,820,837,861,866,882,896 'step':280,304,337,367,390 'strategi':949 'string':708,768,794,809,821,897 'struct':775,790 'styleguid':1008,1012 'subdirectori':218 'support':397 'system':22,286 'target':194,199,303,567,650 'test':205,208,210,214,216,219,249,252,370,373,378,412,416,503,566 'test-dir':251 'thread':139,331,578,667,671,680 'thread-saf':670 'thread-safeti':138,330,577,666 'threadsanit':472 'throw':478,695,836,881 'tidi':259,263,402,980 'tool':299,1034 'tool-specif':1033 'topic-agent-skills' 'topic-ai-agents' 'topic-beads' 'topic-claude-code' 'topic-codex' 'topic-cursor' 'topic-developer-tools' 'topic-gemini-cli' 'topic-opencode' 'topic-plugin' 'topic-slash-commands' 'topic-spec-driven-development' 'transform':454 'truli':95 'type':142,232,241,336,362,441,585 'ubsan':406,591 'undefin':278 'undefinedbehaviorsanit':470 'uniqu':86,427,778,816 'unit':411 'use':2,30,322,342,356,371,424,462,551,677,1010 'valid':527,539 'valu':361 'variabl':116 'verifi':544 'version':163,167,614,619 'view':709,769,810,898 'within':599 'work':39 'workflow':63,279,942,946,1036 'wrap':436 'wrapper':349,556 'write':369,377 'written':448 'www.conventionalcommits.org':1003","prices":[{"id":"307de8ee-0b4f-467c-994c-bae750e97969","listingId":"2e6922d0-3cd6-4b8f-a6ce-cf1be44ec3c7","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"cofin","category":"flow","install_from":"skills.sh"},"createdAt":"2026-04-23T13:03:58.542Z"}],"sources":[{"listingId":"2e6922d0-3cd6-4b8f-a6ce-cf1be44ec3c7","source":"github","sourceId":"cofin/flow/cpp","sourceUrl":"https://github.com/cofin/flow/tree/main/skills/cpp","isPrimary":false,"firstSeenAt":"2026-04-23T13:03:58.542Z","lastSeenAt":"2026-05-18T19:07:35.990Z"}],"details":{"listingId":"2e6922d0-3cd6-4b8f-a6ce-cf1be44ec3c7","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"cofin","slug":"cpp","github":{"repo":"cofin/flow","stars":11,"topics":["agent-skills","ai-agents","beads","claude-code","codex","context-driven-development","cursor","developer-tools","gemini-cli","opencode","plugin","slash-commands","spec-driven-development","subagents","tdd","workflow"],"license":"apache-2.0","html_url":"https://github.com/cofin/flow","pushed_at":"2026-04-27T19:07:26Z","description":"Context-Driven Development toolkit for AI agents — spec-first planning, TDD workflow, and Beads integration.","skill_md_sha":"b60f20ac6afc7d9dddeb9d6fbd2f60ca5c340d5d","skill_md_path":"skills/cpp/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/cofin/flow/tree/main/skills/cpp"},"layout":"multi","source":"github","category":"flow","frontmatter":{"name":"cpp","description":"Use when editing C++ files, .cpp, .hpp, .cc, .hh, .cxx, CMakeLists.txt, modern C++ APIs, resource ownership, error handling, concurrency, build systems, or native extension code."},"skills_sh_url":"https://skills.sh/cofin/flow/cpp"},"updatedAt":"2026-05-18T19:07:35.990Z"}}