Skip to content

Latest commit

 

History

History
69 lines (47 loc) · 5.09 KB

File metadata and controls

69 lines (47 loc) · 5.09 KB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Repository shape

A monorepo of independent utility modules. Each top-level directory (installer/, append-files/, secrets-sanitizer/, update-dns-a-record/, validate-path/) is a self-contained module with its own README.md, entry script, and — if installable — an install.yml. Modules do not share code; the only cross-module contract is the installer protocol below.

The installer protocol (read this before editing any module)

installer/install.sh is the stable public interface of this repo. Users invoke it as:

curl -sSL https://raw.githubusercontent.com/descoped/script-utils/master/installer/install.sh | bash -s -- <module_name>

It then:

  1. Downloads <module_name>/checksums.txt — the trust anchor. Missing checksums abort the install unless ALLOW_UNVERIFIED=1 is set (loud warning path).
  2. Downloads <module_name>/install.yml and verifies it against the checksums file before parsing (the manifest drives what gets installed, so it has to be authenticated first).
  3. Parses the YAML with hand-rolled bash regex (not a real YAML parser — see REQUIREMENTS §7). The supported grammar is a flat list of - file: entries with optional executable, create-symlink, destination keys. Do not expand this surface without switching to a real parser.
  4. Writes an installation plan to a pipe-delimited temp file, prompts /dev/tty for confirmation (bypassable with CONFIRM=1), then downloads each file to $INSTALL_DIR (default $HOME/bin), verifying each against checksums before chmod +x. destination entries land under $INSTALL_DIR/.<module>/<destination>/.

Configurable via env: INSTALL_DIR, CONFIRM, SCRIPT_UTILS_REF (commit SHA or branch for reproducible installs — the repo doesn't tag), SCRIPT_UTILS_OWNER, SCRIPT_UTILS_REPO, ALLOW_UNVERIFIED.

Breaking this contract (changing CLI args, YAML keys, target paths, env var names) requires a CHANGELOG.md entry in the same commit per REQUIREMENTS §9. A new installable module needs both install.yml and checksums.txt at the module root — regenerate checksums in the same commit that edits any installable file:

cd <module>/
shasum -a 256 *.sh *.py README.md install.yml > checksums.txt

REQUIREMENTS.md is binding

REQUIREMENTS.md is not aspirational — it's a merge blocker. Read it before changing any .sh file. The load-bearing rules:

  • §1 Bash 4.x, shebang #!/bin/bash. Documentation must say | bash -s --, never | sh -s -- (several existing READMEs still show sh — these are known gaps).
  • §2 Every .sh passes shellcheck --severity=style. Every script starts with set -euo pipefail unless explicitly justified. Use : > file, never bare > file. Every read uses -r.
  • §3 Integrity verification — any script that downloads code for execution must verify SHA-256 before chmod +x/bash/source. installer/install.sh currently violates this (known gap in REQUIREMENTS appendix); do not propagate the pattern to new code.
  • §4 Docs parity — every flag/env var/positional arg in code appears in the README, and vice versa. When you change one, change the other in the same commit.
  • §6 Idempotency — state-changing scripts must be re-runnable. Check [ -e ]/[ -L ] before creating; remove symlinks before recreating.
  • §7 Interactive prompts read from /dev/tty so the script works under curl | bash. Defaults go in readonly block at the top.

Per-module notes

append-files/ and secrets-sanitizer/

Bash wrapper + Python implementation. The .sh script does Python version gate, dependency install, and arg forwarding; the .py does the work.

  • append-files.sh detects uv (via [project] in pyproject.toml) and switches pip3 installuv pip install. Required packages: click pyperclip tqdm pyyaml.
  • append-files.py dynamically loads extract-code-signatures.py via importlib.util because of the hyphen in the filename. The transform feature (IDL/JSON output) degrades gracefully if that file is missing.
  • secrets-sanitizer is macOS-only — uses pbpaste/pbcopy directly in the wrapper. Don't add Linux support without reworking the clipboard layer.

update-dns-a-record/

Standalone root-only script for Route53 dynamic DNS via cron. No installer integration — users clone and edit PROFILE/HOSTED_ZONE_ID/HOSTNAME inline. Depends on aws CLI and jq.

validate-path/

Pure bash path diagnostics. validate-path.sh is trivial; analyze-path.sh and analyze-path-bash*.sh parse shell rc files. Not wired into the installer.

Verification commands

# Full repo lint sweep (REQUIREMENTS §2 / §10)
find . -name '*.sh' -print0 | xargs -0 shellcheck --severity=style
find . -name '*.sh' -print0 | xargs -0 -I{} bash -n {}

# Per-module smoke test
./secrets-sanitizer/test-secrets-sanitizer.sh   # the only existing test harness

There is no CI config checked in and no package-level test runner — test-secrets-sanitizer.sh is the only executable test suite.