@hivehub/rulebook 4.2.2 → 4.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (334) hide show
  1. package/.claude/commands/continue.md +33 -33
  2. package/.claude/commands/ralph-config.md +112 -112
  3. package/.claude/commands/ralph-history.md +110 -110
  4. package/.claude/commands/ralph-init.md +72 -72
  5. package/.claude/commands/ralph-pause-resume.md +105 -105
  6. package/.claude/commands/ralph-run.md +101 -101
  7. package/.claude/commands/ralph-status.md +76 -76
  8. package/.claude/commands/rulebook-memory-save.md +48 -48
  9. package/.claude/commands/rulebook-memory-search.md +47 -47
  10. package/.claude/commands/rulebook-task-apply.md +67 -67
  11. package/.claude/commands/rulebook-task-archive.md +70 -70
  12. package/.claude/commands/rulebook-task-create.md +93 -93
  13. package/.claude/commands/rulebook-task-list.md +42 -42
  14. package/.claude/commands/rulebook-task-show.md +52 -52
  15. package/.claude/commands/rulebook-task-validate.md +53 -53
  16. package/.claude-plugin/marketplace.json +28 -28
  17. package/.claude-plugin/plugin.json +8 -8
  18. package/README.md +8 -1
  19. package/dist/cli/commands.d.ts.map +1 -1
  20. package/dist/cli/commands.js +4 -4
  21. package/dist/cli/commands.js.map +1 -1
  22. package/dist/core/claude-mcp.d.ts +8 -1
  23. package/dist/core/claude-mcp.d.ts.map +1 -1
  24. package/dist/core/claude-mcp.js +32 -1
  25. package/dist/core/claude-mcp.js.map +1 -1
  26. package/dist/core/generator.d.ts +13 -0
  27. package/dist/core/generator.d.ts.map +1 -1
  28. package/dist/core/generator.js +283 -28
  29. package/dist/core/generator.js.map +1 -1
  30. package/dist/core/workspace/workspace-manager.d.ts.map +1 -1
  31. package/dist/core/workspace/workspace-manager.js +2 -6
  32. package/dist/core/workspace/workspace-manager.js.map +1 -1
  33. package/dist/index.js +1 -3
  34. package/dist/index.js.map +1 -1
  35. package/dist/mcp/rulebook-server.d.ts.map +1 -1
  36. package/dist/mcp/rulebook-server.js +5 -4
  37. package/dist/mcp/rulebook-server.js.map +1 -1
  38. package/package.json +21 -22
  39. package/templates/agents/accessibility-reviewer.md +43 -0
  40. package/templates/agents/api-designer.md +42 -0
  41. package/templates/agents/architect.md +51 -0
  42. package/templates/agents/build-engineer.md +36 -0
  43. package/templates/agents/code-reviewer.md +47 -0
  44. package/templates/agents/database-architect.md +41 -0
  45. package/templates/agents/devops-engineer.md +42 -0
  46. package/templates/agents/docs-writer.md +38 -0
  47. package/templates/agents/i18n-engineer.md +42 -0
  48. package/templates/agents/implementer.md +38 -35
  49. package/templates/agents/migration-engineer.md +42 -0
  50. package/templates/agents/performance-engineer.md +49 -0
  51. package/templates/agents/refactoring-agent.md +41 -0
  52. package/templates/agents/researcher.md +38 -34
  53. package/templates/agents/security-reviewer.md +40 -0
  54. package/templates/agents/team-lead.md +37 -34
  55. package/templates/agents/tester.md +45 -42
  56. package/templates/agents/ux-reviewer.md +43 -0
  57. package/templates/ci/rulebook-review.yml +26 -26
  58. package/templates/cli/AIDER.md +49 -49
  59. package/templates/cli/AMAZON_Q.md +25 -25
  60. package/templates/cli/AUGGIE.md +32 -32
  61. package/templates/cli/CLAUDE.md +117 -117
  62. package/templates/cli/CLINE.md +99 -99
  63. package/templates/cli/CODEBUDDY.md +20 -20
  64. package/templates/cli/CODEIUM.md +20 -20
  65. package/templates/cli/CODEX.md +21 -21
  66. package/templates/cli/CONTINUE.md +34 -34
  67. package/templates/cli/CURSOR_CLI.md +62 -62
  68. package/templates/cli/FACTORY.md +18 -18
  69. package/templates/cli/GEMINI.md +35 -35
  70. package/templates/cli/KILOCODE.md +18 -18
  71. package/templates/cli/OPENCODE.md +18 -18
  72. package/templates/cli/_GENERIC_TEMPLATE.md +29 -29
  73. package/templates/commands/rulebook-memory-save.md +48 -48
  74. package/templates/commands/rulebook-memory-search.md +47 -47
  75. package/templates/commands/rulebook-task-apply.md +67 -67
  76. package/templates/commands/rulebook-task-archive.md +94 -94
  77. package/templates/commands/rulebook-task-create.md +93 -93
  78. package/templates/commands/rulebook-task-list.md +42 -42
  79. package/templates/commands/rulebook-task-show.md +52 -52
  80. package/templates/commands/rulebook-task-validate.md +53 -53
  81. package/templates/core/AGENTS_LEAN.md +25 -25
  82. package/templates/core/AGENTS_OVERRIDE.md +16 -16
  83. package/templates/core/AGENT_AUTOMATION.md +288 -288
  84. package/templates/core/DAG.md +304 -304
  85. package/templates/core/DOCUMENTATION_RULES.md +36 -36
  86. package/templates/core/MULTI_AGENT.md +74 -74
  87. package/templates/core/PLANS.md +28 -28
  88. package/templates/core/QUALITY_ENFORCEMENT.md +68 -68
  89. package/templates/core/RALPH.md +471 -471
  90. package/templates/core/RULEBOOK.md +1935 -1935
  91. package/templates/frameworks/ANGULAR.md +36 -36
  92. package/templates/frameworks/DJANGO.md +83 -83
  93. package/templates/frameworks/ELECTRON.md +147 -147
  94. package/templates/frameworks/FLASK.md +38 -38
  95. package/templates/frameworks/FLUTTER.md +55 -55
  96. package/templates/frameworks/JQUERY.md +32 -32
  97. package/templates/frameworks/LARAVEL.md +38 -38
  98. package/templates/frameworks/NESTJS.md +43 -43
  99. package/templates/frameworks/NEXTJS.md +127 -127
  100. package/templates/frameworks/NUXT.md +40 -40
  101. package/templates/frameworks/RAILS.md +66 -66
  102. package/templates/frameworks/REACT.md +38 -38
  103. package/templates/frameworks/REACT_NATIVE.md +47 -47
  104. package/templates/frameworks/SPRING.md +39 -39
  105. package/templates/frameworks/SYMFONY.md +36 -36
  106. package/templates/frameworks/VUE.md +36 -36
  107. package/templates/frameworks/ZEND.md +35 -35
  108. package/templates/git/CI_CD_PATTERNS.md +661 -661
  109. package/templates/git/GITHUB_ACTIONS.md +728 -728
  110. package/templates/git/GITLAB_CI.md +730 -730
  111. package/templates/git/GIT_WORKFLOW.md +1157 -1157
  112. package/templates/git/SECRETS_MANAGEMENT.md +585 -585
  113. package/templates/hooks/COMMIT_MSG.md +530 -530
  114. package/templates/hooks/POST_CHECKOUT.md +546 -546
  115. package/templates/hooks/PREPARE_COMMIT_MSG.md +619 -619
  116. package/templates/hooks/PRE_COMMIT.md +414 -414
  117. package/templates/hooks/PRE_PUSH.md +601 -601
  118. package/templates/ides/CONTINUE_RULES.md +16 -16
  119. package/templates/ides/COPILOT.md +37 -37
  120. package/templates/ides/COPILOT_INSTRUCTIONS.md +23 -23
  121. package/templates/ides/CURSOR.md +43 -43
  122. package/templates/ides/GEMINI_RULES.md +17 -17
  123. package/templates/ides/JETBRAINS_AI.md +35 -35
  124. package/templates/ides/REPLIT.md +36 -36
  125. package/templates/ides/TABNINE.md +29 -29
  126. package/templates/ides/VSCODE.md +40 -40
  127. package/templates/ides/WINDSURF.md +36 -36
  128. package/templates/ides/WINDSURF_RULES.md +14 -14
  129. package/templates/ides/ZED.md +32 -32
  130. package/templates/ides/cursor-mdc/go.mdc +24 -24
  131. package/templates/ides/cursor-mdc/python.mdc +24 -24
  132. package/templates/ides/cursor-mdc/quality.mdc +25 -25
  133. package/templates/ides/cursor-mdc/ralph.mdc +39 -39
  134. package/templates/ides/cursor-mdc/rulebook.mdc +38 -38
  135. package/templates/ides/cursor-mdc/rust.mdc +24 -24
  136. package/templates/ides/cursor-mdc/typescript.mdc +25 -25
  137. package/templates/languages/C.md +333 -333
  138. package/templates/languages/CPP.md +743 -743
  139. package/templates/languages/CSHARP.md +417 -417
  140. package/templates/languages/ELIXIR.md +454 -454
  141. package/templates/languages/ERLANG.md +361 -361
  142. package/templates/languages/GO.md +645 -645
  143. package/templates/languages/HASKELL.md +177 -177
  144. package/templates/languages/JAVA.md +607 -607
  145. package/templates/languages/JAVASCRIPT.md +631 -631
  146. package/templates/languages/JULIA.md +97 -97
  147. package/templates/languages/KOTLIN.md +511 -511
  148. package/templates/languages/LISP.md +100 -100
  149. package/templates/languages/LUA.md +74 -74
  150. package/templates/languages/OBJECTIVEC.md +90 -90
  151. package/templates/languages/PHP.md +416 -416
  152. package/templates/languages/PYTHON.md +682 -682
  153. package/templates/languages/RUBY.md +421 -421
  154. package/templates/languages/RUST.md +477 -477
  155. package/templates/languages/SAS.md +73 -73
  156. package/templates/languages/SCALA.md +348 -348
  157. package/templates/languages/SOLIDITY.md +580 -580
  158. package/templates/languages/SQL.md +137 -137
  159. package/templates/languages/SWIFT.md +466 -466
  160. package/templates/languages/TYPESCRIPT.md +591 -591
  161. package/templates/languages/ZIG.md +265 -265
  162. package/templates/modules/ATLASSIAN.md +255 -255
  163. package/templates/modules/CONTEXT7.md +54 -54
  164. package/templates/modules/FIGMA.md +267 -267
  165. package/templates/modules/GITHUB_MCP.md +64 -64
  166. package/templates/modules/GRAFANA.md +328 -328
  167. package/templates/modules/MEMORY.md +126 -126
  168. package/templates/modules/NOTION.md +247 -247
  169. package/templates/modules/PLAYWRIGHT.md +90 -90
  170. package/templates/modules/RULEBOOK_MCP.md +156 -156
  171. package/templates/modules/SERENA.md +337 -337
  172. package/templates/modules/SUPABASE.md +223 -223
  173. package/templates/modules/SYNAP.md +69 -69
  174. package/templates/modules/VECTORIZER.md +63 -63
  175. package/templates/modules/sequential-thinking.md +42 -42
  176. package/templates/ralph/ralph-history.bat +4 -4
  177. package/templates/ralph/ralph-history.sh +5 -5
  178. package/templates/ralph/ralph-init.bat +5 -5
  179. package/templates/ralph/ralph-init.sh +5 -5
  180. package/templates/ralph/ralph-pause.bat +5 -5
  181. package/templates/ralph/ralph-pause.sh +5 -5
  182. package/templates/ralph/ralph-run.bat +5 -5
  183. package/templates/ralph/ralph-run.sh +5 -5
  184. package/templates/ralph/ralph-status.bat +4 -4
  185. package/templates/ralph/ralph-status.sh +5 -5
  186. package/templates/services/AZURE_BLOB.md +184 -184
  187. package/templates/services/CASSANDRA.md +239 -239
  188. package/templates/services/DATADOG.md +26 -26
  189. package/templates/services/DOCKER.md +124 -124
  190. package/templates/services/DOCKER_COMPOSE.md +168 -168
  191. package/templates/services/DYNAMODB.md +308 -308
  192. package/templates/services/ELASTICSEARCH.md +347 -347
  193. package/templates/services/GCS.md +178 -178
  194. package/templates/services/HELM.md +194 -194
  195. package/templates/services/INFLUXDB.md +265 -265
  196. package/templates/services/KAFKA.md +341 -341
  197. package/templates/services/KUBERNETES.md +208 -208
  198. package/templates/services/MARIADB.md +183 -183
  199. package/templates/services/MEMCACHED.md +242 -242
  200. package/templates/services/MINIO.md +201 -201
  201. package/templates/services/MONGODB.md +268 -268
  202. package/templates/services/MYSQL.md +358 -358
  203. package/templates/services/NEO4J.md +247 -247
  204. package/templates/services/OPENTELEMETRY.md +25 -25
  205. package/templates/services/ORACLE.md +290 -290
  206. package/templates/services/PINO.md +24 -24
  207. package/templates/services/POSTGRESQL.md +326 -326
  208. package/templates/services/PROMETHEUS.md +33 -33
  209. package/templates/services/RABBITMQ.md +286 -286
  210. package/templates/services/REDIS.md +292 -292
  211. package/templates/services/S3.md +298 -298
  212. package/templates/services/SENTRY.md +23 -23
  213. package/templates/services/SQLITE.md +294 -294
  214. package/templates/services/SQLSERVER.md +294 -294
  215. package/templates/services/WINSTON.md +30 -30
  216. package/templates/skills/cli/aider/SKILL.md +59 -59
  217. package/templates/skills/cli/amazon-q/SKILL.md +35 -35
  218. package/templates/skills/cli/auggie/SKILL.md +42 -42
  219. package/templates/skills/cli/claude/SKILL.md +42 -42
  220. package/templates/skills/cli/cline/SKILL.md +42 -42
  221. package/templates/skills/cli/codebuddy/SKILL.md +30 -30
  222. package/templates/skills/cli/codeium/SKILL.md +30 -30
  223. package/templates/skills/cli/codex/SKILL.md +31 -31
  224. package/templates/skills/cli/continue/SKILL.md +44 -44
  225. package/templates/skills/cli/cursor-cli/SKILL.md +38 -38
  226. package/templates/skills/cli/factory/SKILL.md +28 -28
  227. package/templates/skills/cli/gemini/SKILL.md +45 -45
  228. package/templates/skills/cli/kilocode/SKILL.md +28 -28
  229. package/templates/skills/cli/opencode/SKILL.md +28 -28
  230. package/templates/skills/core/agent-automation/SKILL.md +194 -194
  231. package/templates/skills/core/dag/SKILL.md +314 -314
  232. package/templates/skills/core/documentation-rules/SKILL.md +46 -46
  233. package/templates/skills/core/quality-enforcement/SKILL.md +78 -78
  234. package/templates/skills/core/rulebook/SKILL.md +176 -176
  235. package/templates/skills/dev/accessibility/SKILL.md +17 -0
  236. package/templates/skills/dev/api-design/SKILL.md +15 -0
  237. package/templates/skills/dev/architect/SKILL.md +17 -0
  238. package/templates/skills/dev/build-fix/SKILL.md +17 -0
  239. package/templates/skills/dev/db-design/SKILL.md +15 -0
  240. package/templates/skills/dev/debug/SKILL.md +16 -0
  241. package/templates/skills/dev/deploy/SKILL.md +17 -0
  242. package/templates/skills/dev/docs/SKILL.md +17 -0
  243. package/templates/skills/dev/migrate/SKILL.md +15 -0
  244. package/templates/skills/dev/perf/SKILL.md +17 -0
  245. package/templates/skills/dev/refactor/SKILL.md +17 -0
  246. package/templates/skills/dev/research/SKILL.md +14 -0
  247. package/templates/skills/dev/review/SKILL.md +18 -0
  248. package/templates/skills/dev/security-audit/SKILL.md +17 -0
  249. package/templates/skills/frameworks/angular/SKILL.md +46 -46
  250. package/templates/skills/frameworks/django/SKILL.md +93 -93
  251. package/templates/skills/frameworks/electron/SKILL.md +157 -157
  252. package/templates/skills/frameworks/flask/SKILL.md +48 -48
  253. package/templates/skills/frameworks/flutter/SKILL.md +65 -65
  254. package/templates/skills/frameworks/jquery/SKILL.md +42 -42
  255. package/templates/skills/frameworks/laravel/SKILL.md +48 -48
  256. package/templates/skills/frameworks/nestjs/SKILL.md +53 -53
  257. package/templates/skills/frameworks/nextjs/SKILL.md +137 -137
  258. package/templates/skills/frameworks/nuxt/SKILL.md +50 -50
  259. package/templates/skills/frameworks/rails/SKILL.md +76 -76
  260. package/templates/skills/frameworks/react/SKILL.md +48 -48
  261. package/templates/skills/frameworks/react-native/SKILL.md +57 -57
  262. package/templates/skills/frameworks/spring/SKILL.md +49 -49
  263. package/templates/skills/frameworks/symfony/SKILL.md +46 -46
  264. package/templates/skills/frameworks/vue/SKILL.md +46 -46
  265. package/templates/skills/frameworks/zend/SKILL.md +45 -45
  266. package/templates/skills/ides/copilot/SKILL.md +47 -47
  267. package/templates/skills/ides/cursor/SKILL.md +53 -53
  268. package/templates/skills/ides/jetbrains-ai/SKILL.md +45 -45
  269. package/templates/skills/ides/replit/SKILL.md +46 -46
  270. package/templates/skills/ides/tabnine/SKILL.md +39 -39
  271. package/templates/skills/ides/vscode/SKILL.md +50 -50
  272. package/templates/skills/ides/windsurf/SKILL.md +46 -46
  273. package/templates/skills/ides/zed/SKILL.md +42 -42
  274. package/templates/skills/languages/c/SKILL.md +343 -343
  275. package/templates/skills/languages/cpp/SKILL.md +753 -753
  276. package/templates/skills/languages/csharp/SKILL.md +427 -427
  277. package/templates/skills/languages/elixir/SKILL.md +464 -464
  278. package/templates/skills/languages/erlang/SKILL.md +371 -371
  279. package/templates/skills/languages/go/SKILL.md +655 -655
  280. package/templates/skills/languages/haskell/SKILL.md +187 -187
  281. package/templates/skills/languages/java/SKILL.md +617 -617
  282. package/templates/skills/languages/javascript/SKILL.md +641 -641
  283. package/templates/skills/languages/julia/SKILL.md +107 -107
  284. package/templates/skills/languages/kotlin/SKILL.md +521 -521
  285. package/templates/skills/languages/lisp/SKILL.md +110 -110
  286. package/templates/skills/languages/lua/SKILL.md +84 -84
  287. package/templates/skills/languages/objectivec/SKILL.md +100 -100
  288. package/templates/skills/languages/php/SKILL.md +426 -426
  289. package/templates/skills/languages/python/SKILL.md +692 -692
  290. package/templates/skills/languages/ruby/SKILL.md +431 -431
  291. package/templates/skills/languages/rust/SKILL.md +487 -487
  292. package/templates/skills/languages/sas/SKILL.md +83 -83
  293. package/templates/skills/languages/scala/SKILL.md +358 -358
  294. package/templates/skills/languages/solidity/SKILL.md +590 -590
  295. package/templates/skills/languages/sql/SKILL.md +147 -147
  296. package/templates/skills/languages/swift/SKILL.md +476 -476
  297. package/templates/skills/languages/typescript/SKILL.md +302 -302
  298. package/templates/skills/languages/zig/SKILL.md +275 -275
  299. package/templates/skills/modules/atlassian/SKILL.md +265 -265
  300. package/templates/skills/modules/context7/SKILL.md +64 -64
  301. package/templates/skills/modules/figma/SKILL.md +277 -277
  302. package/templates/skills/modules/github-mcp/SKILL.md +74 -74
  303. package/templates/skills/modules/grafana/SKILL.md +338 -338
  304. package/templates/skills/modules/memory/SKILL.md +73 -73
  305. package/templates/skills/modules/notion/SKILL.md +257 -257
  306. package/templates/skills/modules/playwright/SKILL.md +100 -100
  307. package/templates/skills/modules/rulebook-mcp/SKILL.md +166 -166
  308. package/templates/skills/modules/serena/SKILL.md +347 -347
  309. package/templates/skills/modules/supabase/SKILL.md +233 -233
  310. package/templates/skills/modules/synap/SKILL.md +79 -79
  311. package/templates/skills/modules/vectorizer/SKILL.md +73 -73
  312. package/templates/skills/services/azure-blob/SKILL.md +194 -194
  313. package/templates/skills/services/cassandra/SKILL.md +249 -249
  314. package/templates/skills/services/dynamodb/SKILL.md +318 -318
  315. package/templates/skills/services/elasticsearch/SKILL.md +357 -357
  316. package/templates/skills/services/gcs/SKILL.md +188 -188
  317. package/templates/skills/services/influxdb/SKILL.md +275 -275
  318. package/templates/skills/services/kafka/SKILL.md +351 -351
  319. package/templates/skills/services/mariadb/SKILL.md +193 -193
  320. package/templates/skills/services/memcached/SKILL.md +252 -252
  321. package/templates/skills/services/minio/SKILL.md +211 -211
  322. package/templates/skills/services/mongodb/SKILL.md +278 -278
  323. package/templates/skills/services/mysql/SKILL.md +368 -368
  324. package/templates/skills/services/neo4j/SKILL.md +257 -257
  325. package/templates/skills/services/oracle/SKILL.md +300 -300
  326. package/templates/skills/services/postgresql/SKILL.md +336 -336
  327. package/templates/skills/services/rabbitmq/SKILL.md +296 -296
  328. package/templates/skills/services/redis/SKILL.md +302 -302
  329. package/templates/skills/services/s3/SKILL.md +308 -308
  330. package/templates/skills/services/sqlite/SKILL.md +304 -304
  331. package/templates/skills/services/sqlserver/SKILL.md +304 -304
  332. package/templates/skills/workflows/ralph/SKILL.md +309 -309
  333. package/templates/skills/workflows/ralph/install.sh +87 -87
  334. package/templates/skills/workflows/ralph/manifest.json +158 -158
