Skip to main content

Put on your company hat — switch between company environments

Project description

hat — Put On Your Company Hat

Version 1.0.1

A CLI tool for switching between multiple company environments. Manages VPN, SSH keys, cloud credentials, env vars, DNS, git identity, docker registries, browser profiles, tool installation, and git repo cloning.

Install

# From PyPI
uv tool install hatctl

# Or from GitHub
uv tool install git+https://github.com/apyatkin/personal-tools.git

Update

uv tool install hatctl --upgrade

# Or from GitHub
uv tool install git+https://github.com/apyatkin/personal-tools.git --force

Uninstall

uv tool uninstall hatctl

Shell Integration

Add to ~/.zshrc:

eval "$(hat shell-init zsh)"

This sources env vars, aliases, and completions on every prompt and adds a [company] indicator.

Quick Start

# Create a company config
hat init acme

# Or configure without editing YAML
hat config set acme git.identity.name "Your Name"
hat config set acme git.identity.email "you@acme.com"
hat config set acme cloud.nomad.addr "https://nomad.acme.com:4646"
hat config add-ssh acme ~/.ssh/acme_ed25519
hat config add-secret acme cloud.nomad.token_ref acme-nomad-token

# Put on your Acme hat
hat on acme

# What hat am I wearing?
hat status

# Switch to another company (takes off previous hat first)
hat on globex

# Take off your hat
hat off

Company Config

Each company lives in ~/Library/hat/companies/<name>/config.yaml. All sections are optional — only configure what you need:

name: acme
description: "Acme Corp"

git:
  identity:
    name: "Your Name"
    email: "you@acme.com"
  sources:
    - provider: gitlab
      host: gitlab.acme.com
      group: infrastructure
      token_ref: keychain:acme-gitlab-token
    - provider: github
      org: acme-oss
      token_ref: keychain:acme-github-pat

env:
  CUSTOM_VAR: value

ssh:
  keys:
    - ~/.ssh/acme_ed25519
  config: ~/Library/hat/companies/acme/ssh_config

vpn:
  provider: wireguard   # wireguard | amnezia | tailscale
  config: ~/Library/hat/companies/acme/wg0.conf
  interface: wg-acme

dns:
  resolvers:
    - 10.0.0.53
  search_domains:
    - acme.internal

hosts:
  entries:
    - "10.0.1.10 grafana.acme.internal"

cloud:
  aws:
    profile: acme-prod
    sso: true
  kubernetes:
    kubeconfig: ~/Library/hat/companies/acme/kubeconfig
    refresh:
      provider: yandex   # yandex | aws | digitalocean
      cluster: acme-k8s
  nomad:
    addr: https://nomad.acme.internal:4646
    token_ref: keychain:acme-nomad-token
  vault:
    addr: https://vault.acme.com:8200
    token_ref: keychain:acme-vault-token
  consul:
    addr: https://consul.acme.com:8500
    token_ref: keychain:acme-consul-token
  yandex:
    profile: acme
  digitalocean:
    context: acme
  hetzner:
    token_ref: keychain:acme-hcloud-token
  terraform:
    vars:
      backend_bucket: acme-tf-state

docker:
  registries:
    - host: registry.acme.com
      username_ref: keychain:acme-reg-user
      password_ref: keychain:acme-reg-pass

proxy:
  http: http://proxy.acme.com:3128
  https: http://proxy.acme.com:3128
  no_proxy: "*.acme.internal,10.0.0.0/8"

browser:
  profile: "Acme"
  app: google-chrome     # google-chrome | firefox | arc

apps:
  slack:
    workspace: acme-corp
  jira:
    host: acme.atlassian.net
    project: INFRA
    token_ref: keychain:acme-jira-token
  favro:
    organization_id: "org-123"
    token_ref: keychain:acme-favro-token

Config Without Editing YAML

# Set any config value
hat config set <company> <path> <value>

# Add SSH key (stored in Keychain, never on disk)
hat config add-ssh <company> <keychain-name> -f ~/.ssh/key
hat config add-ssh <company> <keychain-name>   # paste key, Ctrl-D

# Store secret in Keychain + add ref to config
hat config add-secret <company> <config-path> <keychain-name>
hat config add-secret <company> <config-path> <keychain-name> -f <file>

SSH keys stored in Keychain are extracted to a temporary file (0600 permissions) during hat on, loaded via ssh-add, and deleted on hat off. Keys never persist on disk.

Secrets

Secrets are referenced in config via *_ref fields and resolved at activation time from:

  • macOS Keychain: keychain:<service-name>
  • Bitwarden: bitwarden:<item>, bitwarden:<item>/password, bitwarden:<item>/field/<name>

Values are base64-encoded in Keychain to support multiline secrets (SSH keys, certs).

# Store a secret (paste multiline, Ctrl-D to finish)
hat secret set keychain:acme-gitlab-token

