Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
159 changes: 159 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
# AGENTS.md

Guidance for coding agents working in **macOS-setup-scripts**.

## Repository summary

- Bash automation for provisioning a development-focused macOS environment (Homebrew, dotfiles, `defaults write`, and related setup).
- Orchestrator: `src/scripts/master.sh`; shared helpers: `src/scripts/utils.sh`.
- Dotfiles live in the `src/dotfiles/` git submodule (do not edit unless the task explicitly requires submodule changes).
- User-facing docs: `README.md`.
- CI on pull requests:
- **Quality Checks** (`.github/workflows/quality-checks.yaml`) — markdownlint, Prettier, ShellCheck, yamllint via [garretpatten/quality-checks](https://github.com/garretpatten/quality-checks).
- **Test Runner** (`.github/workflows/test-runner.yaml`) — runs scripts on `macos-latest` (skips heavy steps in `pre-install.sh`).

## Layout

```text
src/scripts/ # Setup phases (*.sh); source utils.sh with shellcheck directives
src/dotfiles/ # Submodule — separate repo; excluded from root Prettier runs
src/assets/ # Static assets (e.g. wolf.txt)
.github/workflows/ # GitHub Actions
```

## Shell script conventions

- Use `#!/bin/bash` and `set` behavior consistent with neighboring scripts.
- Source shared code with a ShellCheck hint, for example:

```bash
# shellcheck source=utils.sh
source "${SCRIPT_DIR}/utils.sh"
```

- Prefer `utils.sh` helpers (`log_error`, `ensure_directory`, `copy_file_safe`, and so on) over duplicating logic.
- Append recoverable command failures with `2>>"$ERROR_LOG_FILE" || true` where other scripts already do.
- Keep changes scoped to the requested task; avoid unrelated refactors or drive-by formatting outside touched files.

## Linter configuration

| Tool | Config | Notes |
| ----------------- | ------------------------------------------- | ------------------------------------------------ |
| markdownlint-cli2 | `.markdownlint.yaml`, `.markdownlintignore` | MD013 (line length) is off |
| Prettier | `.prettierrc`, `.prettierignore` | `src/dotfiles/` is ignored at repo root |
| ShellCheck | `.shellcheckrc` | `external-sources=true`, `source-path=SCRIPTDIR` |
| yamllint | `.yamllint` | Line length max 80; `document-start` disabled |

## Required quality gate

**Before you finalize any change** (end of task, commit, or PR), you **must** run all four linters below on every file you added or modified (and on any new files you created). Do not skip this step.

1. Fix reported issues (use auto-fix flags where noted).
2. Re-run checks until all four pass.
3. In your final message, state that the four linters passed or list anything you could not run and why.

If a tool is missing locally, install it (see [Prerequisites](#prerequisites)) or use the `npx` / `pip3` invocations below. Do not mark work complete while known lint failures remain in changed paths.

## Prerequisites

From the repository root:

```bash
npm ci
```

Install CLI tools if needed (macOS examples):

```bash
brew install shellcheck
pip3 install yamllint
npm install -g markdownlint-cli2 # optional; npx works without global install
```

Prettier is provided by this repo’s `package.json` after `npm ci`.

## Running linters

Run commands from the **repository root** so config files are discovered.

### Changed files only (typical)

Set a diff base (adjust branch name if needed):

```bash
BASE_REF="${BASE_REF:-origin/master}"
git fetch origin master 2>/dev/null || true
```

Collect paths you changed:

```bash
mapfile -t MD_FILES < <(git diff --name-only --diff-filter=ACMR "${BASE_REF}"...HEAD | grep -E '\.(md|markdown)$' || true)
mapfile -t SH_FILES < <(git diff --name-only --diff-filter=ACMR "${BASE_REF}"...HEAD | grep -E '\.(sh|bash|zsh)$' || true)
mapfile -t YAML_FILES < <(git diff --name-only --diff-filter=ACMR "${BASE_REF}"...HEAD | grep -E '\.(yml|yaml)$' || true)
mapfile -t PRETTIER_FILES < <(git diff --name-only --diff-filter=ACMR "${BASE_REF}"...HEAD | grep -E '\.(js|jsx|ts|tsx|json|css|scss|md|yml|yaml)$' || true)
```

Then run (skip a tool when its file list is empty):

```bash
# markdownlint — check
[[ ${#MD_FILES[@]} -gt 0 ]] && markdownlint-cli2 "${MD_FILES[@]}"

# markdownlint — fix, then re-check
[[ ${#MD_FILES[@]} -gt 0 ]] && markdownlint-cli2 --fix "${MD_FILES[@]}"

# Prettier — check (matches CI)
[[ ${#PRETTIER_FILES[@]} -gt 0 ]] && npx prettier --no-error-on-unmatched-pattern --check "${PRETTIER_FILES[@]}"

# Prettier — write, then re-check
[[ ${#PRETTIER_FILES[@]} -gt 0 ]] && npx prettier --no-error-on-unmatched-pattern --write "${PRETTIER_FILES[@]}"

# ShellCheck
[[ ${#SH_FILES[@]} -gt 0 ]] && shellcheck "${SH_FILES[@]}"

# yamllint
[[ ${#YAML_FILES[@]} -gt 0 ]] && yamllint "${YAML_FILES[@]}"
```

Without a global `markdownlint-cli2`:

```bash
npx --yes markdownlint-cli2 "${MD_FILES[@]}"
npx --yes markdownlint-cli2 --fix "${MD_FILES[@]}"
```

### Full-repo checks (when unsure what changed)

Use when you touched many paths or want parity with a broad local sweep:

```bash
npx --yes markdownlint-cli2 "**/*.md"
npx prettier --no-error-on-unmatched-pattern --check .
shellcheck src/scripts/*.sh
yamllint .github .yamllint .markdownlint.yaml
```

Prettier honors `.prettierignore` (including `src/dotfiles/`). Yamllint loads `.yamllint` from the current directory.

## Typical validation order

1. **Shell** (`.sh` under `src/scripts/`): `shellcheck`
2. **YAML** (`.github/`, root `*.yaml` / `*.yml`): `yamllint`
3. **Markdown**: `markdownlint-cli2` (fix with `--fix` if needed)
4. **Prettier** (JSON, Markdown, YAML, and other supported types in scope): `prettier --check` after any `--write`

## Before finishing (checklist)

- [ ] `markdownlint-cli2` passed on all changed Markdown files
- [ ] `npx prettier --check` passed on all changed files Prettier handles (respecting `.prettierignore`)
- [ ] `shellcheck` passed on all changed shell scripts
- [ ] `yamllint` passed on all changed YAML files
- [ ] No unrelated files were reformatted or lint-fixed outside the task scope
- [ ] If a linter could not be run, that fact is called out explicitly in the summary

## Commits and pull requests

- Create commits only when the user asks.
- Pull requests are validated by **Quality Checks** and **Test Runner**; local runs above should match CI behavior for the four linters.
- Do not modify `src/dotfiles/` unless the task requires it; submodule changes have their own workflow in that repository.
Loading