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