AgentSkillsCN

Hashimoto

Hashimoto

SKILL.md

Mitchell Hashimoto — CLI & Infrastructure Mastery

Write CLI tools and infrastructure software in the style of Mitchell Hashimoto, founder of HashiCorp (Vagrant, Packer, Terraform, Consul, Vault, Nomad) and creator of Ghostty.

Core Philosophy

1. Human-Friendly by Default, Machine-Parseable by Flag

code
# Default: human-readable
$ corey status
✓ GitHub CLI: authenticated as @user
✓ Git config: user.email configured
✗ SSH agent: no keys loaded

# Machine: structured output
$ corey status --json
{"github_cli":{"status":"ok","user":"user"},"git_config":{"status":"ok"},"ssh_agent":{"status":"error","message":"no keys loaded"}}

2. Progressive Disclosure

  • Simple commands do simple things
  • Advanced behavior via explicit flags
  • Never surprise the user with implicit actions

3. Composable Unix Tools

  • Single responsibility per command
  • Stdin/stdout for pipelines
  • Exit codes are contracts (0=success, 1=user error, 2=system error)

CLI Design Principles

Command Structure

code
<tool> <noun> <verb> [flags] [args]

corey credential list
corey credential get github.com
corey credential set github.com --from-gh
corey sync pull --source=gh
corey sync push --target=git-credential

Flag Conventions

  • --json — machine-readable output
  • --porcelain — stable output for scripts
  • --verbose / -v — show what's happening
  • --dry-run — preview without modification
  • --force — skip confirmations (dangerous)
  • --quiet / -q — suppress non-error output

Error Messages

code
Error: GitHub CLI not authenticated

  The `gh` CLI is installed but not logged in.

  To fix this, run:
    gh auth login

  Or use a different credential source:
    corey sync pull --source=git-credential

Always provide:

  1. What went wrong
  2. Why it matters
  3. How to fix it

Secrets Management (Vault-Inspired)

Never Store Secrets in Plain Text

  • Use OS keychain (libsecret on Linux, Keychain on macOS)
  • Encrypt at rest with user-derived key
  • Memory-safe handling (zero on drop)

Audit Trail

  • Log credential access (not values)
  • Support --audit-log for compliance

Principle of Least Privilege

  • Request only needed scopes
  • Support credential expiry
  • Rotate on schedule

Configuration Philosophy

Layered Configuration

code
1. CLI flags (highest priority)
2. Environment variables
3. Local config (.corey/config.toml)
4. User config (~/.config/corey/config.toml)
5. System config (/etc/corey/config.toml)
6. Compiled defaults (lowest priority)

Config File Format

toml
# Prefer TOML: readable, typed, no footguns

[defaults]
output = "human"  # or "json"
color = "auto"    # or "always", "never"

[sources.github]
priority = 1
enabled = true

[targets.git-credential]
enabled = true

Implementation Patterns

Subcommand Dispatch

zig
const commands = .{
    .{ "credential", @import("cmd/credential.zig") },
    .{ "sync", @import("cmd/sync.zig") },
    .{ "status", @import("cmd/status.zig") },
    .{ "config", @import("cmd/config.zig") },
};

pub fn main() !void {
    const args = try std.process.argsAlloc(allocator);
    if (args.len < 2) return showHelp();
    
    inline for (commands) |cmd| {
        if (std.mem.eql(u8, args[1], cmd[0])) {
            return cmd[1].run(args[2..]);
        }
    }
    return error.UnknownCommand;
}

Graceful Degradation

zig
fn getCredential(host: []const u8) !Credential {
    // Try sources in priority order
    if (tryGitHubCLI(host)) |cred| return cred;
    if (tryGitCredential(host)) |cred| return cred;
    if (tryKeychain(host)) |cred| return cred;
    return error.NoCredentialFound;
}

Testing Philosophy

Test the Interface, Not Implementation

  • Run CLI as subprocess
  • Verify stdout, stderr, exit code
  • Test with real (mock) credentials

Golden File Tests

code
tests/
  golden/
    status_ok.stdout
    status_ok.stderr
    status_ok.exitcode

When to Apply This Skill

  • Designing CLI argument parsing
  • Structuring subcommands
  • Handling credentials and secrets
  • Writing configuration systems
  • Creating human-friendly error messages
  • Building for both humans and scripts