@@ -1,753 +1,753 @@
1
- ---
2
- name: "C++"
3
- description: "Execute these commands after EVERY implementation (see AGENT_AUTOMATION module for full workflow)."
4
- version: "1.0.0"
5
- category: "languages"
6
- author: "Rulebook"
7
- tags: ["languages", "language"]
8
- dependencies: []
9
- conflicts: []
10
- ---
11
- <!-- CPP:START -->
12
- # C/C++ Project Rules
13
-
14
- ## Agent Automation Commands
15
-
16
- **CRITICAL**: Execute these commands after EVERY implementation (see AGENT_AUTOMATION module for full workflow).
17
-
18
- ```bash
19
- # Complete quality check sequence:
20
- clang-format --dry-run --Werror src/**/*.cpp # Format check
21
- clang-tidy src/**/*.cpp # Linting
22
- make test # All tests (100% pass)
23
- make # Build verification
24
-
25
- # Additional checks:
26
- cppcheck --enable=all src/ # Static analysis
27
- valgrind --leak-check=full ./build/test # Memory check
28
- ```
29
-
30
- ## C/C++ Configuration
31
-
32
- **CRITICAL**: Use C++20 or C++23 with modern CMake.
33
-
34
- - **C++ Standard**: C++20 or C++23
35
- - **CMake**: 3.25+
36
- - **Compiler**: GCC 11+, Clang 15+, or MSVC 19.30+
37
- - **Build System**: CMake (recommended) or Meson
38
- - **Package Manager**: Conan or vcpkg
39
-
40
- ### CMakeLists.txt Requirements
41
-
42
- ```cmake
43
- cmake_minimum_required(VERSION 3.25)
44
- project(YourProject VERSION 1.0.0 LANGUAGES CXX)
45
-
46
- # C++ Standard
47
- set(CMAKE_CXX_STANDARD 20)
48
- set(CMAKE_CXX_STANDARD_REQUIRED ON)
49
- set(CMAKE_CXX_EXTENSIONS OFF)
50
-
51
- # Compiler warnings
52
- if(MSVC)
53
- add_compile_options(/W4 /WX)
54
- else()
55
- add_compile_options(-Wall -Wextra -Wpedantic -Werror)
56
- endif()
57
-
58
- # Export compile commands for tooling
59
- set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
60
-
61
- # Project options
62
- option(BUILD_TESTING "Build tests" ON)
63
- option(BUILD_DOCS "Build documentation" ON)
64
- option(ENABLE_SANITIZERS "Enable sanitizers" ON)
65
-
66
- # Dependencies (using FetchContent or find_package)
67
- include(FetchContent)
68
-
69
- FetchContent_Declare(
70
- googletest
71
- GIT_REPOSITORY https://github.com/google/googletest.git
72
- GIT_TAG v1.14.0
73
- )
74
- FetchContent_MakeAvailable(googletest)
75
-
76
- # Library
77
- add_library(${PROJECT_NAME}
78
- src/your_module.cpp
79
- src/your_module.hpp
80
- )
81
-
82
- target_include_directories(${PROJECT_NAME}
83
- PUBLIC
84
- $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
85
- $<INSTALL_INTERFACE:include>
86
- PRIVATE
87
- ${CMAKE_CURRENT_SOURCE_DIR}/src
88
- )
89
-
90
- # Enable sanitizers in debug
91
- if(ENABLE_SANITIZERS AND CMAKE_BUILD_TYPE MATCHES Debug)
92
- target_compile_options(${PROJECT_NAME} PRIVATE
93
- -fsanitize=address
94
- -fsanitize=undefined
95
- -fno-omit-frame-pointer
96
- )
97
- target_link_options(${PROJECT_NAME} PRIVATE
98
- -fsanitize=address
99
- -fsanitize=undefined
100
- )
101
- endif()
102
-
103
- # Tests
104
- if(BUILD_TESTING)
105
- enable_testing()
106
- add_subdirectory(tests)
107
- endif()
108
-
109
- # Installation
110
- install(TARGETS ${PROJECT_NAME}
111
- EXPORT ${PROJECT_NAME}Targets
112
- LIBRARY DESTINATION lib
113
- ARCHIVE DESTINATION lib
114
- RUNTIME DESTINATION bin
115
- INCLUDES DESTINATION include
116
- )
117
- ```
118
-
119
- ## Code Quality Standards
120
-
121
- ### Mandatory Quality Checks
122
-
123
- **CRITICAL**: After implementing ANY feature, you MUST run these commands in order.
124
-
125
- **IMPORTANT**: These commands MUST match your GitHub Actions workflows to prevent CI/CD failures!
126
-
127
- ```bash
128
- # Pre-Commit Checklist (MUST match .github/workflows/*.yml)
129
-
130
- # 1. Format check (matches workflow - use --dry-run, not -i!)
131
- clang-format --dry-run --Werror src/**/*.{cpp,hpp} tests/**/*.{cpp,hpp}
132
-
133
- # 2. Static analysis (matches workflow)
134
- clang-tidy src/**/*.cpp -- -std=c++20
135
-
136
- # 3. Build (MUST pass with no warnings - matches workflow)
137
- cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-Werror"
138
- cmake --build build
139
-
140
- # 4. Run all tests (MUST pass 100% - matches workflow)
141
- ctest --test-dir build --output-on-failure
142
-
143
- # 5. Check with sanitizers (matches workflow)
144
- cmake -B build-asan -DENABLE_SANITIZERS=ON
145
- cmake --build build-asan
146
- ctest --test-dir build-asan
147
-
148
- # 6. Check coverage (matches workflow)
149
- cmake -B build-cov -DCMAKE_BUILD_TYPE=Coverage
150
- cmake --build build-cov
151
- ctest --test-dir build-cov
152
- gcov build-cov/CMakeFiles/YourProject.dir/src/*.gcno
153
-
154
- # If ANY fails: ❌ DO NOT COMMIT - Fix first!
155
- ```
156
-
157
- **Why This Matters:**
158
- - CI/CD failures happen when local commands differ from workflows
159
- - Example: Using `clang-format -i` locally but `--dry-run --Werror` in CI = failure
160
- - Example: Missing `-Werror` flag = warnings pass locally but fail in CI
161
- - Example: Skipping sanitizers locally = CI catches memory bugs you missed
162
- ```
163
-
164
- **If ANY of these fail, you MUST fix the issues before committing.**
165
-
166
- ### Code Style
167
-
168
- Use `.clang-format` for consistent formatting:
169
-
170
- ```yaml
171
- ---
172
- Language: Cpp
173
- BasedOnStyle: Google
174
- IndentWidth: 4
175
- ColumnLimit: 100
176
- UseTab: Never
177
- PointerAlignment: Left
178
- ReferenceAlignment: Left
179
- DerivePointerAlignment: false
180
-
181
- # Includes
182
- SortIncludes: CaseInsensitive
183
- IncludeBlocks: Regroup
184
- IncludeCategories:
185
- - Regex: '^<.*\.h>'
186
- Priority: 1
187
- - Regex: '^<.*>'
188
- Priority: 2
189
- - Regex: '.*'
190
- Priority: 3
191
-
192
- # Braces
193
- BreakBeforeBraces: Attach
194
- AllowShortFunctionsOnASingleLine: Inline
195
- AllowShortIfStatementsOnASingleLine: Never
196
-
197
- # Spacing
198
- SpaceAfterCStyleCast: false
199
- SpaceAfterTemplateKeyword: true
200
- SpaceBeforeParens: ControlStatements
201
-
202
- # Modern C++
203
- Standard: c++20
204
- ```
205
-
206
- ### Static Analysis
207
-
208
- Use `.clang-tidy` for code analysis:
209
-
210
- ```yaml
211
- ---
212
- Checks: >
213
- *,
214
- -abseil-*,
215
- -altera-*,
216
- -android-*,
217
- -fuchsia-*,
218
- -google-*,
219
- -llvm-*,
220
- -llvmlibc-*,
221
- -zircon-*,
222
- -readability-identifier-length,
223
- -modernize-use-trailing-return-type
224
-
225
- CheckOptions:
226
- - key: readability-identifier-naming.NamespaceCase
227
- value: lower_case
228
- - key: readability-identifier-naming.ClassCase
229
- value: CamelCase
230
- - key: readability-identifier-naming.StructCase
231
- value: CamelCase
232
- - key: readability-identifier-naming.FunctionCase
233
- value: camelCase
234
- - key: readability-identifier-naming.VariableCase
235
- value: lower_case
236
- - key: readability-identifier-naming.ConstantCase
237
- value: UPPER_CASE
238
- - key: readability-identifier-naming.MemberCase
239
- value: lower_case_
240
- - key: readability-identifier-naming.PrivateMemberSuffix
241
- value: '_'
242
-
243
- WarningsAsErrors: '*'
244
- ```
245
-
246
- ### Testing
247
-
248
- - **Framework**: Google Test (recommended) or Catch2
249
- - **Location**: `tests/` directory
250
- - **Coverage**: gcov/lcov or llvm-cov
251
- - **Coverage Threshold**: 95%+
252
-
253
- Example test with Google Test:
254
-
255
- ```cpp
256
- #include <gtest/gtest.h>
257
- #include "your_module.hpp"
258
-
259
- namespace your_namespace::tests {
260
-
261
- class DataProcessorTest : public ::testing::Test {
262
- protected:
263
- void SetUp() override {
264
- processor = std::make_unique<DataProcessor>();
265
- }
266
-
267
- void TearDown() override {
268
- processor.reset();
269
- }
270
-
271
- std::unique_ptr<DataProcessor> processor;
272
- };
273
-
274
- TEST_F(DataProcessorTest, ProcessValidInput) {
275
- const std::string input = "hello";
276
- const auto result = processor->process(input);
277
-
278
- EXPECT_EQ(result, "HELLO");
279
- }
280
-
281
- TEST_F(DataProcessorTest, ProcessEmptyInputThrows) {
282
- EXPECT_THROW(
283
- processor->process(""),
284
- std::invalid_argument
285
- );
286
- }
287
-
288
- TEST_F(DataProcessorTest, ProcessLargeInput) {
289
- const std::string input(1000, 'a');
290
- const auto result = processor->process(input);
291
-
292
- ASSERT_EQ(result.size(), 1000);
293
- EXPECT_TRUE(std::all_of(result.begin(), result.end(),
294
- [](char c) { return std::isupper(c); }));
295
- }
296
-
297
- } // namespace your_namespace::tests
298
- ```
299
-
300
- ### Modern C++ Best Practices
301
-
302
- - Use RAII for resource management
303
- - Prefer `std::unique_ptr` and `std::shared_ptr` over raw pointers
304
- - Use `const` and `constexpr` liberally
305
- - Prefer `std::string_view` for read-only strings
306
- - Use range-based for loops
307
- - Use `auto` for type deduction when clear
308
- - Avoid manual memory management
309
-
310
- Example modern C++ code:
311
-
312
- ```cpp
313
- #pragma once
314
-
315
- #include <memory>
316
- #include <string>
317
- #include <string_view>
318
- #include <vector>
319
- #include <optional>
320
- #include <expected>
321
-
322
- namespace your_namespace {
323
-
324
- /// @brief Processes data with various transformations
325
- class DataProcessor {
326
- public:
327
- DataProcessor() = default;
328
- ~DataProcessor() = default;
329
-
330
- // Delete copy constructor and assignment
331
- DataProcessor(const DataProcessor&) = delete;
332
- DataProcessor& operator=(const DataProcessor&) = delete;
333
-
334
- // Default move constructor and assignment
335
- DataProcessor(DataProcessor&&) noexcept = default;
336
- DataProcessor& operator=(DataProcessor&&) noexcept = default;
337
-
338
- /// @brief Process input string to uppercase
339
- /// @param input The input string to process
340
- /// @return Processed string or error
341
- /// @throws std::invalid_argument if input is empty
342
- [[nodiscard]] std::string process(std::string_view input) const;
343
-
344
- /// @brief Find value in data
345
- /// @param data The data to search
346
- /// @param key The key to find
347
- /// @return Optional value if found
348
- [[nodiscard]] std::optional<std::string> findValue(
349
- const std::vector<std::pair<std::string, std::string>>& data,
350
- std::string_view key
351
- ) const;
352
-
353
- /// @brief Process multiple items
354
- /// @param items Items to process
355
- /// @return Processed items
356
- [[nodiscard]] std::vector<std::string> processMany(
357
- const std::vector<std::string>& items
358
- ) const;
359
-
360
- private:
361
- mutable std::mutex mutex_;
362
- };
363
-
364
- } // namespace your_namespace
365
- ```
366
-
367
- Implementation:
368
-
369
- ```cpp
370
- #include "your_module.hpp"
371
- #include <algorithm>
372
- #include <stdexcept>
373
- #include <cctype>
374
-
375
- namespace your_namespace {
376
-
377
- std::string DataProcessor::process(std::string_view input) const {
378
- if (input.empty()) {
379
- throw std::invalid_argument("Input cannot be empty");
380
- }
381
-
382
- std::string result;
383
- result.reserve(input.size());
384
-
385
- std::transform(input.begin(), input.end(),
386
- std::back_inserter(result),
387
- [](unsigned char c) { return std::toupper(c); });
388
-
389
- return result;
390
- }
391
-
392
- std::optional<std::string> DataProcessor::findValue(
393
- const std::vector<std::pair<std::string, std::string>>& data,
394
- std::string_view key
395
- ) const {
396
- auto it = std::find_if(data.begin(), data.end(),
397
- [key](const auto& pair) { return pair.first == key; });
398
-
399
- if (it != data.end()) {
400
- return it->second;
401
- }
402
-
403
- return std::nullopt;
404
- }
405
-
406
- std::vector<std::string> DataProcessor::processMany(
407
- const std::vector<std::string>& items
408
- ) const {
409
- std::vector<std::string> results;
410
- results.reserve(items.size());
411
-
412
- std::transform(items.begin(), items.end(),
413
- std::back_inserter(results),
414
- [this](const auto& item) { return process(item); });
415
-
416
- return results;
417
- }
418
-
419
- } // namespace your_namespace
420
- ```
421
-
422
- ## Documentation
423
-
424
- Use Doxygen for API documentation:
425
-
426
- ```cpp
427
- /**
428
- * @file your_module.hpp
429
- * @brief Data processing utilities
430
- * @author Your Name
431
- * @date 2024-10-23
432
- */
433
-
434
- /**
435
- * @class DataProcessor
436
- * @brief Processes various data formats
437
- *
438
- * This class provides thread-safe data processing capabilities.
439
- * All methods are const-correct and exception-safe.
440
- *
441
- * @example
442
- * @code{.cpp}
443
- * DataProcessor processor;
444
- * auto result = processor.process("hello");
445
- * assert(result == "HELLO");
446
- * @endcode
447
- */
448
- ```
449
-
450
- ### Doxyfile Configuration:
451
-
452
- ```
453
- PROJECT_NAME = "Your Project"
454
- PROJECT_NUMBER = 1.0.0
455
- OUTPUT_DIRECTORY = docs
456
- GENERATE_HTML = YES
457
- GENERATE_LATEX = NO
458
- EXTRACT_ALL = YES
459
- EXTRACT_PRIVATE = NO
460
- EXTRACT_STATIC = YES
461
- SOURCE_BROWSER = YES
462
- INLINE_SOURCES = YES
463
- RECURSIVE = YES
464
- ```
465
-
466
- ## Project Structure
467
-
468
- ```
469
- project/
470
- ├── CMakeLists.txt # CMake configuration
471
- ├── .clang-format # Code formatting rules
472
- ├── .clang-tidy # Static analysis rules
473
- ├── Doxyfile # Documentation config
474
- ├── conanfile.txt # Conan dependencies (optional)
475
- ├── vcpkg.json # vcpkg dependencies (optional)
476
- ├── README.md # Project overview
477
- ├── CHANGELOG.md # Version history
478
- ├── LICENSE # Project license
479
- ├── include/
480
- │ └── your_project/
481
- │ └── your_module.hpp # Public headers
482
- ├── src/
483
- │ └── your_module.cpp # Implementation
484
- ├── tests/
485
- │ ├── CMakeLists.txt
486
- │ └── test_your_module.cpp
487
- ├── benchmarks/ # Performance benchmarks
488
- │ └── benchmark_main.cpp
489
- └── docs/ # Project documentation
490
- ```
491
-
492
- ## Memory Safety
493
-
494
- - Use RAII for all resource management
495
- - Prefer stack allocation over heap
496
- - Use smart pointers for heap allocation
497
- - Never use raw `new`/`delete`
498
- - Use containers instead of manual arrays
499
- - Check all pointer dereferences
500
-
501
- Example:
502
-
503
- ```cpp
504
- // Good: RAII with smart pointers
505
- class FileManager {
506
- public:
507
- explicit FileManager(std::string_view filename)
508
- : file_(std::make_unique<std::ifstream>(filename.data())) {
509
- if (!file_->is_open()) {
510
- throw std::runtime_error("Failed to open file");
511
- }
512
- }
513
-
514
- // RAII - file automatically closed
515
- ~FileManager() = default;
516
-
517
- [[nodiscard]] std::string readLine() {
518
- std::string line;
519
- if (std::getline(*file_, line)) {
520
- return line;
521
- }
522
- throw std::runtime_error("Failed to read line");
523
- }
524
-
525
- private:
526
- std::unique_ptr<std::ifstream> file_;
527
- };
528
-
529
- // Bad: Manual memory management
530
- class BadFileManager {
531
- public:
532
- BadFileManager(const char* filename) {
533
- file = new std::ifstream(filename); // ❌ Manual allocation
534
- }
535
-
536
- ~BadFileManager() {
537
- delete file; // ❌ Manual deletion (error-prone)
538
- }
539
-
540
- private:
541
- std::ifstream* file; // ❌ Raw pointer
542
- };
543
- ```
544
-
545
- ## Error Handling
546
-
547
- - Use exceptions for exceptional cases
548
- - Use `std::expected` (C++23) or `std::optional` for expected failures
549
- - Create custom exception classes
550
- - Document all exceptions with `@throws`
551
-
552
- Example:
553
-
554
- ```cpp
555
- #include <stdexcept>
556
- #include <optional>
557
-
558
- namespace your_namespace {
559
-
560
- class ValidationError : public std::runtime_error {
561
- public:
562
- explicit ValidationError(std::string_view message, std::string_view field)
563
- : std::runtime_error(std::string(message))
564
- , field_(field) {}
565
-
566
- [[nodiscard]] const std::string& field() const noexcept { return field_; }
567
-
568
- private:
569
- std::string field_;
570
- };
571
-
572
- class DataValidator {
573
- public:
574
- /// @throws ValidationError if data is invalid
575
- void validate(std::string_view data) const {
576
- if (data.empty()) {
577
- throw ValidationError("Data cannot be empty", "data");
578
- }
579
- }
580
-
581
- /// @return Optional value if valid, nullopt otherwise
582
- [[nodiscard]] std::optional<int> tryParse(std::string_view str) const noexcept {
583
- try {
584
- return std::stoi(std::string(str));
585
- } catch (...) {
586
- return std::nullopt;
587
- }
588
- }
589
- };
590
-
591
- } // namespace your_namespace
592
- ```
593
-
594
- ## Threading & Concurrency
595
-
596
- - Use `std::thread`, `std::jthread` (C++20), or `std::async`
597
- - Use `std::mutex`, `std::shared_mutex` for synchronization
598
- - Prefer `std::atomic` for simple shared state
599
- - Use `std::lock_guard` or `std::scoped_lock`
600
-
601
- Example:
602
-
603
- ```cpp
604
- #include <mutex>
605
- #include <shared_mutex>
606
- #include <thread>
607
- #include <atomic>
608
-
609
- class ThreadSafeCounter {
610
- public:
611
- void increment() {
612
- std::scoped_lock lock(mutex_);
613
- ++counter_;
614
- }
615
-
616
- [[nodiscard]] int get() const {
617
- std::shared_lock lock(mutex_);
618
- return counter_;
619
- }
620
-
621
- private:
622
- mutable std::shared_mutex mutex_;
623
- int counter_{0};
624
- };
625
-
626
- // For simple atomics
627
- class AtomicCounter {
628
- public:
629
- void increment() noexcept {
630
- counter_.fetch_add(1, std::memory_order_relaxed);
631
- }
632
-
633
- [[nodiscard]] int get() const noexcept {
634
- return counter_.load(std::memory_order_relaxed);
635
- }
636
-
637
- private:
638
- std::atomic<int> counter_{0};
639
- };
640
- ```
641
-
642
- ## CI/CD Requirements
643
-
644
- Must include GitHub Actions workflows for:
645
-
646
- 1. **Testing** (`cpp-test.yml`):
647
- - Test on ubuntu-latest, windows-latest, macos-latest
648
- - Test with GCC, Clang, MSVC
649
- - Upload coverage reports
650
-
651
- 2. **Linting** (`cpp-lint.yml`):
652
- - clang-format check
653
- - clang-tidy analysis
654
- - cppcheck static analysis
655
-
656
- ## Package Publication
657
-
658
- ### Publishing C/C++ Libraries
659
-
660
- **Options:**
661
- 1. **Conan Center**: Public Conan repository
662
- 2. **vcpkg**: Microsoft's package manager
663
- 3. **GitHub Releases**: Binary releases
664
- 4. **Header-only**: Single-file distribution
665
-
666
- ### Conan Publication
667
-
668
- **conanfile.py:**
669
-
670
- ```python
671
- from conan import ConanFile
672
- from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout
673
-
674
- class YourProjectConan(ConanFile):
675
- name = "your-project"
676
- version = "1.0.0"
677
- license = "MIT"
678
- author = "Your Name your.email@example.com"
679
- url = "https://github.com/your-org/your-project"
680
- description = "Short description"
681
- topics = ("cpp", "library")
682
- settings = "os", "compiler", "build_type", "arch"
683
-
684
- options = {
685
- "shared": [True, False],
686
- "fPIC": [True, False]
687
- }
688
- default_options = {
689
- "shared": False,
690
- "fPIC": True
691
- }
692
-
693
- exports_sources = "CMakeLists.txt", "src/*", "include/*"
694
-
695
- def layout(self):
696
- cmake_layout(self)
697
-
698
- def generate(self):
699
- tc = CMakeToolchain(self)
700
- tc.generate()
701
-
702
- def build(self):
703
- cmake = CMake(self)
704
- cmake.configure()
705
- cmake.build()
706
-
707
- def package(self):
708
- cmake = CMake(self)
709
- cmake.install()
710
-
711
- def package_info(self):
712
- self.cpp_info.libs = ["your-project"]
713
- ```
714
-
715
- ### vcpkg Publication
716
-
717
- **vcpkg.json:**
718
-
719
- ```json
720
- {
721
- "name": "your-project",
722
- "version": "1.0.0",
723
- "description": "Short description",
724
- "homepage": "https://github.com/your-org/your-project",
725
- "license": "MIT",
726
- "dependencies": [
727
- {
728
- "name": "vcpkg-cmake",
729
- "host": true
730
- },
731
- {
732
- "name": "vcpkg-cmake-config",
733
- "host": true
734
- }
735
- ]
736
- }
737
- ```
738
-
739
- ### Publishing Checklist:
740
-
741
- - ✅ All tests passing with sanitizers
742
- - ✅ clang-tidy clean
743
- - ✅ clang-format applied
744
- - ✅ Documentation generated
745
- - ✅ Version updated in CMakeLists.txt
746
- - ✅ CHANGELOG.md updated
747
- - ✅ README.md with build instructions
748
- - ✅ LICENSE file present
749
- - ✅ CMake config for find_package support
750
- - ✅ Conan recipe or vcpkg portfile
751
-
752
- <!-- CPP:END -->
753
-
1
+ ---
2
+ name: "C++"
3
+ description: "Execute these commands after EVERY implementation (see AGENT_AUTOMATION module for full workflow)."
4
+ version: "1.0.0"
5
+ category: "languages"
6
+ author: "Rulebook"
7
+ tags: ["languages", "language"]
8
+ dependencies: []
9
+ conflicts: []
10
+ ---
11
+ <!-- CPP:START -->
12
+ # C/C++ Project Rules
13
+
14
+ ## Agent Automation Commands
15
+
16
+ **CRITICAL**: Execute these commands after EVERY implementation (see AGENT_AUTOMATION module for full workflow).
17
+
18
+ ```bash
19
+ # Complete quality check sequence:
20
+ clang-format --dry-run --Werror src/**/*.cpp # Format check
21
+ clang-tidy src/**/*.cpp # Linting
22
+ make test # All tests (100% pass)
23
+ make # Build verification
24
+
25
+ # Additional checks:
26
+ cppcheck --enable=all src/ # Static analysis
27
+ valgrind --leak-check=full ./build/test # Memory check
28
+ ```
29
+
30
+ ## C/C++ Configuration
31
+
32
+ **CRITICAL**: Use C++20 or C++23 with modern CMake.
33
+
34
+ - **C++ Standard**: C++20 or C++23
35
+ - **CMake**: 3.25+
36
+ - **Compiler**: GCC 11+, Clang 15+, or MSVC 19.30+
37
+ - **Build System**: CMake (recommended) or Meson
38
+ - **Package Manager**: Conan or vcpkg
39
+
40
+ ### CMakeLists.txt Requirements
41
+
42
+ ```cmake
43
+ cmake_minimum_required(VERSION 3.25)
44
+ project(YourProject VERSION 1.0.0 LANGUAGES CXX)
45
+
46
+ # C++ Standard
47
+ set(CMAKE_CXX_STANDARD 20)
48
+ set(CMAKE_CXX_STANDARD_REQUIRED ON)
49
+ set(CMAKE_CXX_EXTENSIONS OFF)
50
+
51
+ # Compiler warnings
52
+ if(MSVC)
53
+ add_compile_options(/W4 /WX)
54
+ else()
55
+ add_compile_options(-Wall -Wextra -Wpedantic -Werror)
56
+ endif()
57
+
58
+ # Export compile commands for tooling
59
+ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
60
+
61
+ # Project options
62
+ option(BUILD_TESTING "Build tests" ON)
63
+ option(BUILD_DOCS "Build documentation" ON)
64
+ option(ENABLE_SANITIZERS "Enable sanitizers" ON)
65
+
66
+ # Dependencies (using FetchContent or find_package)
67
+ include(FetchContent)
68
+
69
+ FetchContent_Declare(
70
+ googletest
71
+ GIT_REPOSITORY https://github.com/google/googletest.git
72
+ GIT_TAG v1.14.0
73
+ )
74
+ FetchContent_MakeAvailable(googletest)
75
+
76
+ # Library
77
+ add_library(${PROJECT_NAME}
78
+ src/your_module.cpp
79
+ src/your_module.hpp
80
+ )
81
+
82
+ target_include_directories(${PROJECT_NAME}
83
+ PUBLIC
84
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
85
+ $<INSTALL_INTERFACE:include>
86
+ PRIVATE
87
+ ${CMAKE_CURRENT_SOURCE_DIR}/src
88
+ )
89
+
90
+ # Enable sanitizers in debug
91
+ if(ENABLE_SANITIZERS AND CMAKE_BUILD_TYPE MATCHES Debug)
92
+ target_compile_options(${PROJECT_NAME} PRIVATE
93
+ -fsanitize=address
94
+ -fsanitize=undefined
95
+ -fno-omit-frame-pointer
96
+ )
97
+ target_link_options(${PROJECT_NAME} PRIVATE
98
+ -fsanitize=address
99
+ -fsanitize=undefined
100
+ )
101
+ endif()
102
+
103
+ # Tests
104
+ if(BUILD_TESTING)
105
+ enable_testing()
106
+ add_subdirectory(tests)
107
+ endif()
108
+
109
+ # Installation
110
+ install(TARGETS ${PROJECT_NAME}
111
+ EXPORT ${PROJECT_NAME}Targets
112
+ LIBRARY DESTINATION lib
113
+ ARCHIVE DESTINATION lib
114
+ RUNTIME DESTINATION bin
115
+ INCLUDES DESTINATION include
116
+ )
117
+ ```
118
+
119
+ ## Code Quality Standards
120
+
121
+ ### Mandatory Quality Checks
122
+
123
+ **CRITICAL**: After implementing ANY feature, you MUST run these commands in order.
124
+
125
+ **IMPORTANT**: These commands MUST match your GitHub Actions workflows to prevent CI/CD failures!
126
+
127
+ ```bash
128
+ # Pre-Commit Checklist (MUST match .github/workflows/*.yml)
129
+
130
+ # 1. Format check (matches workflow - use --dry-run, not -i!)
131
+ clang-format --dry-run --Werror src/**/*.{cpp,hpp} tests/**/*.{cpp,hpp}
132
+
133
+ # 2. Static analysis (matches workflow)
134
+ clang-tidy src/**/*.cpp -- -std=c++20
135
+
136
+ # 3. Build (MUST pass with no warnings - matches workflow)
137
+ cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-Werror"
138
+ cmake --build build
139
+
140
+ # 4. Run all tests (MUST pass 100% - matches workflow)
141
+ ctest --test-dir build --output-on-failure
142
+
143
+ # 5. Check with sanitizers (matches workflow)
144
+ cmake -B build-asan -DENABLE_SANITIZERS=ON
145
+ cmake --build build-asan
146
+ ctest --test-dir build-asan
147
+
148
+ # 6. Check coverage (matches workflow)
149
+ cmake -B build-cov -DCMAKE_BUILD_TYPE=Coverage
150
+ cmake --build build-cov
151
+ ctest --test-dir build-cov
152
+ gcov build-cov/CMakeFiles/YourProject.dir/src/*.gcno
153
+
154
+ # If ANY fails: ❌ DO NOT COMMIT - Fix first!
155
+ ```
156
+
157
+ **Why This Matters:**
158
+ - CI/CD failures happen when local commands differ from workflows
159
+ - Example: Using `clang-format -i` locally but `--dry-run --Werror` in CI = failure
160
+ - Example: Missing `-Werror` flag = warnings pass locally but fail in CI
161
+ - Example: Skipping sanitizers locally = CI catches memory bugs you missed
162
+ ```
163
+
164
+ **If ANY of these fail, you MUST fix the issues before committing.**
165
+
166
+ ### Code Style
167
+
168
+ Use `.clang-format` for consistent formatting:
169
+
170
+ ```yaml
171
+ ---
172
+ Language: Cpp
173
+ BasedOnStyle: Google
174
+ IndentWidth: 4
175
+ ColumnLimit: 100
176
+ UseTab: Never
177
+ PointerAlignment: Left
178
+ ReferenceAlignment: Left
179
+ DerivePointerAlignment: false
180
+
181
+ # Includes
182
+ SortIncludes: CaseInsensitive
183
+ IncludeBlocks: Regroup
184
+ IncludeCategories:
185
+ - Regex: '^<.*\.h>'
186
+ Priority: 1
187
+ - Regex: '^<.*>'
188
+ Priority: 2
189
+ - Regex: '.*'
190
+ Priority: 3
191
+
192
+ # Braces
193
+ BreakBeforeBraces: Attach
194
+ AllowShortFunctionsOnASingleLine: Inline
195
+ AllowShortIfStatementsOnASingleLine: Never
196
+
197
+ # Spacing
198
+ SpaceAfterCStyleCast: false
199
+ SpaceAfterTemplateKeyword: true
200
+ SpaceBeforeParens: ControlStatements
201
+
202
+ # Modern C++
203
+ Standard: c++20
204
+ ```
205
+
206
+ ### Static Analysis
207
+
208
+ Use `.clang-tidy` for code analysis:
209
+
210
+ ```yaml
211
+ ---
212
+ Checks: >
213
+ *,
214
+ -abseil-*,
215
+ -altera-*,
216
+ -android-*,
217
+ -fuchsia-*,
218
+ -google-*,
219
+ -llvm-*,
220
+ -llvmlibc-*,
221
+ -zircon-*,
222
+ -readability-identifier-length,
223
+ -modernize-use-trailing-return-type
224
+
225
+ CheckOptions:
226
+ - key: readability-identifier-naming.NamespaceCase
227
+ value: lower_case
228
+ - key: readability-identifier-naming.ClassCase
229
+ value: CamelCase
230
+ - key: readability-identifier-naming.StructCase
231
+ value: CamelCase
232
+ - key: readability-identifier-naming.FunctionCase
233
+ value: camelCase
234
+ - key: readability-identifier-naming.VariableCase
235
+ value: lower_case
236
+ - key: readability-identifier-naming.ConstantCase
237
+ value: UPPER_CASE
238
+ - key: readability-identifier-naming.MemberCase
239
+ value: lower_case_
240
+ - key: readability-identifier-naming.PrivateMemberSuffix
241
+ value: '_'
242
+
243
+ WarningsAsErrors: '*'
244
+ ```
245
+
246
+ ### Testing
247
+
248
+ - **Framework**: Google Test (recommended) or Catch2
249
+ - **Location**: `tests/` directory
250
+ - **Coverage**: gcov/lcov or llvm-cov
251
+ - **Coverage Threshold**: 95%+
252
+
253
+ Example test with Google Test:
254
+
255
+ ```cpp
256
+ #include <gtest/gtest.h>
257
+ #include "your_module.hpp"
258
+
259
+ namespace your_namespace::tests {
260
+
261
+ class DataProcessorTest : public ::testing::Test {
262
+ protected:
263
+ void SetUp() override {
264
+ processor = std::make_unique<DataProcessor>();
265
+ }
266
+
267
+ void TearDown() override {
268
+ processor.reset();
269
+ }
270
+
271
+ std::unique_ptr<DataProcessor> processor;
272
+ };
273
+
274
+ TEST_F(DataProcessorTest, ProcessValidInput) {
275
+ const std::string input = "hello";
276
+ const auto result = processor->process(input);
277
+
278
+ EXPECT_EQ(result, "HELLO");
279
+ }
280
+
281
+ TEST_F(DataProcessorTest, ProcessEmptyInputThrows) {
282
+ EXPECT_THROW(
283
+ processor->process(""),
284
+ std::invalid_argument
285
+ );
286
+ }
287
+
288
+ TEST_F(DataProcessorTest, ProcessLargeInput) {
289
+ const std::string input(1000, 'a');
290
+ const auto result = processor->process(input);
291
+
292
+ ASSERT_EQ(result.size(), 1000);
293
+ EXPECT_TRUE(std::all_of(result.begin(), result.end(),
294
+ [](char c) { return std::isupper(c); }));
295
+ }
296
+
297
+ } // namespace your_namespace::tests
298
+ ```
299
+
300
+ ### Modern C++ Best Practices
301
+
302
+ - Use RAII for resource management
303
+ - Prefer `std::unique_ptr` and `std::shared_ptr` over raw pointers
304
+ - Use `const` and `constexpr` liberally
305
+ - Prefer `std::string_view` for read-only strings
306
+ - Use range-based for loops
307
+ - Use `auto` for type deduction when clear
308
+ - Avoid manual memory management
309
+
310
+ Example modern C++ code:
311
+
312
+ ```cpp
313
+ #pragma once
314
+
315
+ #include <memory>
316
+ #include <string>
317
+ #include <string_view>
318
+ #include <vector>
319
+ #include <optional>
320
+ #include <expected>
321
+
322
+ namespace your_namespace {
323
+
324
+ /// @brief Processes data with various transformations
325
+ class DataProcessor {
326
+ public:
327
+ DataProcessor() = default;
328
+ ~DataProcessor() = default;
329
+
330
+ // Delete copy constructor and assignment
331
+ DataProcessor(const DataProcessor&) = delete;
332
+ DataProcessor& operator=(const DataProcessor&) = delete;
333
+
334
+ // Default move constructor and assignment
335
+ DataProcessor(DataProcessor&&) noexcept = default;
336
+ DataProcessor& operator=(DataProcessor&&) noexcept = default;
337
+
338
+ /// @brief Process input string to uppercase
339
+ /// @param input The input string to process
340
+ /// @return Processed string or error
341
+ /// @throws std::invalid_argument if input is empty
342
+ [[nodiscard]] std::string process(std::string_view input) const;
343
+
344
+ /// @brief Find value in data
345
+ /// @param data The data to search
346
+ /// @param key The key to find
347
+ /// @return Optional value if found
348
+ [[nodiscard]] std::optional<std::string> findValue(
349
+ const std::vector<std::pair<std::string, std::string>>& data,
350
+ std::string_view key
351
+ ) const;
352
+
353
+ /// @brief Process multiple items
354
+ /// @param items Items to process
355
+ /// @return Processed items
356
+ [[nodiscard]] std::vector<std::string> processMany(
357
+ const std::vector<std::string>& items
358
+ ) const;
359
+
360
+ private:
361
+ mutable std::mutex mutex_;
362
+ };
363
+
364
+ } // namespace your_namespace
365
+ ```
366
+
367
+ Implementation:
368
+
369
+ ```cpp
370
+ #include "your_module.hpp"
371
+ #include <algorithm>
372
+ #include <stdexcept>
373
+ #include <cctype>
374
+
375
+ namespace your_namespace {
376
+
377
+ std::string DataProcessor::process(std::string_view input) const {
378
+ if (input.empty()) {
379
+ throw std::invalid_argument("Input cannot be empty");
380
+ }
381
+
382
+ std::string result;
383
+ result.reserve(input.size());
384
+
385
+ std::transform(input.begin(), input.end(),
386
+ std::back_inserter(result),
387
+ [](unsigned char c) { return std::toupper(c); });
388
+
389
+ return result;
390
+ }
391
+
392
+ std::optional<std::string> DataProcessor::findValue(
393
+ const std::vector<std::pair<std::string, std::string>>& data,
394
+ std::string_view key
395
+ ) const {
396
+ auto it = std::find_if(data.begin(), data.end(),
397
+ [key](const auto& pair) { return pair.first == key; });
398
+
399
+ if (it != data.end()) {
400
+ return it->second;
401
+ }
402
+
403
+ return std::nullopt;
404
+ }
405
+
406
+ std::vector<std::string> DataProcessor::processMany(
407
+ const std::vector<std::string>& items
408
+ ) const {
409
+ std::vector<std::string> results;
410
+ results.reserve(items.size());
411
+
412
+ std::transform(items.begin(), items.end(),
413
+ std::back_inserter(results),
414
+ [this](const auto& item) { return process(item); });
415
+
416
+ return results;
417
+ }
418
+
419
+ } // namespace your_namespace
420
+ ```
421
+
422
+ ## Documentation
423
+
424
+ Use Doxygen for API documentation:
425
+
426
+ ```cpp
427
+ /**
428
+ * @file your_module.hpp
429
+ * @brief Data processing utilities
430
+ * @author Your Name
431
+ * @date 2024-10-23
432
+ */
433
+
434
+ /**
435
+ * @class DataProcessor
436
+ * @brief Processes various data formats
437
+ *
438
+ * This class provides thread-safe data processing capabilities.
439
+ * All methods are const-correct and exception-safe.
440
+ *
441
+ * @example
442
+ * @code{.cpp}
443
+ * DataProcessor processor;
444
+ * auto result = processor.process("hello");
445
+ * assert(result == "HELLO");
446
+ * @endcode
447
+ */
448
+ ```
449
+
450
+ ### Doxyfile Configuration:
451
+
452
+ ```
453
+ PROJECT_NAME = "Your Project"
454
+ PROJECT_NUMBER = 1.0.0
455
+ OUTPUT_DIRECTORY = docs
456
+ GENERATE_HTML = YES
457
+ GENERATE_LATEX = NO
458
+ EXTRACT_ALL = YES
459
+ EXTRACT_PRIVATE = NO
460
+ EXTRACT_STATIC = YES
461
+ SOURCE_BROWSER = YES
462
+ INLINE_SOURCES = YES
463
+ RECURSIVE = YES
464
+ ```
465
+
466
+ ## Project Structure
467
+
468
+ ```
469
+ project/
470
+ ├── CMakeLists.txt # CMake configuration
471
+ ├── .clang-format # Code formatting rules
472
+ ├── .clang-tidy # Static analysis rules
473
+ ├── Doxyfile # Documentation config
474
+ ├── conanfile.txt # Conan dependencies (optional)
475
+ ├── vcpkg.json # vcpkg dependencies (optional)
476
+ ├── README.md # Project overview
477
+ ├── CHANGELOG.md # Version history
478
+ ├── LICENSE # Project license
479
+ ├── include/
480
+ │ └── your_project/
481
+ │ └── your_module.hpp # Public headers
482
+ ├── src/
483
+ │ └── your_module.cpp # Implementation
484
+ ├── tests/
485
+ │ ├── CMakeLists.txt
486
+ │ └── test_your_module.cpp
487
+ ├── benchmarks/ # Performance benchmarks
488
+ │ └── benchmark_main.cpp
489
+ └── docs/ # Project documentation
490
+ ```
491
+
492
+ ## Memory Safety
493
+
494
+ - Use RAII for all resource management
495
+ - Prefer stack allocation over heap
496
+ - Use smart pointers for heap allocation
497
+ - Never use raw `new`/`delete`
498
+ - Use containers instead of manual arrays
499
+ - Check all pointer dereferences
500
+
501
+ Example:
502
+
503
+ ```cpp
504
+ // Good: RAII with smart pointers
505
+ class FileManager {
506
+ public:
507
+ explicit FileManager(std::string_view filename)
508
+ : file_(std::make_unique<std::ifstream>(filename.data())) {
509
+ if (!file_->is_open()) {
510
+ throw std::runtime_error("Failed to open file");
511
+ }
512
+ }
513
+
514
+ // RAII - file automatically closed
515
+ ~FileManager() = default;
516
+
517
+ [[nodiscard]] std::string readLine() {
518
+ std::string line;
519
+ if (std::getline(*file_, line)) {
520
+ return line;
521
+ }
522
+ throw std::runtime_error("Failed to read line");
523
+ }
524
+
525
+ private:
526
+ std::unique_ptr<std::ifstream> file_;
527
+ };
528
+
529
+ // Bad: Manual memory management
530
+ class BadFileManager {
531
+ public:
532
+ BadFileManager(const char* filename) {
533
+ file = new std::ifstream(filename); // ❌ Manual allocation
534
+ }
535
+
536
+ ~BadFileManager() {
537
+ delete file; // ❌ Manual deletion (error-prone)
538
+ }
539
+
540
+ private:
541
+ std::ifstream* file; // ❌ Raw pointer
542
+ };
543
+ ```
544
+
545
+ ## Error Handling
546
+
547
+ - Use exceptions for exceptional cases
548
+ - Use `std::expected` (C++23) or `std::optional` for expected failures
549
+ - Create custom exception classes
550
+ - Document all exceptions with `@throws`
551
+
552
+ Example:
553
+
554
+ ```cpp
555
+ #include <stdexcept>
556
+ #include <optional>
557
+
558
+ namespace your_namespace {
559
+
560
+ class ValidationError : public std::runtime_error {
561
+ public:
562
+ explicit ValidationError(std::string_view message, std::string_view field)
563
+ : std::runtime_error(std::string(message))
564
+ , field_(field) {}
565
+
566
+ [[nodiscard]] const std::string& field() const noexcept { return field_; }
567
+
568
+ private:
569
+ std::string field_;
570
+ };
571
+
572
+ class DataValidator {
573
+ public:
574
+ /// @throws ValidationError if data is invalid
575
+ void validate(std::string_view data) const {
576
+ if (data.empty()) {
577
+ throw ValidationError("Data cannot be empty", "data");
578
+ }
579
+ }
580
+
581
+ /// @return Optional value if valid, nullopt otherwise
582
+ [[nodiscard]] std::optional<int> tryParse(std::string_view str) const noexcept {
583
+ try {
584
+ return std::stoi(std::string(str));
585
+ } catch (...) {
586
+ return std::nullopt;
587
+ }
588
+ }
589
+ };
590
+
591
+ } // namespace your_namespace
592
+ ```
593
+
594
+ ## Threading & Concurrency
595
+
596
+ - Use `std::thread`, `std::jthread` (C++20), or `std::async`
597
+ - Use `std::mutex`, `std::shared_mutex` for synchronization
598
+ - Prefer `std::atomic` for simple shared state
599
+ - Use `std::lock_guard` or `std::scoped_lock`
600
+
601
+ Example:
602
+
603
+ ```cpp
604
+ #include <mutex>
605
+ #include <shared_mutex>
606
+ #include <thread>
607
+ #include <atomic>
608
+
609
+ class ThreadSafeCounter {
610
+ public:
611
+ void increment() {
612
+ std::scoped_lock lock(mutex_);
613
+ ++counter_;
614
+ }
615
+
616
+ [[nodiscard]] int get() const {
617
+ std::shared_lock lock(mutex_);
618
+ return counter_;
619
+ }
620
+
621
+ private:
622
+ mutable std::shared_mutex mutex_;
623
+ int counter_{0};
624
+ };
625
+
626
+ // For simple atomics
627
+ class AtomicCounter {
628
+ public:
629
+ void increment() noexcept {
630
+ counter_.fetch_add(1, std::memory_order_relaxed);
631
+ }
632
+
633
+ [[nodiscard]] int get() const noexcept {
634
+ return counter_.load(std::memory_order_relaxed);
635
+ }
636
+
637
+ private:
638
+ std::atomic<int> counter_{0};
639
+ };
640
+ ```
641
+
642
+ ## CI/CD Requirements
643
+
644
+ Must include GitHub Actions workflows for:
645
+
646
+ 1. **Testing** (`cpp-test.yml`):
647
+ - Test on ubuntu-latest, windows-latest, macos-latest
648
+ - Test with GCC, Clang, MSVC
649
+ - Upload coverage reports
650
+
651
+ 2. **Linting** (`cpp-lint.yml`):
652
+ - clang-format check
653
+ - clang-tidy analysis
654
+ - cppcheck static analysis
655
+
656
+ ## Package Publication
657
+
658
+ ### Publishing C/C++ Libraries
659
+
660
+ **Options:**
661
+ 1. **Conan Center**: Public Conan repository
662
+ 2. **vcpkg**: Microsoft's package manager
663
+ 3. **GitHub Releases**: Binary releases
664
+ 4. **Header-only**: Single-file distribution
665
+
666
+ ### Conan Publication
667
+
668
+ **conanfile.py:**
669
+
670
+ ```python
671
+ from conan import ConanFile
672
+ from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout
673
+
674
+ class YourProjectConan(ConanFile):
675
+ name = "your-project"
676
+ version = "1.0.0"
677
+ license = "MIT"
678
+ author = "Your Name your.email@example.com"
679
+ url = "https://github.com/your-org/your-project"
680
+ description = "Short description"
681
+ topics = ("cpp", "library")
682
+ settings = "os", "compiler", "build_type", "arch"
683
+
684
+ options = {
685
+ "shared": [True, False],
686
+ "fPIC": [True, False]
687
+ }
688
+ default_options = {
689
+ "shared": False,
690
+ "fPIC": True
691
+ }
692
+
693
+ exports_sources = "CMakeLists.txt", "src/*", "include/*"
694
+
695
+ def layout(self):
696
+ cmake_layout(self)
697
+
698
+ def generate(self):
699
+ tc = CMakeToolchain(self)
700
+ tc.generate()
701
+
702
+ def build(self):
703
+ cmake = CMake(self)
704
+ cmake.configure()
705
+ cmake.build()
706
+
707
+ def package(self):
708
+ cmake = CMake(self)
709
+ cmake.install()
710
+
711
+ def package_info(self):
712
+ self.cpp_info.libs = ["your-project"]
713
+ ```
714
+
715
+ ### vcpkg Publication
716
+
717
+ **vcpkg.json:**
718
+
719
+ ```json
720
+ {
721
+ "name": "your-project",
722
+ "version": "1.0.0",
723
+ "description": "Short description",
724
+ "homepage": "https://github.com/your-org/your-project",
725
+ "license": "MIT",
726
+ "dependencies": [
727
+ {
728
+ "name": "vcpkg-cmake",
729
+ "host": true
730
+ },
731
+ {
732
+ "name": "vcpkg-cmake-config",
733
+ "host": true
734
+ }
735
+ ]
736
+ }
737
+ ```
738
+
739
+ ### Publishing Checklist:
740
+
741
+ - ✅ All tests passing with sanitizers
742
+ - ✅ clang-tidy clean
743
+ - ✅ clang-format applied
744
+ - ✅ Documentation generated
745
+ - ✅ Version updated in CMakeLists.txt
746
+ - ✅ CHANGELOG.md updated
747
+ - ✅ README.md with build instructions
748
+ - ✅ LICENSE file present
749
+ - ✅ CMake config for find_package support
750
+ - ✅ Conan recipe or vcpkg portfile
751
+
752
+ <!-- CPP:END -->
753
+