diff --git a/bin/git-close-pull-request b/bin/git-close-pull-request
deleted file mode 100755
index 67f3673d..00000000
--- a/bin/git-close-pull-request
+++ /dev/null
@@ -1,271 +0,0 @@
-#!/usr/bin/env php
-<?php
-
-declare(strict_types=1);
-
-/**
- * Usage: git close-pull-request -t <target>
- *
- * Run this from a branch which has an upstream remote branch, and an associated
- * pull request.
- *
- * The script will merge the branch into master, push master (which will
- * automatically close the pull request), and delete both the local and remote
- * branches.
- *
- * Based on a script by @christoomey. Translated into PHP.
- */
-
-class ClosesPullRequests
-{
-    private $targetBranch;
-    private $localBranch;
-    private $remoteBranch;
-
-    private const RUN_TYPE_COMMAND = 'command';
-    private const RUN_TYPE_QUERY = 'query';
-
-    public function __construct()
-    {
-        $this->localBranch = $this->run(
-            'git rev-parse --abbrev-ref HEAD',
-            self::RUN_TYPE_QUERY
-        );
-        $this->targetBranch = $this->getTargetBranchFromArgs();
-
-        $this->remoteBranch = $this->run(
-            'git rev-parse --abbrev-ref --symbolic-full-name @{u}',
-            self::RUN_TYPE_QUERY
-        );
-        $this->remoteBranch = str_replace('origin/', '', $this->remoteBranch);
-    }
-
-    public function __invoke(): void
-    {
-        $this->confirmCiStatusIsPassing();
-        // TODO: Check that the current branch has a tracking branch.
-        $this->ensureWorkingDirectoryAndIndexAreClean();
-        $this->fetchOrigin();
-        $this->ensureFeatureBranchInSync();
-        $this->ensureTargetBranchInSync();
-        $this->checkoutTargetBranch();
-        $this->mergeLocalBranch();
-        $this->pushTargetBranch();
-        $this->deleteRemoteBranch();
-        $this->deleteLocalBranch();
-    }
-
-    private function ensureWorkingDirectoryAndIndexAreClean(): void
-    {
-        echo 'Ensuring that index and working directory are clean...' . PHP_EOL;
-
-        $isIndexClean = $this->run('git diff --cached --exit-code', self::RUN_TYPE_COMMAND);
-        $isWorkingDirClean = $this->run('git diff --exit-code', self::RUN_TYPE_COMMAND);
-
-        if (!$isIndexClean || !$isWorkingDirClean) {
-            $this->dieWithMessage('Index or working dir not clean. Aborting.');
-        }
-    }
-
-    private function getTargetBranchFromArgs(): string
-    {
-        if (!$targetBranchName = $this->getArg('t:', ['target:'])) {
-            $this->dieWithMessage('Invalid target branch specified. Aborting.');
-        }
-
-        return $targetBranchName;
-    }
-
-    private function confirmCiStatusIsPassing(): void
-    {
-        if ($this->isForce()) {
-            echo 'Forced. Skipping ci-status check...' . PHP_EOL;
-            return;
-        }
-
-        echo 'Confirming ci-status on PR is green...' . PHP_EOL;
-
-        $passedCi = $this->run('gh pr checks', self::RUN_TYPE_COMMAND);
-
-        // TODO: Check if there are no CI checks. Does this return `true` as well?
-        if (!$passedCi) {
-            $this->dieWithMessage('CI pending or failed.');
-        }
-    }
-
-    private function fetchOrigin(): void
-    {
-        print 'Fetching origin to confirm local and remote in sync...'
-            . PHP_EOL;
-
-        $this->run('git fetch origin', self::RUN_TYPE_COMMAND);
-    }
-
-    private function ensureTargetBranchInSync(): void
-    {
-        $this->ensureBranchInSyncWithUpstream(
-            $this->targetBranch,
-            $this->targetBranch
-        );
-    }
-
-    private function ensureFeatureBranchInSync(): void
-    {
-        $this->ensureBranchInSyncWithUpstream(
-            $this->localBranch,
-            $this->remoteBranch
-        );
-    }
-
-    private function ensureBranchInSyncWithUpstream(
-        string $localBranch,
-        string $remoteBranch
-    ): void {
-        echo sprintf(
-            'Ensuring that %s is in sync with its upstream...',
-            $localBranch
-        ) . PHP_EOL;
-
-        $localCommitTip = $this->tipCommitOfBranch($localBranch);
-        $remoteCommitTip = $this->tipCommitOfBranch(sprintf(
-            'origin/%s',
-            $remoteBranch
-        ));
-
-        if ($localCommitTip != $remoteCommitTip) {
-            $this->dieWithMessage(sprintf(
-                'Branch %s was out of date, needs rebasing. Aborting.',
-                $localBranch
-            ));
-        }
-    }
-
-    private function tipCommitOfBranch(string $branchName): string
-    {
-        return $this->run(
-            sprintf('git rev-parse %s', $branchName),
-            self::RUN_TYPE_QUERY
-        );
-    }
-
-    private function checkoutTargetBranch(): void
-    {
-        echo sprintf('Checking out %s...' . PHP_EOL, $this->targetBranch);
-
-        $this->run(
-            sprintf('git checkout %s', $this->targetBranch),
-            self::RUN_TYPE_COMMAND
-        );
-    }
-
-    private function mergeLocalBranch(): void
-    {
-        echo sprintf(
-            'Merging %s into %s...' . PHP_EOL,
-            $this->localBranch,
-            $this->targetBranch
-        );
-
-        $mergeCommand = sprintf('git merge --ff-only %s', $this->localBranch);
-        if (!$this->run($mergeCommand, self::RUN_TYPE_COMMAND)) {
-            // Switch back to the previous branch.
-            $this->run('git checkout -', self::RUN_TYPE_COMMAND);
-
-            $this->dieWithMessage(sprintf(
-                'Branch %s is not fast-forwardable.',
-                $this->localBranch
-            ));
-        }
-    }
-
-    public function pushTargetBranch(): void
-    {
-        print(sprintf('Pushing updated %s branch...', $this->targetBranch));
-
-        $this->run(
-            sprintf('git push origin %s', $this->targetBranch),
-            self::RUN_TYPE_COMMAND
-        );
-    }
-
-    public function deleteRemoteBranch(): void
-    {
-        echo 'Deleting remote branch...' . PHP_EOL;
-
-        $this->run(
-            sprintf('git push origin :%s', $this->remoteBranch),
-            self::RUN_TYPE_COMMAND
-        );
-    }
-
-    public function deleteLocalBranch(): void
-    {
-        echo 'Deleting local branch...' . PHP_EOL;
-
-        $this->run(
-            sprintf('git branch -d %s', $this->localBranch),
-            self::RUN_TYPE_COMMAND
-        );
-    }
-
-    private function getArg(string $shortOpts, array $longOpts = []): ?string
-    {
-        if (!$values = getopt($shortOpts, $longOpts)) {
-            return NULL;
-        }
-
-        return current($values);
-    }
-
-    private function hasArg(string $shortOpts, array $longOpts = []): bool
-    {
-        return !empty(getopt($shortOpts, $longOpts));
-    }
-
-    private function isForce(): bool
-    {
-        return $this->hasArg('f::', ['force::']);
-    }
-
-    /**
-     * Run the command.
-     *
-     * @return bool|string
-     *   If the type is 'command', the method will return if there were any
-     *   errors when running the command based on its return code.
-     *
-     *   If the type is 'query', then the output of the command will be returned
-     *   as a string.
-     */
-    private function run(string $command, string $type)
-    {
-        switch ($type) {
-            case self::RUN_TYPE_COMMAND:
-                // Perform the command, hiding the original output and return
-                // whether or not there were errors.
-                @exec("$command", $output, $return);
-
-                return $return == 0;
-
-            case self::RUN_TYPE_QUERY:
-                // Perform the command and return the output.
-                return exec($command, $output);
-        }
-    }
-
-    private function dieWithMessage(string $message): void
-    {
-        echo sprintf("\e[31m%s\e[0m", $message);
-
-        exit(1);
-    }
-
-    private function exitWithWarning(string $message): void
-    {
-        echo sprintf("\e[33m%s\e[0m", $message);
-
-        exit(2);
-    }
-}
-
-(new ClosesPullRequests())->__invoke();
diff --git a/bin/git-create-new-tracking-branch b/bin/git-create-new-tracking-branch
deleted file mode 100755
index 0a14fb4b..00000000
--- a/bin/git-create-new-tracking-branch
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/sh
-
-set -e
-
-if [ "$#" -lt 1 ]; then
-  echo "Error: Not enough arguments."
-  exit l
-fi
-
-# Create a new branch including any additional arguments.
-git checkout -b "$@"
-
-# Push the branch to origin, bypassing any Git hooks.
-new_branch_name=$1
-git push --no-verify -u origin "${new_branch_name}:opd-${new_branch_name}"
diff --git a/bin/git-delete-merged-branches b/bin/git-delete-merged-branches
deleted file mode 100755
index 77e7fc00..00000000
--- a/bin/git-delete-merged-branches
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/usr/bin/env php
-<?php
-
-function extractBranchNamesFromInfo(string $branchInfo): array
-{
-    $branchNames = array_map(function (string $branchInfo): string {
-        preg_match('/\s*((\w|-|\/)+)\s*/', $branchInfo, $matches);
-
-        return $matches[1] ?? '';
-    }, explode(PHP_EOL, $branchInfo));
-
-    return array_filter($branchNames);
-}
-
-function filterIgnoredBranches(array $branchNames): array
-{
-    return array_filter($branchNames, function (string $branchName): bool {
-        return !in_array($branchName, ['develop', 'master', 'staging', 'production']);
-    });
-}
-
-$branchInfo = shell_exec('git branch -vv | grep ": gone]"');
-
-# Return early if there are no branches to delete.
-if ($branchInfo === NULL) {
-  return;
-}
-
-$branchNames = extractBranchNamesFromInfo($branchInfo);
-$filteredBranchNames = filterIgnoredBranches($branchNames);
-
-$currentBranch = exec('git rev-parse --abbrev-ref HEAD');
-
-foreach ($filteredBranchNames as $branchName) {
-    if ($branchName == $currentBranch) {
-        echo "Cannot delete {$branchName} as it is the current branch.";
-        continue;
-    }
-
-    echo "Deleting {$branchName}...";
-    exec("git branch -D ${branchName}");
-}
diff --git a/bin/git-master-to-main-wrapper b/bin/git-master-to-main-wrapper
deleted file mode 100755
index bfef84b5..00000000
--- a/bin/git-master-to-main-wrapper
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/env zsh
-
-# Usage: instead of
-#
-#     git rebase -i master
-#
-# run this:
-#
-#     git master-to-main-wrapper rebase -i %BRANCH%
-#
-# It will replace the literal string `%BRANCH%` with "main" (preferred) or
-# "master" depending on what the current repository uses.
-
-command=$*
-branchname=$(main-or-master-branch)
-replaced_commands=$(echo $command | sed "s/%BRANCH%/$branchname/g")
-# sh_glob ignores special meaning of parentheses so that fancy logs like this
-# work: `git master-to-main-wrapper log --format='%w(78)%s%n%+b'`
-zsh -c "setopt sh_glob; git ${replaced_commands}"
\ No newline at end of file
diff --git a/bin/git-opr b/bin/git-opr
deleted file mode 100755
index 642f5f56..00000000
--- a/bin/git-opr
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/bin/bash
-
-set -e
-
-ensure_is_published() {
-  [[ ! $is_published ]] && git publish
-}
-
-is_published() {
-  echo $(git upstream)
-}
-
-open_or_build_pull_request() {
-  type gh &>/dev/null
-
-  if [ $? -ne 0 ]; then
-    echo "Error: gh command not found."
-    exit 1
-  fi
-
-  # Load an existing PR, or create a new one.
-  gh pr view --web || gh pr create --assignee opdavies --web
-}
-
-ensure_is_published
-open_or_build_pull_request
diff --git a/bin/git-publish b/bin/git-publish
deleted file mode 100755
index ca196bf7..00000000
--- a/bin/git-publish
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/usr/bin/env php
-<?php
-
-/**
- * Usage: git publish
- */
-
-$currentBranch = exec('git rev-parse --abbrev-ref HEAD');
-
-if (in_array($currentBranch, ['develop', 'main', 'master', 'staging', 'production'])) {
-    print "Currently on ${currentBranch}. Aborting.";
-    exit(1);
-}
-
-exec("git push -u origin $currentBranch:opd-{$currentBranch}");
diff --git a/bin/git.sh b/bin/git.sh
deleted file mode 100755
index 9be64daa..00000000
--- a/bin/git.sh
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/bash
- 
-# The MIT License (MIT)
-# Copyright (c) 2013 Alvin Abad
- 
-if [ $# -eq 0 ]; then
-    echo "Git wrapper script that can specify an ssh-key file
-Usage:
-    git.sh -i ssh-key-file git-command
-    "
-    exit 1
-fi
- 
-# remove temporary file on exit
-trap 'rm -f /tmp/.git_ssh.$$' 0
- 
-if [ "$1" = "-i" ]; then
-    SSH_KEY=$2; shift; shift
-    echo "ssh -i $SSH_KEY \$@" > /tmp/.git_ssh.$$
-    chmod +x /tmp/.git_ssh.$$
-    export GIT_SSH=/tmp/.git_ssh.$$
-fi
- 
-# in case the git command is repeated
-[ "$1" = "git" ] && shift
- 
-# Run the git command
-git "$@"
diff --git a/bin/phpunit-or-pest b/bin/phpunit-or-pest
deleted file mode 100755
index 781b7124..00000000
--- a/bin/phpunit-or-pest
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/usr/bin/env bash
-
-if [[ -f "vendor/bin/pest" ]]; then
-  echo "pest"
-  exit 0
-fi
-
-echo "phpunit"
diff --git a/bin/tmuxinator-fzf b/bin/tmuxinator-fzf
deleted file mode 100755
index 595a9fa2..00000000
--- a/bin/tmuxinator-fzf
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/usr/bin/env bash
-
-# Use fzf to select a project to open with tmuxinator.
-
-set -euo pipefail
-
-tmuxinator list -n | tail -n +2 | fzf | xargs tmuxinator start
diff --git a/bin/watch-changes b/bin/watch-changes
deleted file mode 100755
index 2978e290..00000000
--- a/bin/watch-changes
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/usr/bin/env bash
-
-if [ "$1" ] && [ "$2" ]; then
-  while true
-  do
-    inotifywait --event modify --exclude ".null-ls_*" --recursive $1 2> /dev/null
-    $2
-  done
-else
-  echo "usage: watch-changes <file> <command>"
-fi