Cross-platform Unix utilities in Zig with TDD workflow
A SKILL.md for working with vibeutils, a modern Zig implementation of GNU coreutils with OpenBSD engineering principles.
This skill helps you work with the vibeutils codebase - a cross-platform Unix utilities implementation in Zig. The project prioritizes correctness, simplicity, and modern UX (colors, progress bars) while maintaining compatibility with POSIX/GNU/BSD standards.
**Zero external users. Break things to fix them. No backwards compatibility.**
**Use agents for ANY code change beyond trivial fixes:**
1. **architect agent** → Design solution
2. **programmer agent** → Implement code
3. **reviewer agent** → Review quality
4. **optimizer agent** → Optimize if needed
5. **CRITICAL: Run `zig build test` before declaring success**
**Agent usage required for:**
**Direct coding only for:**
**Default: Use agents. When uncertain, use agents.**
**This project uses Zig 0.15.1. Your pre-0.11.0 knowledge has FUNDAMENTAL breaking changes.**
**Before writing ANY Zig code:**
1. Check `docs/ZIG_BREAKING_CHANGES.md` first
2. Grep that doc when you get errors
3. Verify patterns you think you know
**Common mistakes you WILL make:**
**Common pitfalls:**
**Prerequisites:** Integration tests require bash 4.0+ (macOS needs `brew install bash`)
```bash
make help # All available commands
make build # Build all utilities
make test # Run tests
make coverage # Generate coverage report (target 90%+)
make fmt # Format code
make build UTIL=chown
make test UTIL=chown
make run UTIL=chown ARGS="-h"
make fuzz UTIL=wc # Linux only
zig build test --summary all
zig build -Doptimize=ReleaseFast
```
**CRITICAL: Read `docs/TESTING_STRATEGY.md` before implementing filter utilities**
Filter utilities (tee, cat, sort, uniq) that read stdin will **hang in unit tests**. You must:
1. Identify if utility is filter-based
2. Use `runUtilWithInput()` pattern or skip unit tests
3. Ensure exit codes correct (`ExitCode.misuse` for arg errors)
4. Use 8192-byte buffers consistently
**Standard tests:**
**Privileged tests:**
**Fuzzing:**
**Target: 90%+ coverage**
**Key design decisions:**
1. **Common library pattern** (`src/common/`):
- Terminal capability detection (NO_COLOR, color modes)
- Error handling with program name prefixes
- Progress indicators
- Styling with graceful degradation
2. **TDD workflow:**
- Write failing tests first
- Implement minimal code to pass
- Add test cases for flags/edge cases
3. **Module structure:**
- Common library in `src/common/`
- Each utility in `src/<utility>.zig`
- Man pages in `man/man1/` (mdoc format)
1. Create `src/<utility>.zig` with embedded tests
2. Add to `build.zig`
3. Write tests first (TDD)
4. Create man page `man/man1/<utility>.1`
5. **Run FULL test suite**: `zig build test`
6. Verify no hangs: `timeout 60 zig build test`
7. Update TODO.md AFTER full suite passes
**Use mdoc format with sections:** NAME, SYNOPSIS, DESCRIPTION, EXIT STATUS, EXAMPLES, SEE ALSO, STANDARDS, AUTHORS
**Key rules:**
**Consult these sources when implementing:**
1. **POSIX.1-2017**: `https://pubs.opengroup.org/onlinepubs/9699919799/utilities/<command>.html`
- Authoritative standard
- Required behavior, flags, exit codes
2. **OpenBSD**: `https://man.openbsd.org/<command>`
- Security, simplicity, correctness focus
3. **GNU coreutils**:
- Linux: `man <command>`
- macOS: `man g<command>` (brew install coreutils)
- Online: `https://www.gnu.org/software/coreutils/manual/html_node/index.html`
**Strategy:**
**I/O pattern (Zig 0.15.1 Writergate):**
```zig
pub fn main() !void {
var stdout_buffer: [4096]u8 = undefined;
var stdout_writer = std.fs.File.stdout().writer(&stdout_buffer);
const stdout = &stdout_writer.interface;
defer stdout.flush() catch {};
}
pub fn runUtil(allocator: Allocator, args: []const []const u8,
stdout_writer: anytype, stderr_writer: anytype) !u8 {
common.printErrorWithProgram(allocator, stderr_writer, "util", "error: {s}", .{msg});
return @intFromEnum(common.ExitCode.general_error);
}
```
**Memory management:**
**Argument parsing:**
**System utilities implement functionality. The OS enforces security.**
```zig
// ❌ WRONG: Security theater
if (std.mem.indexOf(u8, path, "../") != null) return error.PathTraversal;
// ✅ RIGHT: Trust the OS
try std.fs.cwd().deleteFile(path);
```
**Validate only for correctness:**
**DON'T:** Add path validation, "protected" lists, prevent "../"
**DO:** Let OS handle permissions, report its errors
**Core docs (use Grep tool to find examples):**
**OrbStack:** `orb -m ubuntu zig build test`
**Docker:** `make test-linux`, `make shell-linux`, `make ci-linux`
Pre-commit hook automatically:
Located at `.git/hooks/pre-commit`
1. **Always use agent workflow** for non-trivial changes
2. **Check ZIG_BREAKING_CHANGES.md** before writing Zig code
3. **Read TESTING_STRATEGY.md** before implementing filter utilities
4. **Run full test suite** (`zig build test`) before declaring success
5. **Trust the OS** for security enforcement
6. **Target 90%+ coverage**
7. **TDD workflow**: tests first, then implementation
8. **Pre-1.0**: Break things to fix them, no backwards compatibility
Leave a review
No reviews yet. Be the first to review this skill!
# Download SKILL.md from killerskills.ai/api/skills/vibeutils-development/raw