- claude-profile: phase 1-3 picker (profile, mode, launch) with preset support, dryrun, WezTerm theming, and --append-system-prompt mode body injection - 5 mode files (chat/quick/deep/hybrid/orch) with YAML frontmatter + prose body; new escalates_to field drives statusline →Opus arrow for deep and hybrid - statusline.sh reads CLAUDE_CONFIG_DIR/active-mode.env to show [Sonnet→Opus] deep · topic format when launched via claude-profile - Root CLAUDE.md session-start: auto-selects project from cwd or CLAUDE_PROJECT in active-mode.env, skipping the interactive picker when context is clear - Spec, tests (37 assertions, 9 test files, all passing), context docs, and preset example included Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
3.9 KiB
3.9 KiB
CLAUDE.md — small-scripts
Overview
A collection of small, standalone utility scripts designed to be symlinked into ~/sbin. Development follows an agent-driven, spec-first workflow using OpenSpec — this project is the initial testbed for that approach.
Key Principles
- Spec-first development. Every script starts with an OpenSpec in
specs/. No implementation without a spec. - Dryrun by default. Every script MUST support a
--dryrun(or-n) flag that previews all actions without making changes. Dryrun output should clearly show what would happen. - Test via dryrun. Each script has a corresponding test script in
tests/that exercises the main script's--dryrunmode to verify behaviour matches the spec. - Symlink deployment. Scripts are linked to
~/sbinfor PATH availability — the repo is the source of truth, not the installed copy.
Repository Structure
small-scripts/
├── CLAUDE.md # This file — project conventions
├── MEMORY.md # Thin index linking to memory/ topic files
├── FUTURE.md # Backlog of ideas
├── README.md # Human-readable docs
├── specs/ # OpenSpec files (one per script)
│ └── <script-name>.spec.md
├── scripts/ # The actual scripts
│ └── <script-name>
├── tests/ # Test scripts (one per main script)
│ └── test-<script-name>.sh
├── data/ # Read-only data files consumed by scripts
│ └── <script-name>/ # One subdirectory per script that needs data
└── memory/ # Tiered memory topic files
└── log/ # Session logs
data/ directory
Some scripts need static data that is too large or too structured to embed inline (e.g. claude-profile reads engagement mode definitions from data/claude-profile/modes/*.md). Put such data under data/<script-name>/. Treat it as read-only at runtime — user customisation belongs in the user's config directory, not in data/. Example files (e.g. presets.yaml.example) live alongside the data and are copied by the user into their config dir.
Workflow
Adding a new script
- Write the spec — Create
specs/<script-name>.spec.mdusing OpenSpec format - Implement the script — Create
scripts/<script-name>, ensuring--dryrunsupport - Write the test — Create
tests/test-<script-name>.shthat validates dryrun output against spec expectations - Verify — Run the test, confirm pass
- Symlink —
ln -sf "$(pwd)/scripts/<script-name>" ~/sbin/<script-name>
Script conventions
- Scripts should be idempotent and safe to re-run
- Exit non-zero on failure
- Use colour output for status messages where appropriate
- Include a
--helpflag with usage information - Shebang line should specify the interpreter explicitly (e.g.,
#!/usr/bin/env bash,#!/usr/bin/env python3) --dryrun/-nmust be supported — it previews actions without side effects
Test conventions
- Test scripts live in
tests/and are namedtest-<script-name>.sh - Tests invoke the main script with
--dryrunand assert on output/exit codes - Tests should be runnable standalone:
./tests/test-<script-name>.sh - Use colour output (green/red) for pass/fail
- Exit non-zero if any assertion fails
- A top-level
./tests/run-all.shruns every test and summarises results
OpenSpec format
Specs define:
- Purpose — What the script does, in one sentence
- Usage — CLI interface, flags, arguments
- Behaviour — Step-by-step description of what the script does
- Dryrun behaviour — What
--dryrunoutputs (explicitly) - Edge cases — Known boundary conditions and expected handling
- Examples — Concrete input/output examples
Environment
- Scripts target Linux (Ubuntu/Debian primarily)
- Bash is the default language unless complexity warrants Python
~/sbinis in the user's PATH