Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .gitconfig-darwin
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
[user]
email = kincaidoneil@users.noreply.github.com
name = Kincaid O'Neil
email = kincaidoneil@users.noreply.github.com
name = Kincaid O'Neil
signingkey = ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA+62vYiqoYgGwJ2TC1CJUlqBfF3iBFwKHFwnVO08gFy
[commit]
gpgsign = true
gpgsign = true
[gpg]
format = ssh
[gpg "ssh"]
program = /Applications/1Password.app/Contents/MacOS/op-ssh-sign
[core]
editor = code --wait
editor = code --wait
[init]
defaultBranch = main
defaultBranch = main
[push]
autoSetupRemote = true
14 changes: 7 additions & 7 deletions .gitconfig-linux
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
[user]
email = kincaidoneil@users.noreply.github.com
name = Kincaid O'Neil
signingKey = DA3BAC238DFEC340740E4C2E16666E7D706EB0FF
email = kincaidoneil@users.noreply.github.com
name = Kincaid O'Neil
signingKey = DA3BAC238DFEC340740E4C2E16666E7D706EB0FF
[commit]
gpgsign = true
gpgsign = true
[gpg]
program = gpg
program = gpg
[core]
editor = code --wait
editor = code --wait
[init]
defaultBranch = main
defaultBranch = main
[push]
autoSetupRemote = true
44 changes: 44 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Test Install

on:
push:
branches: [main]
pull_request:

jobs:
test:
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v4

- name: Remove pre-installed Node
run: |
# macOS
sudo rm -f /opt/homebrew/bin/node
sudo rm -f /opt/homebrew/bin/npm
sudo rm -f /opt/homebrew/bin/npx
# Linux
sudo rm -f /usr/local/bin/n
sudo rm -f /usr/local/bin/node
sudo rm -f /usr/local/bin/npm
sudo rm -f /usr/local/bin/npx

- name: Run install script
run: bash install.sh

- name: Verify installations
shell: zsh {0}
run: |
# Check dotfiles are symlinked
test -L ~/.zshrc
test -L ~/.gitconfig

# Check key commands exist
command -v brew
command -v node
command -v cargo
command -v zsh
32 changes: 10 additions & 22 deletions .zshrc
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,21 @@
export N_PREFIX="$HOME/n"; [[ :$PATH: == *":$N_PREFIX/bin:"* ]] || PATH+=":$N_PREFIX/bin"

# Bun completions
[ -s "/Users/kincaid/.bun/_bun" ] && source "/Users/kincaid/.bun/_bun"
[ -s "$HOME/.bun/_bun" ] && source "$HOME/.bun/_bun"

# Bun
export BUN_INSTALL="$HOME/.bun"
export PATH="$BUN_INSTALL/bin:$PATH"

# pnpm
export PNPM_HOME="/Users/kincaid/Library/pnpm"
case ":$PATH:" in
*":$PNPM_HOME:"*) ;;
*) export PATH="$PNPM_HOME:$PATH" ;;
esac

# Claude Code and other things
export PATH="$HOME/.local/bin:$PATH"

# Homebrew (only if directory exists/on Darwin)
[ -d "/opt/homebrew" ] && eval "$(/opt/homebrew/bin/brew shellenv)"

# Make OpenSSL available in PATH on Apple Silicon
[ -d "/opt/homebrew" ] && export PATH="/opt/homebrew/opt/openssl@3/bin:$PATH"
if [ -d "/opt/homebrew" ]; then
eval "$(/opt/homebrew/bin/brew shellenv)"
# Make OpenSSL available in PATH on Apple Silicon
export PATH="/opt/homebrew/opt/openssl@3/bin:$PATH"
fi

# Config a better version of ls and tree view
alias ls="eza -lhmua --group-directories-first"
Expand All @@ -35,19 +29,13 @@ bindkey "^[[1;5D" backward-word
bindkey '^H' backward-kill-word
bindkey '5~' kill-word

