Skip to content

Setup.sh Reference

Nelson Spence edited this page Mar 17, 2026 · 2 revisions

Setup.sh Reference

setup.sh installs shared Claude Code rules from this repo into a target repository's .claude/rules/org/ directory. It supports symlink and copy modes, provenance tracking, and idempotent re-installation.

Usage

bash setup.sh /path/to/target-repo [OPTIONS]

The target directory must exist. It does not need to be a git repository, but a warning is printed if .git is absent.

Flags

Flag Description
--copy Copy files instead of symlinking (required on Windows without WSL)
--internal Also install custom rules from internal/ (requires confirmation)
--yes, -y Skip confirmation prompts (for CI/scripted usage)
--uninstall Remove all rules installed by this tool
--status Show what is currently installed
--dry-run Preview what would happen without making changes
--force Overwrite non-symlink files in org/ without prompting
--version Show version
--help Show usage help

Flags --uninstall and --status are mutually exclusive. All other flags compose freely. --dry-run works with both install and uninstall.

Provenance tracking

Each install writes a .claude-secure-config marker file to the target's org/ directory. The marker records:

  • Source path (where this repo lives on disk)
  • Timestamp (UTC ISO 8601)
  • Version
  • Install mode (--copy or symlink)

--status reads this marker to report installation details. --uninstall checks for the marker before removing files; without it, uninstall requires --force. If the marker is absent, the directory is reported as unmanaged.

After each install, the script scans org/ for orphaned files — files present in the destination that are no longer in the source — and reports them with a prompt to remove manually or run --uninstall.

Exit codes

Code Meaning
0 Success
1 Error (printed to stderr via die())

All fatal errors call die(), which prints Error: <message> to stderr and exits with code 1. Examples: target does not exist, conflicting flags, permission failure, non-interactive shell when confirmation is required.

If install is interrupted before the marker file is written, a cleanup trap warns on exit: Warning: Install was interrupted. Run --uninstall --force to clean up.

Common workflows

How do I install for the first time?

git clone https://github.com/Fieldnote-Echo/claude-secure-config.git
bash claude-secure-config/setup.sh /path/to/your-repo

By default, rules are symlinked. Add .claude/rules/org/ to your .gitignore so the symlinks are not committed.

How do I preview what will happen before installing?

bash setup.sh /path/to/your-repo --dry-run

Prints every action that would be taken — directory creation, file links or copies — without modifying anything.

How do I update to the latest rules?

Pull the latest version of this repo, then re-run:

git -C /path/to/claude-secure-config pull
bash /path/to/claude-secure-config/setup.sh /path/to/your-repo

Symlinks update automatically after git pull (no re-run needed). Copy mode (--copy) requires re-running to overwrite files.

How do I install on Windows or a filesystem that does not support symlinks?

bash setup.sh /path/to/your-repo --copy

Files are copied instead of symlinked. Re-run with --copy after pulling updates.

How do I install internal/private rules?

Place your private rule files (.md) in the internal/ directory of this repo (gitignored). Then:

bash setup.sh /path/to/your-repo --internal

The script lists the files found in internal/ and asks for confirmation before installing. To skip the prompt in CI:

bash setup.sh /path/to/your-repo --internal --yes

How do I check what is installed?

bash setup.sh /path/to/your-repo --status

Reports whether the directory is managed, the source path, install date, version, and lists every file with its link target or [BROKEN] if a symlink is dangling.

How do I uninstall?

bash setup.sh /path/to/your-repo --uninstall

Removes all .md files and the marker file from org/. Removes the org/ directory if it is empty afterward. Requires the marker file to be present; use --force to remove an unmanaged directory. Preview first with --dry-run:

bash setup.sh /path/to/your-repo --uninstall --dry-run

How do I run setup non-interactively (CI)?

bash setup.sh /path/to/your-repo --yes

--yes skips all confirmation prompts. Required when running in a non-interactive shell with --internal. Without --yes, a non-interactive shell will cause the script to exit with an error when internal rule confirmation is needed.

Notes

  • Requires bash 4+. Symlink mode requires a Unix-like OS (macOS, Linux, WSL).
  • Shared rules are installed from an explicit allowlist, not a wildcard glob, so adding a file to rules/ does not install it until the allowlist in setup.sh is updated.
  • The destination is always <target>/.claude/rules/org/.

See also: Installation Options | Hook Configuration | Customization Patterns