Collection of tools and scripts made for personal use
A Python script for extending audio files by looping a specific section until a target duration is reached. Perfect for creating hour-long ambient music from shorter tracks.
The script takes an audio file and:
- Plays the beginning up to the loop start point
- Repeatedly loops a specified section until the minimum length is reached
- Plays the remainder of the original file after the loop end point
Preserves the original codec and bitrate when possible. Supports flexible time
formats (e.g., 1:30.5, 90s, 1h).
Usage:
./bin/extend-loop -i input.mp3 --loop-start 0:18.744 --loop-end 1:52.563 --min-length 1h --output extended.mp3Transcribes an audio file using mlx-whisper on Apple Silicon. Uses
kaiinui/kotoba-whisper-v2.0-mlx for Japanese and
mlx-community/whisper-large-v3-turbo for everything else. Live-prints each
segment with timestamps as it decodes, and writes .txt, .vtt, .srt,
.tsv, and .json files next to the input.
Usage:
transcribe-audio path/to/audio.mp3 --lang en
transcribe-audio path/to/audio.mp3 --lang jaSpeaker diarization with pyannote.audio 4.x
(pyannote/speaker-diarization-community-1). Prints start end speaker
ranges to stdout and writes an .rttm file next to the input. Optional
--num-speakers / --min-speakers / --max-speakers hints improve quality
when the count is known. Requires accepting the model license on HuggingFace
once and setting HF_TOKEN (or HUGGINGFACE_TOKEN) to a read token.
Usage:
export HF_TOKEN=hf_xxxxxxxxxxxx
diarize-audio path/to/audio.mp3
diarize-audio path/to/audio.mp3 --num-speakers 2Swift utilities to check if the microphone or camera is currently in use on
macOS. Returns exit code 0 if in use, 1 if not. Use -q for quiet mode (exit
code only).
A Ruby CLI tool for searching and displaying Claude Code conversation histories
from ~/.claude/projects/. Parses JSONL session files into structured data,
browse sessions by project, view full transcripts with timestamps, and search
activity by date.
Usage:
claude-history projects # List all projects
claude-history sessions --project myproject # List sessions in a project
claude-history show-session SESSION_ID --project myproject # Display a transcript
claude-history sessions-updated-on 2025-04-12 # Find sessions by dateFormats markdown files in-place. Wraps prose paragraphs and list items at 80
columns (preserving list continuation indent), leaves fenced and indented code
blocks alone, and never splits inline backtick spans. Pads table columns to
uniform width, wraps wide tables in <!-- markdownlint-disable MD013 -->
comments, and removes the wrapper from tables that no longer need it. All width
calculations are Unicode display-width aware (CJK and emoji count as 2 columns).
Finally runs markdownlint-cli2 --fix for general cleanup. Tables that fail to
parse are left untouched.
Usage:
format-md file1.md file2.mdA Ruby CLI for the Joplin note-taking app that communicates with Joplin's REST API. Supports listing notebooks/notes, searching, creating and managing notes/folders, adding and removing tags, and updating note content and metadata.
Usage:
export JOPLIN_TOKEN=your_token_from_joplin_settings
joplin folders # List all notebooks
joplin search "query" # Search notes
joplin create-note <folder-id> "Title" "Body" # Create noteA CLI tool for launching processes with encrypted environment variables. Stores
secrets securely in the macOS Keychain and prompts for approval before
injection, preventing plain-text .env files from being scattered around the
filesystem. Available in both Go and Ruby implementations.
Usage:
with-secure-env init # Generate and store encryption key
with-secure-env edit /path/to/app # Edit envs for an application
with-secure-env launch /path/to/app args # Launch with injected envsCommand-line tool for tracking work sessions, breaks, and lunch to generate timesheet data for employer reporting. Records start/stop events and automatically calculates daily and monthly work hours with overtime tracking.
Usage:
worktime start # Start a work session
worktime stop # End work
worktime lunch # Toggle lunch break
worktime status [DATE] # Show current status
worktime month [MONTH] # Show monthly overview with overtimeExports a Claude.ai conversation as a printable PDF. Two pieces:
- A Chrome extension that adds a floating "PDF" button to any
claude.ai/chat/*page. Clicking it opens a print-ready tab; pick Save as PDF from Chrome's print dialog. - A Node CLI (
render.mjs) that turns a conversation JSON into a standalone HTML file, ready to feed intochrome --headless --print-to-pdffor unattended export.
Both share the same renderer, which lays out text, thinking,
tool_use, and tool_result blocks with print-friendly CSS.
Usage (extension):
cd src/claude-chat-pdf-export && npm install && npm run build
# then chrome://extensions → Developer mode → Load unpacked →
# src/claude-chat-pdf-export/extensionUsage (CLI):
cd src/claude-chat-pdf-export && npm install
node render.mjs path/to/conv.json path/to/out.html
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \
--headless --disable-gpu --no-pdf-header-footer \
--print-to-pdf=out.pdf "file://$PWD/out.html"A single-page Markdown renderer. Split view: paste/edit Markdown on the left,
see it rendered with GitHub-style typography on the right. Each pane scrolls
independently. Pick from a few themes (GitHub Light, GitHub Dark, a serif
Reading theme, Solarized Light) and use the browser's print dialog to save
the rendered side as PDF. Content and theme persist in localStorage so the
page survives reloads. Runs from a single HTML file with CDN-loaded
marked, highlight.js,
and github-markdown-css.
Usage:
md-render # opens src/md-render/index.html in your default browserCustom Hammerspoon Spoons for macOS automation.