# Export helper to stop and remove all running Docker containers
# Clean up Docker containers, images, networks, and volumes
function docker-clean {
running_containers=$(docker ps -q)
if [[ -z "$running_containers" ]]
then
echo "No Docker containers running."
else
docker stop $(docker ps -q)
docker rm $(docker ps -a -q)
fi
docker stop $(docker ps -q) 2>/dev/null || true

Copilot AI Oct 31, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there are no running containers, docker ps -q returns empty output, causing docker stop to be called with no arguments, which may produce an error message despite the || true. Consider checking if containers exist first: [ -n \"$(docker ps -q)\" ] && docker stop $(docker ps -q) before running the system prune.

Suggested change
docker stop $(docker ps -q) 2>/dev/null || true
[ -n "$(docker ps -q)" ] && docker stop $(docker ps -q) 2>/dev/null || true

Copilot uses AI. Check for mistakes.
docker system prune -af --volumes
}

# Zi initializaiton
# Zi initialization
source "$HOME/.zi/bin/zi.zsh"
autoload -Uz _zi
(( ${+_comps} )) && _comps[zi]=_zi
Expand Down
59 changes: 29 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,34 +1,47 @@
## Kincaid's Config
## Kincaid's Dotfiles

### Install

To install on a fresh Linux box, create new user account as `root`:
#### On macOS or Linux

Run the install script to set up packages and dotfiles:

```bash
source <(curl -s https://raw.githubusercontent.com/kincaidoneil/dotfiles/main/add-user.sh)
curl -s https://raw.githubusercontent.com/kincaidoneil/dotfiles/main/install.sh | bash
```

On Linux or macOS, run install script for packages and settings:
This will:
- Install Homebrew (if not present)
- Install all development tools and runtimes
- Symlink dotfiles (`.zshrc`, `.gitconfig`)
- Configure Zsh with plugins

#### On a Fresh Linux Server (as root)

To create a new user account with sudo access:

```bash
curl -s https://raw.githubusercontent.com/kincaidoneil/dotfiles/main/install.sh | bash -s
curl -s https://raw.githubusercontent.com/kincaidoneil/dotfiles/main/add-user.sh | bash
```

Installs packages with `apt` on Debian, or `brew` on macOS.
Then switch to the new user and run the install script above.

### Authentication

Use 1Password to [manage SSH keys](https://developer.1password.com/docs/ssh/) and configure [SSH commit signing](https://developer.1password.com/docs/ssh/git-commit-signing).

#### Configure GPG commit signing
<details>
<summary><strong>Alternative: Manual GPG/SSH Setup (Legacy)</strong></summary>

_(Skip if using 1Password and/or SSH commit signing.)_
#### Configure GPG Commit Signing

Import GPG secret key:

```bash
gpg --import [PATH]
```

If the key is expired, GPG may cryptically fail to sign with a `No secret key` error. To extend it:
If the key is expired, extend it:

```bash
gpg --edit-key [KEY_ID]
Expand All @@ -37,25 +50,23 @@ gpg --edit-key [KEY_ID]
> save
```

Use an [older revision](https://github.com/kincaidoneil/dotfiles/blob/315dbe3b078480ced80b398e016c152980369c18/.gitconfig-darwin) of `.gitconfig-[PLATFORM]` so Git and GPG place nice, and add the relevant signing key.
You'll need to use an [older revision](https://github.com/kincaidoneil/dotfiles/blob/315dbe3b078480ced80b398e016c152980369c18/.gitconfig-darwin) of `.gitconfig-[PLATFORM]` and manually install GPG tools (`brew install gpg2 pinentry-mac`).

#### Generate new SSH key

_(Prefer using 1Password to generate new keys.)_
#### Generate New SSH Key

```bash
ssh-keygen -o -a 100 -t ed25519 -f ~/.ssh/id_ed25519
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
```

#### Add SSH pubkey to remote
#### Add SSH Pubkey to Remote Server

Add `~/.ssh/id_ed25519.pub` on client on a newline in the `~/.ssh/authorized_keys` file on the server. Refer [here](https://cryptsus.com/blog/how-to-secure-your-ssh-server-with-public-key-elliptic-curve-ed25519-crypto.html) for more background.
Add `~/.ssh/id_ed25519.pub` contents to `~/.ssh/authorized_keys` on the remote server. See [this guide](https://cryptsus.com/blog/how-to-secure-your-ssh-server-with-public-key-elliptic-curve-ed25519-crypto.html) for more details.

#### Add SSH config
#### Add SSH Config

To simplify connecting, add the server as an entry in the `~/.ssh/config` file on the client:
Simplify SSH connections by adding entries to `~/.ssh/config`:

```
Host <NAME>
Expand All @@ -64,16 +75,4 @@ Host <NAME>
UseKeychain yes
```

### Cleanup

```bash
cd ~
rm -rf \
n \
.cargo \
.rustup \
.npm \
.zi \
.zshrc \
.gitconfig
```
</details>
Loading
Loading