@hivehub/rulebook 4.0.0 → 4.2.0

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