Compare commits

..

1 Commits

Author SHA1 Message Date
graham 229ff7dea0 2026-05-13 2026-05-13 20:09:01 -04:00
15 changed files with 380 additions and 56 deletions
+32 -17
View File
@@ -2,10 +2,11 @@ tap "charmbracelet/tap"
tap "dotenvx/brew"
tap "ghall89/tap"
tap "marsanne/cask"
tap "oven-sh/bun"
tap "simonbs/wut", "https://github.com/simonbs/wut.git"
tap "tw93/tap"
brew "age"
brew "xz"
brew "apfel"
brew "atuin"
brew "autoconf"
brew "automake"
@@ -28,6 +29,7 @@ brew "eza"
brew "fastfetch"
brew "fd"
brew "ffmpeg"
brew "fish"
brew "flyctl"
brew "fresh-editor"
brew "fzf"
@@ -58,20 +60,25 @@ brew "man2html"
brew "mas"
brew "micro"
brew "mint"
brew "mistral-vibe"
brew "nvm"
brew "oh-my-posh"
brew "openssl@1.1"
brew "pandoc"
brew "parallel"
brew "pkgconf"
brew "python@3.10"
brew "ripgrep"
brew "rubyfmt"
brew "rust"
brew "rust-analyzer"
brew "sf-pwgen"
brew "sops"
brew "speedtest-cli"
brew "swift-format"
brew "swiftformat"
brew "swiftdraw"
brew "swiftlint"
brew "tea"
brew "telnet"
brew "thefuck"
brew "toot"
@@ -85,18 +92,20 @@ brew "zig"
brew "zlib"
brew "zls"
brew "zoxide"
brew "charmbracelet/tap/crush"
brew "dotenvx/brew/dotenvx"
brew "oven-sh/bun/bun"
brew "simonbs/wut/wut"
brew "tw93/tap/mole"
cask "affinity"
cask "airbuddy"
cask "alfred"
cask "appflowy"
cask "applite"
cask "arq"
cask "ghall89/tap/autodock"
cask "bbedit"
cask "bettershot"
cask "butterkit"
cask "claude-code"
cask "coderabbit"
cask "codex"
cask "contexts"
@@ -104,15 +113,15 @@ cask "cork"
cask "daisydisk"
cask "devcleaner"
cask "discord"
cask "doppler-app"
cask "ea"
cask "equinox"
cask "find-any-file"
cask "fork"
cask "forklift"
cask "freetube"
cask "gb-studio"
cask "ghostty"
cask "gog-galaxy"
cask "gram"
cask "hazel"
cask "helium-browser"
cask "iina"
@@ -126,32 +135,31 @@ cask "ghall89/tap/keystash"
cask "mac-mouse-fix"
cask "mactracker"
cask "markedit"
cask "mullvad-vpn"
cask "musicbrainz-picard"
cask "nova"
cask "orbstack"
cask "orion"
cask "paletro"
cask "pearcleaner"
cask "postgres-unofficial"
cask "postgres-app"
cask "qlmarkdown"
cask "quicklook-json"
cask "rapidapi"
cask "rectangle-pro"
cask "rocket"
cask "slack"
cask "soulseek"
cask "spamsieve"
cask "steam"
cask "swift-shift"
cask "swiftformat-for-xcode"
cask "sync"
cask "tableplus"
cask "tuist"
cask "tunnelblick"
cask "utm"
cask "thaw"
cask "unclack"
cask "vscodium"
cask "whatsapp"
cask "windowkeys"
cask "xscope"
cask "yattee"
cask "zed"
cask "zen"
cask "zoom"
mas "Actions", id: 1586435171
@@ -160,11 +168,14 @@ mas "Affinity Photo 2", id: 1616822987
mas "Anybox", id: 1593408455
mas "Bakery", id: 1575220747
mas "Baking Soda", id: 1601151613
mas "Balatro", id: 6502451661
mas "Battery Indicator", id: 1206020918
mas "Bear", id: 1091189122
mas "brrr", id: 6755617665
mas "Codye", id: 1516894961
mas "Collections", id: 1568395334
mas "Color Picker", id: 1545870783
mas "Coppice", id: 6741889046
mas "Dato", id: 1470584107
mas "DevCleaner", id: 1388020431
mas "Developer", id: 640199958
@@ -176,12 +187,14 @@ mas "Folder Quick Look", id: 6753110395
mas "Front and Center", id: 1493996622
mas "Gifski", id: 1351639930
mas "HEIC Converter", id: 1294126402
mas "Ice Cubes", id: 6444915884
mas "Interactful", id: 1528095640
mas "Ivory", id: 6444602274
mas "JSON Peep", id: 1458969831
mas "Key Codes", id: 414568915
mas "Keynote", id: 361285480
mas "LiquidFetch", id: 6757637185
mas "Little Snitch Mini", id: 1629008763
mas "Lungo", id: 1263070803
mas "Mactracker", id: 430255202
mas "Mockup", id: 1527554407
@@ -191,8 +204,8 @@ mas "Page Screenshot for Safari", id: 1472715727
mas "Pages", id: 361309726
mas "Parcel", id: 375589283
mas "Pastel", id: 413897608
mas "Pixelmator Pro", id: 1289583905
mas "Pixelmator Pro", id: 6746662575
mas "Pixelmator Pro", id: 1289583905
mas "Pixen", id: 525180431
mas "Pocket City 2", id: 6742559886
mas "Pure Paste", id: 1611378436
@@ -201,8 +214,10 @@ mas "Shareful", id: 1522267256
mas "Sleeve", id: 1606145041
mas "Snippety", id: 1530751461
mas "Soulver 3", id: 1508732804
mas "Tapestry", id: 6448078074
mas "TestFlight", id: 899247664
mas "Text Workflow", id: 1600520682
mas "Textastic", id: 572491815
mas "Tot", id: 1491071483
mas "Transporter", id: 1450874784
mas "uBlock Origin Lite", id: 6745342698
@@ -210,12 +225,12 @@ mas "Velja", id: 1607635845
mas "Vinegar", id: 1591303229
mas "WhatsApp", id: 310633997
mas "WorldWideWeb", id: 1621370168
mas "Xcode", id: 497799835
vscode "akamud.vscode-theme-onelight"
vscode "astro-build.astro-vscode"
vscode "biomejs.biome"
vscode "bradlc.vscode-tailwindcss"
vscode "christian-kohler.npm-intellisense"
vscode "codeliger.pirate-map"
vscode "csstools.postcss"
vscode "dbaeumer.vscode-eslint"
vscode "dnicolson.binary-plist"
@@ -239,7 +254,7 @@ vscode "swiftlang.swift-vscode"
vscode "tamasfe.even-better-toml"
vscode "task.vscode-task"
vscode "teabyii.ayu"
vscode "vknabel.vscode-swiftformat"
vscode "vknabel.vscode-swiftlint"
vscode "ziglang.vscode-zig"
go "github.com/go-delve/delve/cmd/dlv"
go "github.com/golangci/golangci-lint/cmd/golangci-lint"
+58
View File
@@ -0,0 +1,58 @@
#!/usr/bin/env bash
set -euo pipefail
usage() {
cat <<'EOF'
Usage:
codex_guarded.sh [--cwd DIR] [--sandbox MODE] [--approval POLICY] [--] [codex args...]
Defaults:
--approval never
--sandbox read-only
--cwd current working directory
Description:
Launch Codex with deterministic non-interactive safety defaults.
EOF
}
CWD="$(pwd)"
SANDBOX="read-only"
APPROVAL="never"
FORWARD_ARGS=()
while [[ $# -gt 0 ]]; do
case "$1" in
--cwd)
CWD="$2"
shift 2
;;
--sandbox)
SANDBOX="$2"
shift 2
;;
--approval)
APPROVAL="$2"
shift 2
;;
-h|--help)
usage
exit 0
;;
--)
shift
FORWARD_ARGS+=("$@")
break
;;
*)
FORWARD_ARGS+=("$1")
shift
;;
esac
done
if [[ ${#FORWARD_ARGS[@]} -gt 0 ]]; then
exec codex -a "$APPROVAL" -s "$SANDBOX" -C "$CWD" "${FORWARD_ARGS[@]}"
else
exec codex -a "$APPROVAL" -s "$SANDBOX" -C "$CWD"
fi
+62
View File
@@ -0,0 +1,62 @@
#!/usr/bin/env bash
set -euo pipefail
usage() {
cat <<'EOF'
Usage:
guard_apply_patch.sh PATCH_FILE [--cwd DIR] [--allow-deletes] [--max-files N] [--max-changed-lines N] [--allow-path-prefix PREFIX ...]
Description:
Validates a patch and applies it only if policy checks pass.
EOF
}
if [[ "${1:-}" == "-h" || "${1:-}" == "--help" || "${#}" -lt 1 ]]; then
usage
exit 0
fi
PATCH_FILE="$1"
shift
CWD="$(pwd)"
VALIDATOR_ARGS=()
while [[ $# -gt 0 ]]; do
case "$1" in
--cwd)
CWD="$2"
shift 2
;;
--allow-deletes)
VALIDATOR_ARGS+=("$1")
shift
;;
--max-files|--max-changed-lines|--allow-path-prefix)
VALIDATOR_ARGS+=("$1" "$2")
shift 2
;;
*)
VALIDATOR_ARGS+=("$1")
shift
;;
esac
done
if [[ ! -f "$PATCH_FILE" ]]; then
echo "Patch file not found: $PATCH_FILE" >&2
exit 1
fi
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
VALIDATOR="$SCRIPT_DIR/guard_validate_patch.py"
python3 "$VALIDATOR" "$PATCH_FILE" --cwd "$CWD" "${VALIDATOR_ARGS[@]}"
echo "Validation passed. Running dry-run apply..."
patch -p1 --dry-run -d "$CWD" < "$PATCH_FILE"
echo "Applying patch..."
patch -p1 -d "$CWD" < "$PATCH_FILE"
echo "Done."
+166
View File
@@ -0,0 +1,166 @@
#!/usr/bin/env python3
"""
Generic patch validator scoped to a target working directory.
"""
from __future__ import annotations
import argparse
import pathlib
import re
import sys
DEFAULT_FORBIDDEN_BASENAMES = {
"Package.resolved",
"Podfile.lock",
"package-lock.json",
"yarn.lock",
"pnpm-lock.yaml",
"Cargo.lock",
"Gemfile.lock",
}
DEFAULT_FORBIDDEN_SUFFIXES = {
".xcconfig",
}
DEFAULT_FORBIDDEN_PATH_PATTERNS = (
re.compile(r"(^|/)\.git(/|$)"),
re.compile(r"(^|/)Info\.plist$"),
re.compile(r"(^|/)project\.pbxproj$"),
)
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description="Validate unified diff patch by policy.")
parser.add_argument("patch_file", type=pathlib.Path)
parser.add_argument("--cwd", type=pathlib.Path, default=pathlib.Path.cwd())
parser.add_argument("--max-files", type=int, default=12)
parser.add_argument("--max-changed-lines", type=int, default=2000)
parser.add_argument("--allow-deletes", action="store_true")
parser.add_argument(
"--allow-path-prefix",
action="append",
default=[],
help="Allowed path prefix relative to --cwd. Repeatable. Defaults to all paths under --cwd.",
)
return parser.parse_args()
def fail(message: str) -> None:
print(f"FAIL: {message}", file=sys.stderr)
raise SystemExit(1)
def normalize_patch_path(raw: str) -> str | None:
raw = raw.strip()
if raw == "/dev/null":
return None
if raw.startswith("a/") or raw.startswith("b/"):
raw = raw[2:]
return raw
def is_safe_relative_path(path: str) -> bool:
p = pathlib.PurePosixPath(path)
if p.is_absolute():
return False
if ".." in p.parts:
return False
if path.startswith("./"):
return False
return True
def main() -> None:
args = parse_args()
if not args.patch_file.exists():
fail(f"patch file not found: {args.patch_file}")
cwd = args.cwd.resolve()
if not cwd.exists() or not cwd.is_dir():
fail(f"--cwd is not a directory: {cwd}")
text = args.patch_file.read_text(encoding="utf-8")
lines = text.splitlines()
added_lines = 0
removed_lines = 0
touched_files: list[str] = []
deleted_files: list[str] = []
for line in lines:
if line.startswith("+++ "):
path = normalize_patch_path(line[4:])
if path:
touched_files.append(path)
continue
if line.startswith("+") and not line.startswith("+++"):
added_lines += 1
continue
if line.startswith("-") and not line.startswith("---"):
removed_lines += 1
for match in re.finditer(r"^--- (.+)\n\+\+\+ (.+)$", text, flags=re.MULTILINE):
before = normalize_patch_path(match.group(1))
after = normalize_patch_path(match.group(2))
if before and after is None:
deleted_files.append(before)
unique_files = sorted(set(touched_files + deleted_files))
if not unique_files:
fail("no file changes detected")
if len(unique_files) > args.max_files:
fail(f"too many files changed: {len(unique_files)} > {args.max_files}")
changed_line_count = added_lines + removed_lines
if changed_line_count > args.max_changed_lines:
fail(
f"too many changed lines: {changed_line_count} > {args.max_changed_lines}"
)
allowed_prefixes = [p.strip("/") for p in args.allow_path_prefix if p.strip("/")]
for rel_path in unique_files:
if not is_safe_relative_path(rel_path):
fail(f"unsafe path in patch: {rel_path}")
if allowed_prefixes and not any(
rel_path == prefix or rel_path.startswith(prefix + "/")
for prefix in allowed_prefixes
):
fail(f"path not in allowed prefixes: {rel_path}")
basename = pathlib.PurePosixPath(rel_path).name
if basename in DEFAULT_FORBIDDEN_BASENAMES:
fail(f"forbidden file basename: {rel_path}")
if any(rel_path.endswith(s) for s in DEFAULT_FORBIDDEN_SUFFIXES):
fail(f"forbidden file suffix: {rel_path}")
if any(pattern.search(rel_path) for pattern in DEFAULT_FORBIDDEN_PATH_PATTERNS):
fail(f"forbidden file path: {rel_path}")
target_path = cwd / rel_path
try:
target_path.resolve().relative_to(cwd)
except ValueError:
fail(f"path escapes cwd scope: {rel_path}")
if deleted_files and not args.allow_deletes:
fail(
"deletions are blocked (use --allow-deletes): "
+ ", ".join(sorted(set(deleted_files)))
)
print("OK: patch passed validation")
print(f"cwd={cwd}")
print(f"files={len(unique_files)} changed_lines={changed_line_count}")
if __name__ == "__main__":
main()
BIN
View File
Binary file not shown.
+1
View File
@@ -3,3 +3,4 @@
.mappsrc
.claude/
+5
View File
@@ -136,6 +136,7 @@ inline_height = 0
## Defaults to true. If enabled, upon hitting enter Atuin will immediately execute the command. Press tab to return to the shell and edit.
# This applies for new installs. Old installs will keep the old behaviour unless configured otherwise.
enter_accept = true
search_mode = "daemon-fuzzy"
## Defaults to "emacs". This specifies the keymap on the startup of `atuin
## search`. If this is set to "auto", the startup keymap mode in the Atuin
@@ -203,3 +204,7 @@ enter_accept = true
# This ensures that sync v2 is enabled for new installs only
# In a later release it will become the default across the board
records = true
[daemon]
enabled = true
autostart = true
+2 -2
View File
@@ -1,4 +1,4 @@
theme = dark: Andromeda,light: Alabaster
theme = dark: Andromeda,light: 3024 Day
macos-secure-input-indication = true
cursor-style = underline
@@ -16,7 +16,7 @@ window-padding-x = 5
window-padding-y = 5
window-padding-balance = true
background-opacity=0.93
background-opacity=0.98
background-blur=true
+5
View File
@@ -109,3 +109,8 @@
"version": 3,
"final_space": true
}
+26 -14
View File
@@ -20,7 +20,7 @@
"workbench.startupEditor": "none",
"editor.screenReaderAnnounceInlineSuggestion": false,
"[typescript]": {
"editor.defaultFormatter": "biomejs.biome"
"editor.defaultFormatter": "esbenp.prettier-vscode",
},
"accessibility.signalOptions.volume": 0,
"breadcrumbs.icons": false,
@@ -31,15 +31,15 @@
"breadcrumbs.enabled": false,
"terminal.integrated.fontLigatures.enabled": true,
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
"editor.defaultFormatter": "esbenp.prettier-vscode",
},
"editor.formatOnSave": true,
"terminal.external.osxExec": "Ghostty.app",
"[jsonc]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
"editor.defaultFormatter": "esbenp.prettier-vscode",
},
"[typescriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
"editor.defaultFormatter": "esbenp.prettier-vscode",
},
"terminal.integrated.fontSize": 14,
"terminal.integrated.fontFamily": "'MesloLGS NF', monospace",
@@ -49,7 +49,7 @@
"chat.commandCenter.enabled": false,
"codeium.enableInComments": false,
"[javascriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
"editor.defaultFormatter": "esbenp.prettier-vscode",
},
"editor.minimap.enabled": false,
"editor.scrollbar.verticalScrollbarSize": 6,
@@ -57,15 +57,15 @@
"javascript.format.enable": false,
"typescript.format.enable": false,
"[astro]": {
"editor.defaultFormatter": "astro-build.astro-vscode"
"editor.defaultFormatter": "astro-build.astro-vscode",
},
"workbench.preferredLightColorTheme": "FlatUI Immersed",
"workbench.preferredLightColorTheme": "Atom One Light",
"discord.suppressNotifications": true,
"[json]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
"editor.defaultFormatter": "esbenp.prettier-vscode",
},
"[html]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
"editor.defaultFormatter": "esbenp.prettier-vscode",
},
"redhat.telemetry.enabled": false,
"jest.runMode": "on-demand",
@@ -99,15 +99,15 @@
"editor.inlayHints.enabled": "offUnlessPressed",
"prettier.documentSelectors": ["**/*.ripple"],
"[ripple]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
"editor.defaultFormatter": "esbenp.prettier-vscode",
},
"makefile.configureOnOpen": false,
"svelte.enable-ts-plugin": true,
"[svelte]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
"editor.defaultFormatter": "esbenp.prettier-vscode",
},
"[scss]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
"editor.defaultFormatter": "esbenp.prettier-vscode",
},
"workbench.navigationControl.enabled": false,
"workbench.layoutControl.enabled": false,
@@ -115,6 +115,18 @@
"workbench.tree.renderIndentGuides": "none",
"swift.disableSwiftPackageManagerIntegration": true,
"[swift]": {
"editor.defaultFormatter": "vknabel.vscode-swiftformat"
}
"editor.defaultFormatter": "vknabel.vscode-swiftformat",
},
"json.schemaDownload.trustedDomains": {
"https://schemastore.azurewebsites.net/": true,
"https://raw.githubusercontent.com/": true,
"https://www.schemastore.org/": true,
"https://json.schemastore.org/": true,
"https://json-schema.org/": true,
"https://biomejs.dev": true,
},
"swiftlint.toolchainPath": "/opt/homebrew/bin/swiftlint",
"swift.disableSwiftlyInstallPrompt": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"terminal.integrated.initialHint": false,
}
+12 -18
View File
@@ -3,8 +3,8 @@
"context": "Workspace",
"bindings": {
"shift-cmd-b": "workspace::ToggleRightDock",
"cmd-w": null
}
"cmd-w": null,
},
},
{
"context": "Pane",
@@ -18,21 +18,21 @@
"cmd-7": ["pane::ActivateItem", 6],
"cmd-8": ["pane::ActivateItem", 7],
"cmd-9": ["pane::ActivateItem", 8],
"cmd-0": "pane::ActivateLastItem"
}
"cmd-0": "pane::ActivateLastItem",
},
},
{
"context": "Editor",
"bindings": {
"cmd-alt-right": "workspace::ActivateNextPane",
"cmd-alt-left": "workspace::ActivatePreviousPane"
}
"cmd-alt-left": "workspace::ActivatePreviousPane",
},
},
{
"context": "Terminal",
"bindings": {
"ctrl-`": "pane::CloseActiveItem"
}
"ctrl-`": "pane::CloseActiveItem",
},
},
{
"context": "Editor",
@@ -40,15 +40,9 @@
"cmd-w": [
"pane::CloseActiveItem",
{
"close_pinned": false
}
]
}
"close_pinned": false,
},
],
},
},
{
"context": "(Editor && !edit_prediction)",
"bindings": {
"alt": "editor::ShowEditPrediction"
}
}
]
+3 -4
View File
@@ -1,4 +1,5 @@
{
"cli_default_open_behavior": "new_window",
"sticky_scroll": {
"enabled": true,
},
@@ -14,9 +15,9 @@
"dock": "right",
},
"title_bar": {
"show_branch_status_icon": true,
"show_user_picture": false,
"show_sign_in": false,
"show_branch_icon": true,
},
"telemetry": {
"diagnostics": false,
@@ -28,6 +29,7 @@
"dock": "right",
},
"edit_predictions": {
"provider": "none",
"disabled_globs": [".md"],
"mode": "subtle",
},
@@ -35,9 +37,6 @@
"border_size": 0.0,
"inactive_opacity": 0.7,
},
"features": {
"edit_prediction_provider": "none",
},
"collaboration_panel": {
"button": false,
},
+1
View File
@@ -26,3 +26,4 @@ alias installbrewfile="brew bundle install --file=~/dotfiles/Brewfile"
alias config="bb ~/dotfiles"
alias linkdfs="sh ~/dotfiles/symlink_dotfiles.zsh"
alias cdot="sh ~/dotfiles/scripts/commit-dotfiles.sh"
+2 -1
View File
@@ -79,9 +79,10 @@ ZSH_THEME="robbyrussell"
gh
nvm
npm
gitignore
brew
thefuck
macos
pnpm-shell-completion
)
FPATH="$(brew --prefix)/share/zsh/site-functions:${FPATH}"
+5
View File
@@ -1,6 +1,9 @@
autoload -U +X bashcompinit && bashcompinit
autoload -U +X compinit && compinit
# Run brew-autoupdate
brew-autoupdate
eval "$(oh-my-posh init zsh --config ~/dotfiles/misc_config/ohmyposh.json)"
eval "$(wut init)"
@@ -28,3 +31,5 @@ fi
# Add RVM to PATH for scripting. Make sure this is the last PATH variable change.
export PATH="$PATH:$HOME/.rvm/bin"
. "$HOME/.atuin/bin/env"