# Store from file (SSH keys, certs)
hat secret set keychain:acme-sshkey -f ~/.ssh/acme_ed25519

# Display a secret
hat secret get keychain:acme-gitlab-token

Repo Management

Clone all repos from a company's GitLab groups and GitHub orgs:

# Clone all repos (preserves GitLab subgroup structure)
hat repos clone acme

# Pull updates for all repos
hat repos pull acme

# Pull all companies
hat repos pull --all

# Show what's cloned vs missing
hat repos list acme

Repos are cloned to ~/projects/<company>/repos/.

Tool Management

Tools are defined globally in ~/projects/common/tools.yaml (not per-company). They're automatically checked on each hat on. Missing tools are installed, outdated tools are upgraded. Update checks are throttled to once per 24 hours.

# Generate default tools.yaml
hat tools init

# Edit to customize
$EDITOR ~/projects/common/tools.yaml

# Check tools without switching context
hat tools check
  • brew tools: installed via Homebrew
  • pipx tools: installed via uv tool (isolated Python venvs)

Shell Aliases & Completions

Generate global aliases and completions for all DevOps tools:

hat aliases generate       # ~/projects/common/aliases.sh
hat completions generate   # ~/projects/common/completions.sh

These are sourced automatically by hat shell-init zsh. Includes aliases like k for kubectl, tf for tofu, dc for docker compose, and completions for all tools.

Claude Code Skills

12 DevOps skills for Claude Code are included in skills/. Deploy them to make them available across all company repos:

# Set skills source in global config
mkdir -p ~/Library/hat
echo "skills_source: /path/to/personal-tools/skills" > ~/Library/hat/config.yaml

# Deploy skills as symlinks
hat skills deploy

Skills cover: GitLab, GitHub, Favro, Jira, Kubernetes, Helm, Terraform, Ansible, Nomad, Vault, Consul, Docker.

What Happens on hat on

Modules activate in this order (deactivate in reverse):

  1. tools — install/update required CLI tools
  2. vpn — connect VPN (prompts before sudo)
  3. dns — configure resolvers (prompts before sudo)
  4. hosts — add /etc/hosts entries (prompts before sudo)
  5. ssh — load SSH keys into agent
  6. git — set git identity via env vars
  7. cloud — set cloud credentials, run login commands
  8. env — export custom env vars
  9. docker — log into registries
  10. proxy — set proxy env vars
  11. browser — open browser with company profile
  12. apps — open Slack, etc.

State is tracked in ~/Library/hat/state.json so hat off and hat status work across shell restarts.

All Commands

hat on <company>                          put on a company hat
hat off                                   take off your hat
hat status                                what hat am I wearing?
hat list                                  list all hats
hat init <company>                        scaffold new company config

hat config set <company> <path> <value>   set a config value
hat config add-ssh <company> <key-path>   add SSH key to config
hat config add-secret <company> <path> <name>  store secret + add ref

hat repos clone <company>                 clone all repos
hat repos pull <company>                  pull updates
hat repos pull --all                      pull all companies
hat repos list <company>                  list local vs remote

hat secret set <ref>                      store a secret
hat secret set <ref> -f <file>            store from file
hat secret get <ref>                      display a secret

hat tools init                            generate tools.yaml
hat tools check                           check/install tools

hat aliases generate                      generate aliases.sh
hat completions generate                  generate completions.sh

hat skills deploy                         deploy Claude Code skills

hat shell-init zsh                        output shell integration code

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

hatctl-1.0.1.tar.gz (80.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

hatctl-1.0.1-py3-none-any.whl (26.9 kB view details)

Uploaded Python 3

File details

Details for the file hatctl-1.0.1.tar.gz.

File metadata

  • Download URL: hatctl-1.0.1.tar.gz
  • Upload date:
  • Size: 80.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for hatctl-1.0.1.tar.gz
Algorithm Hash digest
SHA256 d22dd97e13165c4119459097c74dd61cd627baef27e138bd7a60d7df17d5414a
MD5 d02a728f5143fadbb683cf7f32ac8092
BLAKE2b-256 181777ae3e2b7b3d6881e20a21f9f8eef2b3855acacb68602fc0480797fa887a

See more details on using hashes here.

Provenance

The following attestation bundles were made for hatctl-1.0.1.tar.gz:

Publisher: publish.yml on apyatkin/personal-tools

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file hatctl-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: hatctl-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 26.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for hatctl-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 f456f16827a29a2f2fb62f90c509efa44790b30e4db46243a8f313c72df6793e
MD5 7977b3846befee3c89588dbd9340319f
BLAKE2b-256 2d584c7d3478ee473f854a32d1afd607887f6c9895e23d0eff9309c0d97bd959

See more details on using hashes here.

Provenance

The following attestation bundles were made for hatctl-1.0.1-py3-none-any.whl:

Publisher: publish.yml on apyatkin/personal-tools

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page