b76e56f7502ae0dabec670516ca856ff19ebda33
Passing combined context inline as a CLI arg hits Linux ARG_MAX (~2 MB) when project CONTEXT.md or MEMORY.md are large. Three changes: 1. Write combined_context to a mktemp file and pass via --append-system-prompt-file instead of the inline --append-system-prompt arg. 2. Drop exec in favour of a subprocess call so the EXIT trap fires after claude exits, properly resetting the WezTerm theme and cleaning up the temp file. (With exec, bash is replaced immediately and traps never fire on success — WezTerm reset was silently broken.) 3. Warn when context exceeds 150 KB and show context size (in KB) on the launch line and in dryrun output, so oversized CONTEXT.md files are visible before they become a crash.
small-scripts
A collection of small, standalone utility scripts for daily use. Scripts are symlinked into ~/sbin for PATH availability.
Approach
This project uses spec-driven development (OpenSpec) as a testbed for agent-driven development and refinement:
- Every script starts with a spec in
specs/ - Every script supports
--dryrunto preview actions without side effects - Every script has a test in
tests/that validates dryrun behaviour against the spec
Scripts
| Script | Purpose | Status |
|---|---|---|
check-skills |
Verify Claude Code skill symlinks match source repo | Done |
claude-profile |
Claude Code profile + engagement-mode launcher | Done |
gen-secret |
Generate bash/YAML/JSON-safe random strings | Done |
git-status-report |
Recursive git repo status with diff stats | Done |
md-to-docx |
Markdown to DOCX conversion | Done |
mp3-to-mp4 |
Convert MP3 to MP4 with a static title card | Done |
split-wezterm |
Split WezTerm pane into a rows × cols grid | Done |
sync-repos |
Mirror git repos across remotes | Done |
unreflected-logs |
Scan projects for unreflected session logs | Done |
validate-skill |
Validate SKILL.md files against known Claude Code restrictions | Done |
semver-ci |
Compute MAJOR.MINOR.PATCH.BUILD from commit-message tokens, maintain VERSION.md, and (on main) tag/push/create a Gitea release — see docs/semver-ci.md and template at templates/gitea-workflow-version.yml |
Done |
wait-for-release |
Poll a Gitea repo's releases until a glob pattern matches or a timeout expires (default 600s) | Done |
Engagement modes (claude-profile)
claude-profile launches Claude Code with both a configuration profile (selecting which ~/.claude-* directory to use) and an engagement mode that bundles a driver model, subagent policy, async tolerance, and workflow stance:
| Mode | Driver | For |
|---|---|---|
chat |
Haiku | No project, just conversation |
quick |
Sonnet | Single small focused job, fully synchronous |
deep |
Sonnet (Opus via named workflows) | Hard design or debugging, plan + spec enforced |
hybrid |
Haiku (Opus/Sonnet on demand) | Long sessions, escalates only when needed |
orch |
Sonnet | Decompose work and dispatch container agents |
Mode definitions live in data/claude-profile/modes/<name>.md — YAML frontmatter (machine-parsed) plus a markdown body that becomes part of the system prompt.
claude-profile # interactive picker
claude-profile oreillyit --mode deep # explicit profile + mode
claude-profile --preset deep-cluster # named preset from presets.yaml
claude-profile --dryrun [...] # show resolved values, do not launch
Copy data/claude-profile/presets.yaml.example to $CLAUDE_CONFIG_DIR/presets.yaml to set up named presets.
Repository Structure
small-scripts/
├── scripts/ # Executable scripts (symlinked into ~/sbin)
├── specs/ # OpenSpec files, one per script
├── tests/ # Test scripts that exercise --dryrun
├── data/ # Read-only data files used by scripts
│ └── claude-profile/
│ ├── modes/ # Engagement mode definitions
│ └── presets.yaml.example
└── memory/ # Tiered memory topic files
Quick Start
# Run all tests
./tests/run-all.sh
# Symlink a script into ~/sbin
ln -sf "$(pwd)/scripts/<name>" ~/sbin/<name>
Milestones
| # | Description | Status |
|---|---|---|
| M1 | Project setup, first script | In progress |
Description
Languages
Shell
67.4%
Python
32.6%