red64-cli 0.3.0 → 0.6.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 (95) hide show
  1. package/README.md +194 -338
  2. package/dist/cli/parseArgs.d.ts.map +1 -1
  3. package/dist/cli/parseArgs.js +5 -13
  4. package/dist/cli/parseArgs.js.map +1 -1
  5. package/dist/components/init/types.d.ts +0 -2
  6. package/dist/components/init/types.d.ts.map +1 -1
  7. package/dist/components/screens/HelpScreen.d.ts.map +1 -1
  8. package/dist/components/screens/HelpScreen.js +0 -2
  9. package/dist/components/screens/HelpScreen.js.map +1 -1
  10. package/dist/components/screens/InitScreen.d.ts.map +1 -1
  11. package/dist/components/screens/InitScreen.js +5 -8
  12. package/dist/components/screens/InitScreen.js.map +1 -1
  13. package/dist/components/screens/StartScreen.d.ts.map +1 -1
  14. package/dist/components/screens/StartScreen.js +29 -8
  15. package/dist/components/screens/StartScreen.js.map +1 -1
  16. package/dist/components/screens/StatusScreen.d.ts.map +1 -1
  17. package/dist/components/screens/StatusScreen.js +16 -1
  18. package/dist/components/screens/StatusScreen.js.map +1 -1
  19. package/dist/services/AgentInvoker.d.ts.map +1 -1
  20. package/dist/services/AgentInvoker.js +76 -37
  21. package/dist/services/AgentInvoker.js.map +1 -1
  22. package/dist/services/ClaudeErrorDetector.d.ts +1 -1
  23. package/dist/services/ClaudeErrorDetector.d.ts.map +1 -1
  24. package/dist/services/ClaudeErrorDetector.js +1 -0
  25. package/dist/services/ClaudeErrorDetector.js.map +1 -1
  26. package/dist/services/ClaudeHealthCheck.d.ts +7 -0
  27. package/dist/services/ClaudeHealthCheck.d.ts.map +1 -1
  28. package/dist/services/ClaudeHealthCheck.js +76 -12
  29. package/dist/services/ClaudeHealthCheck.js.map +1 -1
  30. package/dist/services/ConfigService.d.ts +1 -0
  31. package/dist/services/ConfigService.d.ts.map +1 -1
  32. package/dist/services/ConfigService.js.map +1 -1
  33. package/dist/services/DockerRunner.js +1 -1
  34. package/dist/services/DockerRunner.js.map +1 -1
  35. package/dist/services/PhaseExecutor.d.ts.map +1 -1
  36. package/dist/services/PhaseExecutor.js +2 -1
  37. package/dist/services/PhaseExecutor.js.map +1 -1
  38. package/dist/services/TaskRunner.d.ts.map +1 -1
  39. package/dist/services/TaskRunner.js +2 -1
  40. package/dist/services/TaskRunner.js.map +1 -1
  41. package/dist/services/index.d.ts +1 -1
  42. package/dist/services/index.d.ts.map +1 -1
  43. package/dist/services/index.js +1 -1
  44. package/dist/services/index.js.map +1 -1
  45. package/dist/types/index.d.ts +4 -3
  46. package/dist/types/index.d.ts.map +1 -1
  47. package/dist/types/index.js.map +1 -1
  48. package/framework/stacks/c/code-quality.md +326 -0
  49. package/framework/stacks/c/coding-style.md +347 -0
  50. package/framework/stacks/c/conventions.md +513 -0
  51. package/framework/stacks/c/error-handling.md +350 -0
  52. package/framework/stacks/c/feedback.md +158 -0
  53. package/framework/stacks/c/memory-safety.md +408 -0
  54. package/framework/stacks/c/tech.md +122 -0
  55. package/framework/stacks/c/testing.md +472 -0
  56. package/framework/stacks/cpp/code-quality.md +282 -0
  57. package/framework/stacks/cpp/coding-style.md +363 -0
  58. package/framework/stacks/cpp/conventions.md +420 -0
  59. package/framework/stacks/cpp/error-handling.md +264 -0
  60. package/framework/stacks/cpp/feedback.md +104 -0
  61. package/framework/stacks/cpp/memory-safety.md +351 -0
  62. package/framework/stacks/cpp/tech.md +160 -0
  63. package/framework/stacks/cpp/testing.md +323 -0
  64. package/framework/stacks/java/code-quality.md +357 -0
  65. package/framework/stacks/java/coding-style.md +400 -0
  66. package/framework/stacks/java/conventions.md +437 -0
  67. package/framework/stacks/java/error-handling.md +408 -0
  68. package/framework/stacks/java/feedback.md +180 -0
  69. package/framework/stacks/java/tech.md +126 -0
  70. package/framework/stacks/java/testing.md +485 -0
  71. package/framework/stacks/javascript/async-patterns.md +216 -0
  72. package/framework/stacks/javascript/code-quality.md +182 -0
  73. package/framework/stacks/javascript/coding-style.md +293 -0
  74. package/framework/stacks/javascript/conventions.md +268 -0
  75. package/framework/stacks/javascript/error-handling.md +216 -0
  76. package/framework/stacks/javascript/feedback.md +80 -0
  77. package/framework/stacks/javascript/tech.md +114 -0
  78. package/framework/stacks/javascript/testing.md +209 -0
  79. package/framework/stacks/loco/code-quality.md +156 -0
  80. package/framework/stacks/loco/coding-style.md +247 -0
  81. package/framework/stacks/loco/error-handling.md +225 -0
  82. package/framework/stacks/loco/feedback.md +35 -0
  83. package/framework/stacks/loco/loco.md +342 -0
  84. package/framework/stacks/loco/structure.md +193 -0
  85. package/framework/stacks/loco/tech.md +129 -0
  86. package/framework/stacks/loco/testing.md +211 -0
  87. package/framework/stacks/rust/code-quality.md +370 -0
  88. package/framework/stacks/rust/coding-style.md +475 -0
  89. package/framework/stacks/rust/conventions.md +430 -0
  90. package/framework/stacks/rust/error-handling.md +399 -0
  91. package/framework/stacks/rust/feedback.md +152 -0
  92. package/framework/stacks/rust/memory-safety.md +398 -0
  93. package/framework/stacks/rust/tech.md +121 -0
  94. package/framework/stacks/rust/testing.md +528 -0
  95. package/package.json +14 -2
