{"id":"2e6922d0-3cd6-4b8f-a6ce-cf1be44ec3c7","shortId":"W7zZFQ","kind":"skill","title":"cpp","tagline":"Auto-activate for .cpp, .hpp, .cc, .hh, .cxx, CMakeLists.txt. Modern C++ development patterns for extensions and backend systems. Produces modern C++ code with proper build systems, resource management, and CI/CD integration. Use when: designing C++ code, setting up CI/CD pipelin","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-04-24T01:03:25.831Z","embedding":null,"createdAt":"2026-04-23T13:03:58.542Z","updatedAt":"2026-04-24T01:03:25.831Z","lastSeenAt":"2026-04-24T01:03:25.831Z","tsv":"'+20':307 '-1':815 '/actions':1007 '/actions/security-guides/security-hardening-for-github-actions':1015 '/cmake/help/latest/':992 '/cofin/flow/blob/main/templates/styleguides/general.md)':1043 '/cppcoreguidelines/cppcoreguidelines':981 '/extra/clang-tidy/':1000 '0':819,851,896 '0.1.0':636 '1':297,975 '1.0.0':184 '2':321,982 '20':191,643 '3':354,987 '3.20':180,631 '4':384,993 '5':407,1001 '6':1008 '7':1016 '8':1020 'abi':497 'accumul':472 'across':412,495 'action':239,553,1003,1010 'activ':4 'ad':125 'add':211,233,487,661 'address':293 'addresssanit':484 'algorithm':460 'alloc':163,363,451,566 'alongsid':395 'alway':482 'api':71,136,324,549,948 'asan':421,606 'auto':3,887 'auto-activ':2 'avoid':162,509 'b':244,253,287 'backend':19,54 'baselin':1025 'behavior':399 'best':937 'boundari':72,137,498,503,550 'branch':964 'buffer':773,884 'buffer.data':892 'buffer.size':758,893 'build':27,64,77,223,225,229,237,245,247,254,256,259,261,262,270,285,288,301,410,956 'build-and-releas':63 'byte':759,764 'c':13,23,37,43,51,306,496,575,941,976,983 'cach':170,433 'cache-friend':169 'cannot':718 'case':402,1054 'cast':910 'catch':499 'catch2':392 'cc':8 'check':276,546,997 'checkpoint':556 'choic':59 'ci':409,424,481,602,957,966 'ci/cd':32,41,81 'clang':278,417,995 'clang-tidi':277,416,994 'clang.llvm.org':999 'clang.llvm.org/extra/clang-tidy/':998 'class':622,697 'clear':150 'close':729,820 'cmake':172,175,176,188,193,199,204,243,252,260,286,309,625,627,640,645,651,656,988 'cmake.org':991 'cmake.org/cmake/help/latest/':990 'cmakelists.txt':11,304,573,619,626 'code':24,38,122,491,508,559 'command':207,238,240,312,579,659 'commit':1018 'compat':971 'compil':206,311,578,658 'concurr':75,146,490,521,955 'configur':241,250,408,603 'connect':702,731,780 'consist':614 'const':128,740,745,774,788,885,886,918 'convent':949,1017 'convert':505 'copyabl':737 'core':977 'cover':68 'coverag':405 'cpp':1,6,144,281,673,797 'creat':303,514 'critic':524 'ctest':266 'custom':450 'cxx':10,186,189,194,200,290,638,641,646,652 'data':168 'dcmake':246,255,289 'debug':242,249 'declar':335,589 'default':130,865,870,876 'defin':325 'delet':99,375,439,564,742,747 'deliv':558 'demonstr':623 'depend':516 'dependencies/toolchains':434 'design':36,58,85,322,537,936,942,968 'destruct':733 'detail':592,927,1057 'develop':14,44,961 'devic':709,717,726,775,786,811,827,834,838,844,859,861,904,906,916,922 'diagnost':554 'dir':269 'directori':217,668 'doc':989,1004 'docs.github.com':1006,1014 'docs.github.com/actions':1005 'docs.github.com/actions/security-guides/security-hardening-for-github-actions':1013 'document':153,345,598,933 'duplic':1035 'durat':532 'earli':545 'edg':401,1053 'en.cppreference.com':986 'enabl':231 'endif':236 'error':73,113,121,507,610,714,855,900,950 'exampl':618 'except':119,500 'exclus':105 'explicit':115,721 'export':205,310,577,657 'extens':17,52,201,653 'fail':856,902 'failur':274 'fast':426 'faster':477 'fd':814,818,821,841,850,891 'file':145,367 'find':468 'first':161 'flag':291 'flow':972 'focus':397,1047 'follow':932 'forward':334,588 'forward-declar':333 'framework':390 'free':536 'friend':171 'fsanit':292 'general':1039 'generic':1030 'git':78,963 'github':1002,1009 'github.com':1042 'github.com/cofin/flow/blob/main/templates/styleguides/general.md)':1041 'given':708 'global':510 'googletest':391 'guarante':349,596 'guardrail':435 'guid':928 'guidelin':978 'hand':463 'hand-written':462 'handl':74,114,368,611,951 'harden':1012 'harder':522 'header':140,327,331,585 'heap':362 'hh':9 'hidden':515 'hide':141,344 'hoc':126 'hold':527 'hot':165 'hpp':7 'hygien':953 'idiom':341 'immut':127 'impl':792,796,808,816,829,833,840,843,849,860,890,905,921 'implement':142,343,355,396,591,944 'includ':216,220,283,329,604,667,672,677,678,679,680,681,799,802,803,804,805 'include/sensor_reader/sensor_reader.hpp':674 'index':925 'input':544 'instanc':690 'int':813 'integr':33,431,1056 'isocpp.github.io':980 'isocpp.github.io/cppcoreguidelines/cppcoreguidelines':979 'j':263 'keep':167,330,523,1044 'key':84 'languag':185,637 'language/framework':1031 'language/library':985 'librari':209,212,662 'library/executable/test':318 'lifetim':95 'line':404 'local':76,960 'lock':151,370,528,535 'lock-fre':534 'loop':166,465 'maintain':57 'make':442,445,518,831 'manag':30,90 'matrix':411 'measur':160,539 'messag':147 'method':135 'minim':332,587 'minimum':177,531,609,628 'mix':124 'modern':12,22,50,940 'modul':118,617 'moveabl':738 'must':691 'mutabl':511 'mylib':182,213,218 'n':888,895,911 'necessari':542 'need':449 'never':123,371 'new':98,374,438,563 'nodiscard':766,782 'noexcept':750,754,789,869,875,919 'non':736 'non-copy':735 'nproc':264 'number':762 'o':846 'offici':973 'often':476 'one':695 'open':700,720,842,858 'oper':744,752,873 'option':222 'os/arch':414 'output':272 'output-on-failur':271 'overview':45 'ownership':70,100,152,946 'paramet':133 'pass':148 'path':710,727,776,787,812,828,835,839,862,907,917,923 'path.c_str':845 'pattern':15,174 'per':117,157 'perform':159,952 'pimpl':340 'pipelin':42,67,967 'plus':60 'pointer':360,382,569 'polici':116,612 'possibl':337 'practic':938 'pragma':675 'precondit':547 'prefer':376,458,533 'principl':86,87,1040 'privat':790 'produc':21 'project':181,632 'proper':26 'ptr':103,108,795 'public':219,326,351,584,600,671,699 'quick':82 'raii':91,357,364,456,571,624,728,947 'rang':467 'raw':97,373,437,562 'rdon':847 'read':755,765,770,881,889,901 'reader':634,664,670,778 'reader/sensor_reader.hpp':801 'reduc':1034 'refer':83,380,924,929,935,974,984 'references/ci_workflow.md':959 'references/design.md':939 'releas':66,251,258,969 'reliabl':62 'requir':178,196,629,648 'resourc':29,69,89,94,945 'return':552,760,908,920 'rule':88,1032 'run':415,483 'runtim':713,854,899 'safe':56,688 'safer':474 'safeti':156,348,595,684 'sanit':284,420,479,605 'section':525 'secur':1011 'semver':1021 'semver.org':1022 'sensor':633,663,669,705,800 'sensorread':698,722,734,739,741,743,746,748,749,751,753,807,822,823,863,864,866,867,868,871,872,874,880,915 'separ':317,425 'set':39,187,192,198,203,298,574,639,644,650,655 'setup':173 'share':107,112,446,1023,1027 'short':526 'size':768,878 'skill':48,1038,1046 'skill-cpp' 'slower':430 'small':138 'smart':359,568 'socket':369 'source-cofin' 'span':772,883 'specif':1051 'src':280 'src/mylib.cpp':214 'src/sensor_reader.cpp':665,798 'stabl':139 'standard':190,195,308,576,642,647 'state':512 'static':909 'std':101,106,441,444,459,466,469,471,712,723,767,771,783,793,809,824,830,836,853,877,882,898,912 'step':296,320,353,383,406 'strategi':965 'string':724,784,810,825,837,913 'struct':791,806 'styleguid':1024,1028 'subdirectori':234 'support':413 'system':20,28,302 'target':210,215,319,583,666 'test':221,224,226,230,232,235,265,268,386,389,394,428,432,519,582 'test-dir':267 'thread':155,347,594,683,687,696 'thread-saf':686 'thread-safeti':154,346,593,682 'threadsanit':488 'throw':494,711,852,897 'tidi':275,279,418,996 'tool':315,1050 'tool-specif':1049 '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':470 'truli':111 'type':158,248,257,352,378,457,601 'ubsan':422,607 'undefin':294 'undefinedbehaviorsanit':486 'uniqu':102,443,794,832 'unit':427 'use':34,46,338,358,372,387,440,478,567,693,1026 'valid':543,555 'valu':377 'variabl':132 'verifi':560 'version':179,183,630,635 'view':725,785,826,914 'within':615 'work':55 'workflow':79,295,958,962,1052 'wrap':452 'wrapper':365,572 'write':385,393 'written':464 'www.conventionalcommits.org':1019","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-04-24T01:03:25.831Z"}],"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-19T23:22:27Z","description":"Context-Driven Development toolkit for AI agents — spec-first planning, TDD workflow, and Beads integration.","skill_md_sha":"7cea41dfb5570910daaf42cebaddef588403b7c5","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":"Auto-activate for .cpp, .hpp, .cc, .hh, .cxx, CMakeLists.txt. Modern C++ development patterns for extensions and backend systems. Produces modern C++ code with proper build systems, resource management, and CI/CD integration. Use when: designing C++ code, setting up CI/CD pipelines, managing builds, or working with resource ownership, APIs, error handling, and concurrency in C++ projects. Not for C code or legacy C++ without modern idioms."},"skills_sh_url":"https://skills.sh/cofin/flow/cpp"},"updatedAt":"2026-04-24T01:03:25.831Z"}}