@hivehub/rulebook 4.1.0 → 4.2.1

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 (335) 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 +137 -1
  19. package/dist/cli/commands.d.ts +18 -6
  20. package/dist/cli/commands.d.ts.map +1 -1
  21. package/dist/cli/commands.js +727 -406
  22. package/dist/cli/commands.js.map +1 -1
  23. package/dist/core/claude-mcp.d.ts +4 -2
  24. package/dist/core/claude-mcp.d.ts.map +1 -1
  25. package/dist/core/claude-mcp.js +14 -9
  26. package/dist/core/claude-mcp.js.map +1 -1
  27. package/dist/core/generator.d.ts.map +1 -1
  28. package/dist/core/generator.js +13 -0
  29. package/dist/core/generator.js.map +1 -1
  30. package/dist/core/indexer/background-indexer.d.ts.map +1 -1
  31. package/dist/core/indexer/background-indexer.js +26 -5
  32. package/dist/core/indexer/background-indexer.js.map +1 -1
  33. package/dist/core/indexer/file-parser.d.ts.map +1 -1
  34. package/dist/core/indexer/file-parser.js +1 -1
  35. package/dist/core/indexer/file-parser.js.map +1 -1
  36. package/dist/core/indexer/indexer-types.d.ts.map +1 -1
  37. package/dist/core/workspace/legacy-migrator.d.ts +29 -0
  38. package/dist/core/workspace/legacy-migrator.d.ts.map +1 -0
  39. package/dist/core/workspace/legacy-migrator.js +142 -0
  40. package/dist/core/workspace/legacy-migrator.js.map +1 -0
  41. package/dist/core/workspace/project-worker.d.ts +49 -0
  42. package/dist/core/workspace/project-worker.d.ts.map +1 -0
  43. package/dist/core/workspace/project-worker.js +108 -0
  44. package/dist/core/workspace/project-worker.js.map +1 -0
  45. package/dist/core/workspace/workspace-manager.d.ts +90 -0
  46. package/dist/core/workspace/workspace-manager.d.ts.map +1 -0
  47. package/dist/core/workspace/workspace-manager.js +347 -0
  48. package/dist/core/workspace/workspace-manager.js.map +1 -0
  49. package/dist/core/workspace/workspace-types.d.ts +37 -0
  50. package/dist/core/workspace/workspace-types.d.ts.map +1 -0
  51. package/dist/core/workspace/workspace-types.js +8 -0
  52. package/dist/core/workspace/workspace-types.js.map +1 -0
  53. package/dist/index.js +43 -7
  54. package/dist/index.js.map +1 -1
  55. package/dist/mcp/rulebook-server.d.ts.map +1 -1
  56. package/dist/mcp/rulebook-server.js +367 -100
  57. package/dist/mcp/rulebook-server.js.map +1 -1
  58. package/dist/memory/memory-manager.js +2 -2
  59. package/dist/memory/memory-manager.js.map +1 -1
  60. package/dist/memory/memory-search.js.map +1 -1
  61. package/dist/memory/memory-store.d.ts.map +1 -1
  62. package/dist/memory/memory-store.js +1 -1
  63. package/dist/memory/memory-store.js.map +1 -1
  64. package/dist/types.d.ts +1 -0
  65. package/dist/types.d.ts.map +1 -1
  66. package/package.json +22 -21
  67. package/templates/agents/implementer.md +35 -35
  68. package/templates/agents/researcher.md +34 -34
  69. package/templates/agents/team-lead.md +34 -34
  70. package/templates/agents/tester.md +42 -42
  71. package/templates/ci/rulebook-review.yml +26 -26
  72. package/templates/cli/AIDER.md +49 -49
  73. package/templates/cli/AMAZON_Q.md +25 -25
  74. package/templates/cli/AUGGIE.md +32 -32
  75. package/templates/cli/CLAUDE.md +117 -117
  76. package/templates/cli/CLINE.md +99 -99
  77. package/templates/cli/CODEBUDDY.md +20 -20
  78. package/templates/cli/CODEIUM.md +20 -20
  79. package/templates/cli/CODEX.md +21 -21
  80. package/templates/cli/CONTINUE.md +34 -34
  81. package/templates/cli/CURSOR_CLI.md +62 -62
  82. package/templates/cli/FACTORY.md +18 -18
  83. package/templates/cli/GEMINI.md +35 -35
  84. package/templates/cli/KILOCODE.md +18 -18
  85. package/templates/cli/OPENCODE.md +18 -18
  86. package/templates/cli/_GENERIC_TEMPLATE.md +29 -29
  87. package/templates/commands/rulebook-memory-save.md +48 -48
  88. package/templates/commands/rulebook-memory-search.md +47 -47
  89. package/templates/commands/rulebook-task-apply.md +67 -67
  90. package/templates/commands/rulebook-task-archive.md +94 -94
  91. package/templates/commands/rulebook-task-create.md +93 -93
  92. package/templates/commands/rulebook-task-list.md +42 -42
  93. package/templates/commands/rulebook-task-show.md +52 -52
  94. package/templates/commands/rulebook-task-validate.md +53 -53
  95. package/templates/core/AGENTS_LEAN.md +25 -25
  96. package/templates/core/AGENTS_OVERRIDE.md +16 -16
  97. package/templates/core/AGENT_AUTOMATION.md +288 -288
  98. package/templates/core/DAG.md +304 -304
  99. package/templates/core/DOCUMENTATION_RULES.md +36 -36
  100. package/templates/core/MULTI_AGENT.md +74 -74
  101. package/templates/core/PLANS.md +28 -28
  102. package/templates/core/QUALITY_ENFORCEMENT.md +68 -68
  103. package/templates/core/RALPH.md +471 -471
  104. package/templates/core/RULEBOOK.md +1935 -1935
  105. package/templates/core/WORKSPACE.md +69 -0
  106. package/templates/frameworks/ANGULAR.md +36 -36
  107. package/templates/frameworks/DJANGO.md +83 -83
  108. package/templates/frameworks/ELECTRON.md +147 -147
  109. package/templates/frameworks/FLASK.md +38 -38
  110. package/templates/frameworks/FLUTTER.md +55 -55
  111. package/templates/frameworks/JQUERY.md +32 -32
  112. package/templates/frameworks/LARAVEL.md +38 -38
  113. package/templates/frameworks/NESTJS.md +43 -43
  114. package/templates/frameworks/NEXTJS.md +127 -127
  115. package/templates/frameworks/NUXT.md +40 -40
  116. package/templates/frameworks/RAILS.md +66 -66
  117. package/templates/frameworks/REACT.md +38 -38
  118. package/templates/frameworks/REACT_NATIVE.md +47 -47
  119. package/templates/frameworks/SPRING.md +39 -39
  120. package/templates/frameworks/SYMFONY.md +36 -36
  121. package/templates/frameworks/VUE.md +36 -36
  122. package/templates/frameworks/ZEND.md +35 -35
  123. package/templates/git/CI_CD_PATTERNS.md +661 -661
  124. package/templates/git/GITHUB_ACTIONS.md +728 -728
  125. package/templates/git/GITLAB_CI.md +730 -730
  126. package/templates/git/GIT_WORKFLOW.md +1157 -1157
  127. package/templates/git/SECRETS_MANAGEMENT.md +585 -585
  128. package/templates/hooks/COMMIT_MSG.md +530 -530
  129. package/templates/hooks/POST_CHECKOUT.md +546 -546
  130. package/templates/hooks/PREPARE_COMMIT_MSG.md +619 -619
  131. package/templates/hooks/PRE_COMMIT.md +414 -414
  132. package/templates/hooks/PRE_PUSH.md +601 -601
  133. package/templates/ides/CONTINUE_RULES.md +16 -16
  134. package/templates/ides/COPILOT.md +37 -37
  135. package/templates/ides/COPILOT_INSTRUCTIONS.md +23 -23
  136. package/templates/ides/CURSOR.md +43 -43
  137. package/templates/ides/GEMINI_RULES.md +17 -17
  138. package/templates/ides/JETBRAINS_AI.md +35 -35
  139. package/templates/ides/REPLIT.md +36 -36
  140. package/templates/ides/TABNINE.md +29 -29
  141. package/templates/ides/VSCODE.md +40 -40
  142. package/templates/ides/WINDSURF.md +36 -36
  143. package/templates/ides/WINDSURF_RULES.md +14 -14
  144. package/templates/ides/ZED.md +32 -32
  145. package/templates/ides/cursor-mdc/go.mdc +24 -24
  146. package/templates/ides/cursor-mdc/python.mdc +24 -24
  147. package/templates/ides/cursor-mdc/quality.mdc +25 -25
  148. package/templates/ides/cursor-mdc/ralph.mdc +39 -39
  149. package/templates/ides/cursor-mdc/rulebook.mdc +38 -38
  150. package/templates/ides/cursor-mdc/rust.mdc +24 -24
  151. package/templates/ides/cursor-mdc/typescript.mdc +25 -25
  152. package/templates/languages/C.md +333 -333
  153. package/templates/languages/CPP.md +743 -743
  154. package/templates/languages/CSHARP.md +417 -417
  155. package/templates/languages/ELIXIR.md +454 -454
  156. package/templates/languages/ERLANG.md +361 -361
  157. package/templates/languages/GO.md +645 -645
  158. package/templates/languages/HASKELL.md +177 -177
  159. package/templates/languages/JAVA.md +607 -607
  160. package/templates/languages/JAVASCRIPT.md +631 -631
  161. package/templates/languages/JULIA.md +97 -97
  162. package/templates/languages/KOTLIN.md +511 -511
  163. package/templates/languages/LISP.md +100 -100
  164. package/templates/languages/LUA.md +74 -74
  165. package/templates/languages/OBJECTIVEC.md +90 -90
  166. package/templates/languages/PHP.md +416 -416
  167. package/templates/languages/PYTHON.md +682 -682
  168. package/templates/languages/RUBY.md +421 -421
  169. package/templates/languages/RUST.md +477 -477
  170. package/templates/languages/SAS.md +73 -73
  171. package/templates/languages/SCALA.md +348 -348
  172. package/templates/languages/SOLIDITY.md +580 -580
  173. package/templates/languages/SQL.md +137 -137
  174. package/templates/languages/SWIFT.md +466 -466
  175. package/templates/languages/TYPESCRIPT.md +591 -591
  176. package/templates/languages/ZIG.md +265 -265
  177. package/templates/modules/ATLASSIAN.md +255 -255
  178. package/templates/modules/CONTEXT7.md +54 -54
  179. package/templates/modules/FIGMA.md +267 -267
  180. package/templates/modules/GITHUB_MCP.md +64 -64
  181. package/templates/modules/GRAFANA.md +328 -328
  182. package/templates/modules/MEMORY.md +126 -126
  183. package/templates/modules/NOTION.md +247 -247
  184. package/templates/modules/PLAYWRIGHT.md +90 -90
  185. package/templates/modules/RULEBOOK_MCP.md +156 -156
  186. package/templates/modules/SERENA.md +337 -337
  187. package/templates/modules/SUPABASE.md +223 -223
  188. package/templates/modules/SYNAP.md +69 -69
  189. package/templates/modules/VECTORIZER.md +63 -63
  190. package/templates/modules/sequential-thinking.md +42 -42
  191. package/templates/ralph/ralph-history.bat +4 -4
  192. package/templates/ralph/ralph-history.sh +5 -5
  193. package/templates/ralph/ralph-init.bat +5 -5
  194. package/templates/ralph/ralph-init.sh +5 -5
  195. package/templates/ralph/ralph-pause.bat +5 -5
  196. package/templates/ralph/ralph-pause.sh +5 -5
  197. package/templates/ralph/ralph-run.bat +5 -5
  198. package/templates/ralph/ralph-run.sh +5 -5
  199. package/templates/ralph/ralph-status.bat +4 -4
  200. package/templates/ralph/ralph-status.sh +5 -5
  201. package/templates/services/AZURE_BLOB.md +184 -184
  202. package/templates/services/CASSANDRA.md +239 -239
  203. package/templates/services/DATADOG.md +26 -26
  204. package/templates/services/DOCKER.md +124 -124
  205. package/templates/services/DOCKER_COMPOSE.md +168 -168
  206. package/templates/services/DYNAMODB.md +308 -308
  207. package/templates/services/ELASTICSEARCH.md +347 -347
  208. package/templates/services/GCS.md +178 -178
  209. package/templates/services/HELM.md +194 -194
  210. package/templates/services/INFLUXDB.md +265 -265
  211. package/templates/services/KAFKA.md +341 -341
  212. package/templates/services/KUBERNETES.md +208 -208
  213. package/templates/services/MARIADB.md +183 -183
  214. package/templates/services/MEMCACHED.md +242 -242
  215. package/templates/services/MINIO.md +201 -201
  216. package/templates/services/MONGODB.md +268 -268
  217. package/templates/services/MYSQL.md +358 -358
  218. package/templates/services/NEO4J.md +247 -247
  219. package/templates/services/OPENTELEMETRY.md +25 -25
  220. package/templates/services/ORACLE.md +290 -290
  221. package/templates/services/PINO.md +24 -24
  222. package/templates/services/POSTGRESQL.md +326 -326
  223. package/templates/services/PROMETHEUS.md +33 -33
  224. package/templates/services/RABBITMQ.md +286 -286
  225. package/templates/services/REDIS.md +292 -292
  226. package/templates/services/S3.md +298 -298
  227. package/templates/services/SENTRY.md +23 -23
  228. package/templates/services/SQLITE.md +294 -294
  229. package/templates/services/SQLSERVER.md +294 -294
  230. package/templates/services/WINSTON.md +30 -30
  231. package/templates/skills/cli/aider/SKILL.md +59 -59
  232. package/templates/skills/cli/amazon-q/SKILL.md +35 -35
  233. package/templates/skills/cli/auggie/SKILL.md +42 -42
  234. package/templates/skills/cli/claude/SKILL.md +42 -42
  235. package/templates/skills/cli/cline/SKILL.md +42 -42
  236. package/templates/skills/cli/codebuddy/SKILL.md +30 -30
  237. package/templates/skills/cli/codeium/SKILL.md +30 -30
  238. package/templates/skills/cli/codex/SKILL.md +31 -31
  239. package/templates/skills/cli/continue/SKILL.md +44 -44
  240. package/templates/skills/cli/cursor-cli/SKILL.md +38 -38
  241. package/templates/skills/cli/factory/SKILL.md +28 -28
  242. package/templates/skills/cli/gemini/SKILL.md +45 -45
  243. package/templates/skills/cli/kilocode/SKILL.md +28 -28
  244. package/templates/skills/cli/opencode/SKILL.md +28 -28
  245. package/templates/skills/core/agent-automation/SKILL.md +194 -194
  246. package/templates/skills/core/dag/SKILL.md +314 -314
  247. package/templates/skills/core/documentation-rules/SKILL.md +46 -46
  248. package/templates/skills/core/quality-enforcement/SKILL.md +78 -78
  249. package/templates/skills/core/rulebook/SKILL.md +176 -176
  250. package/templates/skills/frameworks/angular/SKILL.md +46 -46
  251. package/templates/skills/frameworks/django/SKILL.md +93 -93
  252. package/templates/skills/frameworks/electron/SKILL.md +157 -157
  253. package/templates/skills/frameworks/flask/SKILL.md +48 -48
  254. package/templates/skills/frameworks/flutter/SKILL.md +65 -65
  255. package/templates/skills/frameworks/jquery/SKILL.md +42 -42
  256. package/templates/skills/frameworks/laravel/SKILL.md +48 -48
  257. package/templates/skills/frameworks/nestjs/SKILL.md +53 -53
  258. package/templates/skills/frameworks/nextjs/SKILL.md +137 -137
  259. package/templates/skills/frameworks/nuxt/SKILL.md +50 -50
  260. package/templates/skills/frameworks/rails/SKILL.md +76 -76
  261. package/templates/skills/frameworks/react/SKILL.md +48 -48
  262. package/templates/skills/frameworks/react-native/SKILL.md +57 -57
  263. package/templates/skills/frameworks/spring/SKILL.md +49 -49
  264. package/templates/skills/frameworks/symfony/SKILL.md +46 -46
  265. package/templates/skills/frameworks/vue/SKILL.md +46 -46
  266. package/templates/skills/frameworks/zend/SKILL.md +45 -45
  267. package/templates/skills/ides/copilot/SKILL.md +47 -47
  268. package/templates/skills/ides/cursor/SKILL.md +53 -53
  269. package/templates/skills/ides/jetbrains-ai/SKILL.md +45 -45
  270. package/templates/skills/ides/replit/SKILL.md +46 -46
  271. package/templates/skills/ides/tabnine/SKILL.md +39 -39
  272. package/templates/skills/ides/vscode/SKILL.md +50 -50
  273. package/templates/skills/ides/windsurf/SKILL.md +46 -46
  274. package/templates/skills/ides/zed/SKILL.md +42 -42
  275. package/templates/skills/languages/c/SKILL.md +343 -343
  276. package/templates/skills/languages/cpp/SKILL.md +753 -753
  277. package/templates/skills/languages/csharp/SKILL.md +427 -427
  278. package/templates/skills/languages/elixir/SKILL.md +464 -464
  279. package/templates/skills/languages/erlang/SKILL.md +371 -371
  280. package/templates/skills/languages/go/SKILL.md +655 -655
  281. package/templates/skills/languages/haskell/SKILL.md +187 -187
  282. package/templates/skills/languages/java/SKILL.md +617 -617
  283. package/templates/skills/languages/javascript/SKILL.md +641 -641
  284. package/templates/skills/languages/julia/SKILL.md +107 -107
  285. package/templates/skills/languages/kotlin/SKILL.md +521 -521
  286. package/templates/skills/languages/lisp/SKILL.md +110 -110
  287. package/templates/skills/languages/lua/SKILL.md +84 -84
  288. package/templates/skills/languages/objectivec/SKILL.md +100 -100
  289. package/templates/skills/languages/php/SKILL.md +426 -426
  290. package/templates/skills/languages/python/SKILL.md +692 -692
  291. package/templates/skills/languages/ruby/SKILL.md +431 -431
  292. package/templates/skills/languages/rust/SKILL.md +487 -487
  293. package/templates/skills/languages/sas/SKILL.md +83 -83
  294. package/templates/skills/languages/scala/SKILL.md +358 -358
  295. package/templates/skills/languages/solidity/SKILL.md +590 -590
  296. package/templates/skills/languages/sql/SKILL.md +147 -147
  297. package/templates/skills/languages/swift/SKILL.md +476 -476
  298. package/templates/skills/languages/typescript/SKILL.md +302 -302
  299. package/templates/skills/languages/zig/SKILL.md +275 -275
  300. package/templates/skills/modules/atlassian/SKILL.md +265 -265
  301. package/templates/skills/modules/context7/SKILL.md +64 -64
  302. package/templates/skills/modules/figma/SKILL.md +277 -277
  303. package/templates/skills/modules/github-mcp/SKILL.md +74 -74
  304. package/templates/skills/modules/grafana/SKILL.md +338 -338
  305. package/templates/skills/modules/memory/SKILL.md +73 -73
  306. package/templates/skills/modules/notion/SKILL.md +257 -257
  307. package/templates/skills/modules/playwright/SKILL.md +100 -100
  308. package/templates/skills/modules/rulebook-mcp/SKILL.md +166 -166
  309. package/templates/skills/modules/serena/SKILL.md +347 -347
  310. package/templates/skills/modules/supabase/SKILL.md +233 -233
  311. package/templates/skills/modules/synap/SKILL.md +79 -79
  312. package/templates/skills/modules/vectorizer/SKILL.md +73 -73
  313. package/templates/skills/services/azure-blob/SKILL.md +194 -194
  314. package/templates/skills/services/cassandra/SKILL.md +249 -249
  315. package/templates/skills/services/dynamodb/SKILL.md +318 -318
  316. package/templates/skills/services/elasticsearch/SKILL.md +357 -357
  317. package/templates/skills/services/gcs/SKILL.md +188 -188
  318. package/templates/skills/services/influxdb/SKILL.md +275 -275
  319. package/templates/skills/services/kafka/SKILL.md +351 -351
  320. package/templates/skills/services/mariadb/SKILL.md +193 -193
  321. package/templates/skills/services/memcached/SKILL.md +252 -252
  322. package/templates/skills/services/minio/SKILL.md +211 -211
  323. package/templates/skills/services/mongodb/SKILL.md +278 -278
  324. package/templates/skills/services/mysql/SKILL.md +368 -368
  325. package/templates/skills/services/neo4j/SKILL.md +257 -257
  326. package/templates/skills/services/oracle/SKILL.md +300 -300
  327. package/templates/skills/services/postgresql/SKILL.md +336 -336
  328. package/templates/skills/services/rabbitmq/SKILL.md +296 -296
  329. package/templates/skills/services/redis/SKILL.md +302 -302
  330. package/templates/skills/services/s3/SKILL.md +308 -308
  331. package/templates/skills/services/sqlite/SKILL.md +304 -304
  332. package/templates/skills/services/sqlserver/SKILL.md +304 -304
  333. package/templates/skills/workflows/ralph/SKILL.md +309 -309
  334. package/templates/skills/workflows/ralph/install.sh +87 -87
  335. 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
+