@@ -0,0 +1,408 @@
1
+ # Memory Safety
2
+
3
+ Patterns and practices for memory-safe C code. Manual memory management demands discipline: always check allocations, always free on all paths, and use tools to verify correctness.
4
+
5
+ ---
6
+
7
+ ## Philosophy
8
+
9
+ - **Every allocation has an owner**: One function allocates, one function frees -- document which
10
+ - **Check every malloc**: Never assume allocation succeeds
11
+ - **Free and NULL**: After freeing, set the pointer to NULL to prevent use-after-free
12
+ - **Verify with tools**: Valgrind, ASan, and UBSan catch what code review misses
13
+ - **Ref**: CERT C MEM30-C through MEM36-C, SEI CERT Secure Coding
14
+
15
+ ---
16
+
17
+ ## Always Check malloc Return
18
+
19
+ ```c
20
+ /* GOOD: Check allocation and handle failure */
21
+ char *buffer = malloc(size);
22
+ if (!buffer) {
23
+ log_error("malloc(%zu) failed", size);
24
+ return ERR_NOMEM;
25
+ }
26
+ memset(buffer, 0, size);
27
+
28
+ /* GOOD: calloc initializes to zero and checks for overflow */
29
+ user_t *users = calloc(count, sizeof(user_t));
30
+ if (!users) {
31
+ return ERR_NOMEM;
32
+ }
33
+
34
+ /* BAD: No check -- null dereference if allocation fails */
35
+ char *buffer = malloc(size);
36
+ memset(buffer, 0, size); /* Crash if malloc returned NULL */
37
+ ```
38
+
39
+ ---
40
+
41
+ ## Free and NULL Pattern
42
+
43
+ ```c
44
+ /* GOOD: Free and immediately NULL the pointer */
45
+ void user_free(user_t *user) {
46
+ if (!user) return;
47
+ free(user->name);
48
+ user->name = NULL;
49
+ free(user->email);
50
+ user->email = NULL;
51
+ free(user);
52
+ }
53
+
54
+ /* GOOD: Safe free macro */
55
+ #define SAFE_FREE(ptr) \
56
+ do { \
57
+ free(ptr); \
58
+ (ptr) = NULL; \
59
+ } while (0)
60
+
61
+ /* Usage */
62
+ SAFE_FREE(buffer);
63
+ SAFE_FREE(name);
64
+
65
+ /* BAD: Free without NULL -- dangling pointer */
66
+ free(buffer);
67
+ /* buffer still holds old address -- use-after-free risk */
68
+ if (buffer) { /* This check is MEANINGLESS after free */
69
+ use(buffer);
70
+ }
71
+ ```
72
+
73
+ ---
74
+
75
+ ## Goto Cleanup for Resource Safety
76
+
77
+ The `goto cleanup` pattern ensures all resources are freed on every exit path. See error-handling.md for full details.
78
+
79
+ ```c
80
+ /* GOOD: All resources freed regardless of which step failed */
81
+ int process(const char *input, result_t *out) {
82
+ int rc = ERR_OK;
83
+ char *buffer = NULL;
84
+ FILE *fp = NULL;
85
+ cJSON *json = NULL;
86
+
87
+ buffer = malloc(BUFFER_SIZE);
88
+ if (!buffer) { rc = ERR_NOMEM; goto cleanup; }
89
+
90
+ fp = fopen(input, "r");
91
+ if (!fp) { rc = ERR_IO; goto cleanup; }
92
+
93
+ /* ... use buffer and fp ... */
94
+
95
+ json = cJSON_Parse(buffer);
96
+ if (!json) { rc = ERR_VALIDATION; goto cleanup; }
97
+
98
+ rc = extract(json, out);
99
+
100
+ cleanup:
101
+ if (json) cJSON_Delete(json);
102
+ if (fp) fclose(fp);
103
+ free(buffer); /* free(NULL) is safe per C standard */
104
+ return rc;
105
+ }
106
+
107
+ /* BAD: Early returns leak resources */
108
+ int process(const char *input, result_t *out) {
109
+ char *buffer = malloc(BUFFER_SIZE);
110
+ if (!buffer) return ERR_NOMEM;
111
+
112
+ FILE *fp = fopen(input, "r");
113
+ if (!fp) return ERR_IO; /* LEAK: buffer not freed */
114
+
115
+ /* ... */
116
+ }
117
+ ```
118
+
119
+ ---
120
+
121
+ ## Buffer Overflow Prevention
122
+
123
+ ```c
124
+ /* GOOD: Use snprintf instead of sprintf */
125
+ char message[256];
126
+ snprintf(message, sizeof(message), "User %s logged in from %s", name, ip);
127
+
128
+ /* GOOD: Use strncpy with explicit null termination */
129
+ char dest[64];
130
+ strncpy(dest, src, sizeof(dest) - 1);
131
+ dest[sizeof(dest) - 1] = '\0';
132
+
133
+ /* GOOD: Use strncat with remaining space calculation */
134
+ char path[PATH_MAX];
135
+ strncpy(path, base_dir, sizeof(path) - 1);
136
+ path[sizeof(path) - 1] = '\0';
137
+ strncat(path, "/", sizeof(path) - strlen(path) - 1);
138
+ strncat(path, filename, sizeof(path) - strlen(path) - 1);
139
+
140
+ /* GOOD: Bounds-check array access */
141
+ int get_item(const int *arr, size_t arr_len, size_t index) {
142
+ if (index >= arr_len) {
143
+ return ERR_OUT_OF_BOUNDS;
144
+ }
145
+ return arr[index];
146
+ }
147
+
148
+ /* BAD: sprintf -- no bounds checking */
149
+ char message[64];
150
+ sprintf(message, "User %s logged in from %s", name, ip); /* Buffer overflow */
151
+
152
+ /* BAD: strcpy -- no bounds checking */
153
+ char dest[64];
154
+ strcpy(dest, src); /* Overflow if src > 63 chars */
155
+
156
+ /* BAD: gets -- never use, removed in C11 */
157
+ char input[256];
158
+ gets(input); /* Unbounded read from stdin */
159
+ ```
160
+
161
+ ### Banned Functions
162
+
163
+ | Banned | Replacement | Reason |
164
+ |---|---|---|
165
+ | `sprintf` | `snprintf` | No bounds checking |
166
+ | `strcpy` | `strncpy` + null term, or `snprintf` | No bounds checking |
167
+ | `strcat` | `strncat` or `snprintf` | No bounds checking |
168
+ | `gets` | `fgets` | Removed in C11, unbounded |
169
+ | `scanf("%s", ...)` | `scanf("%63s", ...)` with width | Unbounded string read |
170
+ | `atoi`, `atol` | `strtol`, `strtoul` | No error detection |
171
+
172
+ ---
173
+
174
+ ## Valgrind Memcheck
175
+
176
+ ```bash
177
+ # Full leak check
178
+ valgrind --leak-check=full \
179
+ --show-leak-kinds=all \
180
+ --track-origins=yes \
181
+ --error-exitcode=1 \
182
+ ./build/myapp
183
+
184
+ # With suppression file
185
+ valgrind --leak-check=full \
186
+ --suppressions=valgrind.supp \
187
+ --error-exitcode=1 \
188
+ ./build/tests/test_user
189
+ ```
190
+
191
+ ### What Valgrind Detects
192
+
193
+ | Issue | Example |
194
+ |---|---|
195
+ | Memory leak | `malloc` without `free` |
196
+ | Use-after-free | Accessing freed memory |
197
+ | Invalid read/write | Buffer overflow, out-of-bounds |
198
+ | Uninitialized value | Reading memory before writing |
199
+ | Double free | Calling `free` twice on same pointer |
200
+ | Mismatched free | `free` on stack memory or wrong allocator |
201
+
202
+ ---
203
+
204
+ ## AddressSanitizer (ASan)
205
+
206
+ Faster than Valgrind, compile-time instrumentation.
207
+
208
+ ```bash
209
+ # Build with ASan
210
+ cmake -B build-asan -DCMAKE_BUILD_TYPE=Debug \
211
+ -DCMAKE_C_FLAGS="-fsanitize=address -fno-omit-frame-pointer"
212
+ cmake --build build-asan
213
+
214
+ # Run tests under ASan
215
+ ctest --test-dir build-asan --output-on-failure
216
+
217
+ # Enable leak detection (default on Linux, opt-in on macOS)
218
+ ASAN_OPTIONS=detect_leaks=1 ./build-asan/myapp
219
+ ```
220
+
221
+ ### ASan Detects
222
+
223
+ - Heap buffer overflow
224
+ - Stack buffer overflow
225
+ - Global buffer overflow
226
+ - Use-after-free
227
+ - Use-after-scope
228
+ - Double free
229
+ - Memory leaks (with `detect_leaks=1`)
230
+
231
+ ---
232
+
233
+ ## Arena / Pool Allocators
234
+
235
+ For performance-critical paths, arena allocators avoid per-object free overhead and eliminate fragmentation.
236
+
237
+ ```c
238
+ /* Simple arena allocator */
239
+ typedef struct {
240
+ char *base;
241
+ size_t capacity;
242
+ size_t offset;
243
+ } arena_t;
244
+
245
+ int arena_init(arena_t *a, size_t capacity) {
246
+ a->base = malloc(capacity);
247
+ if (!a->base) return ERR_NOMEM;
248
+ a->capacity = capacity;
249
+ a->offset = 0;
250
+ return ERR_OK;
251
+ }
252
+
253
+ void *arena_alloc(arena_t *a, size_t size) {
254
+ /* Align to 16 bytes */
255
+ size_t aligned = (size + 15) & ~(size_t)15;
256
+ if (a->offset + aligned > a->capacity) {
257
+ return NULL; /* Out of space */
258
+ }
259
+ void *ptr = a->base + a->offset;
260
+ a->offset += aligned;
261
+ return ptr;
262
+ }
263
+
264
+ void arena_reset(arena_t *a) {
265
+ a->offset = 0; /* "Free" everything at once */
266
+ }
267
+
268
+ void arena_destroy(arena_t *a) {
269
+ free(a->base);
270
+ a->base = NULL;
271
+ a->capacity = 0;
272
+ a->offset = 0;
273
+ }
274
+
275
+ /* Usage: request-scoped allocation */
276
+ int handle_request(const request_t *req, response_t *resp) {
277
+ arena_t arena;
278
+ if (arena_init(&arena, 64 * 1024) != ERR_OK) {
279
+ return ERR_NOMEM;
280
+ }
281
+
282
+ char *name = arena_alloc(&arena, 256);
283
+ char *body = arena_alloc(&arena, 4096);
284
+ /* ... use name and body ... */
285
+
286
+ arena_destroy(&arena); /* Single free for all allocations */
287
+ return ERR_OK;
288
+ }
289
+ ```
290
+
291
+ ---
292
+
293
+ ## RAII-Like Patterns with GCC/Clang Cleanup Attribute
294
+
295
+ ```c
296
+ /* GCC/Clang extension: __attribute__((cleanup)) */
297
+ static void free_ptr(void *p) {
298
+ free(*(void **)p);
299
+ }
300
+
301
+ static void close_file(FILE **fp) {
302
+ if (*fp) fclose(*fp);
303
+ }
304
+
305
+ #define AUTO_FREE __attribute__((cleanup(free_ptr)))
306
+ #define AUTO_CLOSE __attribute__((cleanup(close_file)))
307
+
308
+ /* Usage: automatic cleanup on scope exit */
309
+ int read_config(const char *path, config_t *out) {
310
+ AUTO_FREE char *buffer = malloc(4096);
311
+ if (!buffer) return ERR_NOMEM;
312
+
313
+ AUTO_CLOSE FILE *fp = fopen(path, "r");
314
+ if (!fp) return ERR_IO;
315
+
316
+ size_t n = fread(buffer, 1, 4095, fp);
317
+ buffer[n] = '\0';
318
+
319
+ return parse_config(buffer, out);
320
+ /* fp closed and buffer freed automatically at scope exit */
321
+ }
322
+
323
+ /* GOOD: Scope guard macro for arbitrary cleanup */
324
+ #define DEFER(fn) __attribute__((cleanup(fn)))
325
+ ```
326
+
327
+ **Note**: `__attribute__((cleanup))` is a GCC/Clang extension, not standard C. Use for internal code; prefer goto cleanup for portable library code.
328
+
329
+ ---
330
+
331
+ ## Dangling Pointer Prevention
332
+
333
+ ```c
334
+ /* GOOD: NULL after free prevents use-after-free */
335
+ free(user->name);
336
+ user->name = NULL;
337
+
338
+ /* GOOD: Invalidate pointer after transferring ownership */
339
+ connection_t *conn = connection_create();
340
+ pool_add(pool, conn); /* Pool now owns conn */
341
+ conn = NULL; /* Prevent accidental use */
342
+
343
+ /* BAD: Returning pointer to local stack variable */
344
+ char *get_greeting(void) {
345
+ char buf[64];
346
+ snprintf(buf, sizeof(buf), "Hello, World!");
347
+ return buf; /* DANGLING: buf is on stack, destroyed on return */
348
+ }
349
+
350
+ /* GOOD: Return heap-allocated or caller-provided buffer */
351
+ char *get_greeting(void) {
352
+ char *buf = malloc(64);
353
+ if (!buf) return NULL;
354
+ snprintf(buf, 64, "Hello, World!");
355
+ return buf; /* Caller must free */
356
+ }
357
+
358
+ int get_greeting(char *buf, size_t buf_size) {
359
+ snprintf(buf, buf_size, "Hello, World!");
360
+ return ERR_OK;
361
+ }
362
+ ```
363
+
364
+ ---
365
+
366
+ ## Double-Free Prevention
367
+
368
+ ```c
369
+ /* GOOD: Idempotent destroy function */
370
+ void resource_destroy(resource_t **res) {
371
+ if (!res || !*res) return;
372
+
373
+ free((*res)->data);
374
+ free(*res);
375
+ *res = NULL; /* Prevents double-free if called again */
376
+ }
377
+
378
+ /* Usage */
379
+ resource_t *r = resource_create();
380
+ resource_destroy(&r); /* r is now NULL */
381
+ resource_destroy(&r); /* Safe: no-op because r is NULL */
382
+
383
+ /* BAD: Non-idempotent free */
384
+ void resource_destroy(resource_t *res) {
385
+ free(res->data); /* Crash on double call */
386
+ free(res);
387
+ }
388
+ ```
389
+
390
+ ---
391
+
392
+ ## Anti-Patterns
393
+
394
+ | Anti-Pattern | Problem | Correct Approach |
395
+ |---|---|---|
396
+ | Unchecked `malloc` | Null dereference crash | Always check return, handle `ERR_NOMEM` |
397
+ | `free()` without NULL | Dangling pointer, use-after-free | `SAFE_FREE` macro or manual NULL after free |
398
+ | `sprintf`, `strcpy`, `strcat` | Buffer overflow | `snprintf`, `strncpy` + null term |
399
+ | Returning pointer to stack variable | Dangling pointer, UB | Return heap-allocated or use output parameter |
400
+ | No Valgrind/ASan in CI | Memory bugs reach production | Run sanitizers on every test |
401
+ | Manual cleanup at each error point | Missed frees, duplicated code | `goto cleanup` pattern |
402
+ | Mixing allocators | Heap corruption | Match `malloc`/`free`, `calloc`/`free`, custom pairs |
403
+ | VLA (variable-length arrays) | Stack overflow, no error handling | Use `malloc` with size check |
404
+ | `realloc` without temp pointer | Leak on failure | `tmp = realloc(ptr, n); if (tmp) ptr = tmp;` |
405
+
406
+ ---
407
+
408
+ _Memory safety in C is achieved through discipline, patterns, and tools. Check every allocation, free on every path, NULL after free, and verify with sanitizers._
@@ -0,0 +1,122 @@
1
+ # Technology Stack
2
+
3
+ ## Architecture
4
+
5
+ Modern C application with safety-first design. C17 as baseline standard (C23 where compiler support allows), CMake for build system, comprehensive static analysis and sanitizer pipeline, structured testing with Unity or CMocka.
6
+
7
+ ---
8
+
9
+ ## Core Technologies
10
+
11
+ - **Language**: C17 (ISO/IEC 9899:2018), C23 features where supported
12
+ - **Compilers**: GCC 13+ / Clang 17+ (both required to compile cleanly)
13
+ - **Build System**: CMake 3.25+ (modern target-based)
14
+ - **Package Management**: vcpkg, Conan 2, or vendored dependencies
15
+ - **Formatting**: clang-format 17+
16
+ - **Static Analysis**: clang-tidy, cppcheck, Coverity (CI)
17
+
18
+ ---
19
+
20
+ ## Key Libraries
21
+
22
+ ### Core Utilities
23
+ - **libuv**: Cross-platform async I/O (event loop, TCP, UDP, pipes, timers)
24
+ - **jansson** or **cJSON**: JSON parsing and generation
25
+ - **libcurl**: HTTP client with TLS support
26
+ - **zlib**: Compression
27
+
28
+ ### Data Structures & Algorithms
29
+ - **uthash**: Hash table macros (header-only)
30
+ - **sds**: Simple Dynamic Strings (Redis-derived)
31
+ - **stb**: Single-header libraries (image, truetype, etc.)
32
+
33
+ ### Logging & Diagnostics
34
+ - **log.c**: Simple C logging library (or custom structured logger)
35
+ - **libbacktrace**: Stack trace generation for crash reporting
36
+
37
+ ### Cryptography & Security
38
+ - **OpenSSL** / **mbedTLS**: TLS and cryptographic operations
39
+ - **libsodium**: Modern, easy-to-use crypto primitives
40
+
41
+ ---
42
+
43
+ ## Development Standards
44
+
45
+ ### Code Quality
46
+ - **clang-format**: Automated formatting (`.clang-format` in repo root)
47
+ - **clang-tidy**: Lint and modernize checks
48
+ - **cppcheck**: Additional static analysis (finds what clang-tidy misses)
49
+ - **pre-commit hooks**: Run format and lint before each commit
50
+
51
+ ### Security & Safety
52
+ - **AddressSanitizer (ASan)**: Buffer overflows, use-after-free, memory leaks
53
+ - **MemorySanitizer (MSan)**: Uninitialized memory reads (Clang only)
54
+ - **UndefinedBehaviorSanitizer (UBSan)**: Integer overflow, null deref, alignment
55
+ - **ThreadSanitizer (TSan)**: Data races in multithreaded code
56
+ - **Valgrind**: Heap profiling and leak detection (when sanitizers unavailable)
57
+
58
+ ### Testing
59
+ - **Unity**: Lightweight unit test framework (single .c/.h)
60
+ - **CMock**: Mock generation for Unity (parses headers)
61
+ - **CMocka 2.0**: Alternative with built-in mocking and TAP output
62
+ - **AFL++ / libFuzzer**: Fuzz testing for parsing and input handling
63
+
64
+ ---
65
+
66
+ ## Development Environment
67
+
68
+ ### Required Tools
69
+ - GCC 13+ or Clang 17+
70
+ - CMake 3.25+
71
+ - Make or Ninja
72
+ - clang-format, clang-tidy
73
+ - Valgrind (Linux) or Leaks (macOS)
74
+ - gdb or lldb
75
+
76
+ ### Common Commands
77
+ ```bash
78
+ # Build
79
+ cmake -B build -DCMAKE_BUILD_TYPE=Debug
80
+ cmake --build build
81
+
82
+ # Build with sanitizers
83
+ cmake -B build-asan -DCMAKE_BUILD_TYPE=Debug \
84
+ -DCMAKE_C_FLAGS="-fsanitize=address,undefined -fno-omit-frame-pointer"
85
+ cmake --build build-asan
86
+
87
+ # Tests
88
+ ctest --test-dir build --output-on-failure
89
+
90
+ # Code quality
91
+ clang-format -i src/**/*.c include/**/*.h
92
+ clang-tidy src/*.c -- -Iinclude
93
+ cppcheck --enable=all --suppress=missingInclude src/
94
+
95
+ # Valgrind
96
+ valgrind --leak-check=full --show-leak-kinds=all ./build/myapp
97
+
98
+ # Coverage
99
+ cmake -B build-cov -DCMAKE_BUILD_TYPE=Debug \
100
+ -DCMAKE_C_FLAGS="--coverage"
101
+ cmake --build build-cov
102
+ ctest --test-dir build-cov
103
+ gcovr --root . --html --html-details -o coverage/index.html
104
+ ```
105
+
106
+ ---
107
+
108
+ ## Key Technical Decisions
109
+
110
+ | Decision | Rationale |
111
+ |----------|-----------|
112
+ | **C17 over C11** | Bug fixes and clarifications; wide compiler support; stable baseline |
113
+ | **CMake over Make** | Target-based dependency management, cross-platform, IDE integration |
114
+ | **Unity over Check** | Minimal footprint, no library dependency, embedded-friendly |
115
+ | **clang-format + clang-tidy** | Single toolchain for formatting and linting, excellent C support |
116
+ | **Sanitizers over Valgrind-only** | Faster execution, compile-time instrumentation, CI-friendly |
117
+ | **vcpkg/Conan over manual vendoring** | Reproducible builds, version pinning, transitive dependency resolution |
118
+ | **C23 opt-in, not default** | Compiler support still maturing; adopt features like nullptr, auto, constexpr incrementally |
119
+
120
+ ---
121
+
122
+ _Document standards and patterns, not every dependency. See coding-style.md for detailed C conventions._