Agent skill
uroot
u-root utility implementation patterns (streaming I/O, error format, symlinks)
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/other/uroot
SKILL.md
u-root Utils Integration
This skill covers implementing u-root utility commands in Invowk.
Use this skill when working on:
internal/uroot/- u-root utility implementations- Adding new built-in shell utilities
- Modifying u-root command behavior
Terminology
Standardized naming conventions:
- Project name: "u-root" (lowercase with hyphen) — use in prose, documentation, and comments
- Go identifiers: "uroot" (lowercase, no hyphen) — use for package names, types, and variables
- Config option:
enable_uroot_utils— existing schema, follows Go/CUE convention
Examples:
- Prose: "The u-root integration provides built-in utilities..."
- Package:
internal/uroot/ - Type:
UrootCommand,UrootHandler - Function:
tryUrootBuiltin() - Config:
virtual_shell.enable_uroot_utils: true
Rationale: Consistent terminology reduces confusion. The hyphenated form matches the upstream project name (github.com/u-root/u-root), while the unhyphenated form follows Go naming conventions (hyphens are not allowed in identifiers).
Streaming I/O Requirement
CRITICAL: All u-root utility implementations MUST use streaming I/O for file operations.
Never buffer entire file contents into memory, regardless of file size. This rule ensures:
- Predictable memory usage independent of input size
- No OOM conditions when processing large files
- Consistent behavior across all file sizes
Required Pattern
// CORRECT: Streaming copy with proper close handling
func copyFile(src, dst string) (err error) {
srcFile, err := os.Open(src)
if err != nil {
return err
}
defer func() { _ = srcFile.Close() }() // Read-only source; close error non-critical
dstFile, err := os.Create(dst)
if err != nil {
return err
}
defer func() {
if closeErr := dstFile.Close(); closeErr != nil && err == nil {
err = closeErr
}
}()
_, err = io.Copy(dstFile, srcFile) // Streams in chunks
return err
}
Anti-Patterns to Avoid
// WRONG: Loads entire file into memory
data, err := os.ReadFile(src)
if err != nil {
return err
}
err = os.WriteFile(dst, data, 0644)
// WRONG: Buffering entire content
content, _ := io.ReadAll(reader)
writer.Write(content)
Applies To
All u-root utility implementations that handle file content:
cp- File copyingmv- File moving (when cross-filesystem)cat- File concatenationhead/tail- File viewinggrep- Pattern matching (line-by-line streaming)sort- Sorting (may require temp files for large inputs)wc- Word/line counting (streaming counters)
Exception: Sorting Large Files
sort may need to use temporary files for inputs that exceed available memory. This is acceptable as it's the standard approach used by GNU sort (-T tempdir). The key constraint remains: never hold unbounded data in heap memory.
Symlink Handling
Default behavior: Follow symlinks (copy target content, not the link).
This matches standard POSIX cp behavior and prevents symlink-based path traversal attacks.
cp source destwheresourceis a symlink → copies the target file contentcp -r dir/ dest/wheredir/contains symlinks → copies target contents, not links- Symlink preservation requires explicit
-Pflag (when supported)
Security Rationale
Following symlinks by default prevents:
- Symlink attacks where a malicious link points outside the intended directory
- Accidental exposure of sensitive files via symlink indirection
- Unexpected behavior when copying between filesystems
Unsupported Flag Handling
When a u-root utility receives flags it doesn't support (e.g., GNU-specific extensions like --color):
- Silently ignore the unsupported flag
- Execute the command with supported flags only
- Do NOT emit warnings or errors for unknown flags
This matches common cross-platform behavior where BSD utilities ignore GNU-specific flags.
Error Reporting Format
All errors from u-root utilities MUST be prefixed with [uroot].
This prefix clearly identifies the error source, distinguishing u-root implementation errors from system utility errors and aiding debugging.
Required Format
[uroot] <command>: <error message>
Examples
[uroot] cp: cannot stat 'missing': No such file or directory
[uroot] mv: cannot move 'src' to 'dst': Permission denied
[uroot] cat: /path/to/file: Is a directory
[uroot] mkdir: cannot create directory 'existing': File exists
Implementation Pattern
// CORRECT: Prefix errors with [uroot]
func (h *CpHandler) Run(ctx context.Context, args []string) error {
// ... implementation ...
if err != nil {
return fmt.Errorf("[uroot] cp: %w", err)
}
return nil
}
// WRONG: Raw error without prefix
func (h *CpHandler) Run(ctx context.Context, args []string) error {
if err != nil {
return fmt.Errorf("cp: %w", err) // Missing [uroot] prefix!
}
return nil
}
Rationale
- Users can immediately identify whether an error comes from u-root or system utilities
- Simplifies debugging when both u-root and system utilities are used in the same script
- Enables targeted troubleshooting of u-root implementations vs environment issues
Common Pitfalls
- Buffering file contents - Always use
io.Copy()or similar streaming patterns. Never useos.ReadFile()orio.ReadAll()for arbitrary user files. - Missing error prefix - All u-root errors must include the
[uroot]prefix for source identification. - Naked defer Close() - Never use
defer f.Close(). For read-only files, usedefer func() { _ = f.Close() }()with comment. For write operations, use named returns to capture close errors.
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
Didn't find tool you were looking for?