Skip to content

Instantly share code, notes, and snippets.

View branneman's full-sized avatar

Bran van der Meer branneman

View GitHub Profile
@branneman
branneman / iterm2-claude-worktree-tab-titles.md
Last active July 21, 2026 22:28
Set up automatic iTerm2 tab titles for my Claude Code worktree workflow

Set up automatic iTerm2 tab titles for my Claude Code worktree workflow. Follow these steps exactly.

1. Create the script

Write the following to ~/.local/bin/tabtitle verbatim, then chmod +x it:

#!/usr/bin/env bash
# Rename this iTerm2 tab to the current worktree name (or $1 if given).
# Uses AppleScript, so it works from captured subprocesses like Claude Code tools.
@branneman
branneman / claude-worktree-path-guard.md
Created July 21, 2026 22:09
Claude Code worktree path guard

Claude Code worktree path guard

Personal setup notes + re-setup guide. This documents a PreToolUse hook added to global Claude Code settings on 2026-07-21 (in a session working on the bloomwatch repo) to stop a recurring class of mistake: work meant for a git worktree silently landing in the main checkout instead (or vice versa).

The problem this solves

When Claude Code works inside a git worktree (via the native EnterWorktree

@branneman
branneman / .gitignore
Last active March 31, 2026 14:09
Blizzard WoW Classic API
node_modules
.token.json
.env
@branneman
branneman / app.py
Last active June 7, 2025 14:14
Generating bidirectional Anki decks with Python from a CSV file
import csv
import genanki
from gtts import gTTS
import unicodedata
import re
import os
import sys
from pathlib import Path
if len(sys.argv) < 2:
@branneman
branneman / splitser.js
Last active January 22, 2025 09:38
Splitser algorithm
export const getSettlement = (transactions) => {
const settlement = []
let recurProtection = 0
while (true) {
const balances = getBalances(transactions.concat(settlement))
if (allBalancesZero(balances)) break
if (recurProtection++ > 1e2) {
console.log({ settlement })
$source = "C:\Program Files (x86)\World of Warcraft\_classic_era_\Screenshots"
$destination = "C:\Users\branv\Proton Drive\bran.van.der.meer\My files\70 - Backups\wow-classic\Screenshots"
$zipFolder1 = "C:\Program Files (x86)\World of Warcraft\_classic_era_\Interface"
$zipFolder2 = "C:\Program Files (x86)\World of Warcraft\_classic_era_\WTF"
$zipLocation = "C:\Users\branv\Proton Drive\bran.van.der.meer\My files\70 - Backups\wow-classic\"
$zipDate = Get-Date -Format "yyyy-MM-dd"
$zipFileName = "$zipLocation\wowclassic-backup-$zipDate.zip"
if (!(Test-Path -Path $destination)) {
@branneman
branneman / index.html
Created April 13, 2024 13:22
HTML5 Video: MediaSource, SourceBuffer, video segments, etc.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, viewport-fit=cover"
/>
<title>video test</title>
</head>
@branneman
branneman / six-nations-table.test.ts
Last active March 23, 2024 14:53
Six Nations table calculator
import { describe, expect, it } from 'vitest'
import { Table, Match } from './six-nations-table'
import {
matches2table,
updateTable,
getTable,
orderTable,
PgamesPlayed,
WgamesWon,
LgamesLost,
@branneman
branneman / index.js
Created December 6, 2023 15:15
Random person selector
const allPeople = ['Aisha', 'Amina', 'Anya', 'Carlos', 'Chen', 'Liam', 'Nia', 'Oliver', 'Raj', 'Yuki' ]
const peopleAlreadySpeaking = ['Anya', 'Raj']
const numberOfPeople = 2
// Fisher–Yates shuffle
function shuffle(list) {
const xs = list.slice()
let currentIndex = xs.length
let randomIndex
@branneman
branneman / components-app.tsx
Last active December 7, 2023 11:11
React useTranslation Hook
import { useState } from 'react'
import { Outlet } from 'react-router-dom' // you don't have to use this necessarily, just an example
import Header from 'components/Header'
import { makeTranslationValue } from 'hooks/translation'
import { TranslationContext } from 'context/translation'
import translations from 'data/translations.json'
export default function App() {