Skip to content
Merged
Show file tree
Hide file tree
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
8 changes: 8 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ jobs:
done
exit $failed

validate-packages:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Validate packages.json schema
run: bash scripts/validate-packages.sh

dryrun-smoke:
runs-on: ubuntu-latest
steps:
Expand Down
7 changes: 7 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ repos:
types: [file]
files: (\.zsh$|zshrc\.example$)

- id: validate-packages
name: validate packages.json schema
language: system
entry: bash scripts/validate-packages.sh
files: ^packages\.json$
pass_filenames: false

- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
Expand Down
32 changes: 29 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,18 @@ tracked in TODO.md.)
## Entrypoints

- `setup.sh` — installs everything for the detected platform.
Flags: `--optional --work --personal --dry-run --platform <macos|ubuntu|arch|server> --profile <desktop|server>`.
Flags: `--optional --work --personal --base --tags <csv> --dry-run --platform <macos|ubuntu|arch|server> --profile <desktop|server>`.
The server platform is never auto-detected (`--profile server` or `--platform server` required).
Category selection: `--base` installs only the high-priority base set; `--tags
development,terminal` installs base + those `packages.json` tag categories
(enabled work/personal apps install regardless of category). Run bare on a TTY
with no selection flag and `core_maybe_prompt_selection` prompts interactively;
it is skipped on the server profile and in non-interactive/CI runs. The filter
is implemented by `tagok()` in `CORE_JQ_DEFS`, which reads `TAG_FILTER_ACTIVE`
and `SELECTED_TAGS` from the environment — inactive by default, so flag-driven
and CI runs are unchanged. The dedicated custom-install steps (tailscale,
claude-code, docker) gate on `pkg_selected` so they honor the selection too;
the server profile keeps the filter inactive, so they install as before there.
- `verify.sh` — read-only health check mirroring `setup.sh`'s selection logic.
Flags: `--optional --work --personal --all --platform <macos|ubuntu|arch>`
(no `--dry-run`; `--platform server`/`--profile server` is rejected — nothing
Expand All @@ -19,10 +29,23 @@ tracked in TODO.md.)

- `packages.json` — single source of truth for all package data. Managers are
keyed by platform (`{macos, ubuntu, arch, server}`); `<platform>_name`
overrides the install token; `environment` tags gate on `--work`/`--personal`;
overrides the install token; `environment` gates on `--work`/`--personal`;
`custom` managers carry `install_command` (string or per-platform object) —
run by the engine when `handled_by_setup` is true, otherwise printed as a
manual-install reminder.
- `priority`, `optional`, `environment`, and `install_command` each accept a
**scalar** (applies to every platform) **or a per-platform object** keyed by
platform (e.g. `"priority": { "macos": "medium", "ubuntu": "none" }`). The
engine resolves them via the `prfor`/`optfor`/`envfor`/`icfor` jq defs in
`lib/core.sh`. This is what lets one entry serve platforms that differ in
tier/optionality/gating, instead of splitting into duplicate entries.
- **`environment` caveat:** its scalar form is itself an *array* (`["work"]`),
so the per-platform form is detected as an *object* (`{ "ubuntu": ["work"] }`)
— array means legacy/all-platforms, object means per-platform. Keep the
per-platform value an object-of-arrays.
- `tags` — required non-empty array of descriptive categories from the
controlled vocabulary in `scripts/validate-packages.sh`. Metadata only
(grouping/docs); the install engine ignores them.
- `lib/core.sh` — shared engine: arg parsing, platform detection, env filter,
jq selection, install loops, config deploys. `lib/verify.sh` — check engine.
- `platforms/<platform>.sh` — per-platform quirks only (bootstrap, manager
Expand All @@ -47,7 +70,10 @@ phases.
## Conventions

- Pre-commit runs `shellcheck --severity=warning` on all shell scripts;
`zsh -n` checks `.zsh` files and `zshrc.example`.
`zsh -n` checks `.zsh` files and `zshrc.example`; `scripts/validate-packages.sh`
enforces the `packages.json` schema (platform vocabulary, controlled tag set,
and the "no silent drop" rule — every platform a package targets must resolve a
valid priority tier and a boolean optional). All three also run in CI.
- Probe semantics in `lib/verify.sh` are platform-faithful ports — macOS has no
`command -v` fallback for casks/pipx/app-store, Linux falls back everywhere.
Don't "fix" the asymmetry without checking `UNIFICATION.md` history.
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ For OS-specific software and install instructions, see:
1. Official GitHub CLI — create PRs, manage issues, clone repos, and run Actions from the terminal
3. pyenv | macOS · Linux | [GitHub](https://github.com/pyenv/pyenv) | [brew](https://formulae.brew.sh/formula/pyenv#default)
1. Python version and virtual environment manager
4. poetry | macOS · Linux · Windows | [GitHub](https://github.com/python-poetry/poetry)
1. Python project manager
4. uv | macOS · Linux · Windows | [Docs](https://docs.astral.sh/uv/) | [GitHub](https://github.com/astral-sh/uv) | [brew](https://formulae.brew.sh/formula/uv)
1. Fast Python package and project manager — pip/venv/pyenv successor
5. pipx | macOS · Linux · Windows | [GitHub](https://github.com/pypa/pipx) | [brew](https://formulae.brew.sh/formula/pipx)
1. Install Python CLI tools in isolated virtual environments so they don't pollute the global Python install
6. git-lfs | macOS · Linux · Windows | [Download](https://git-lfs.com/) | [GitHub](https://github.com/git-lfs/git-lfs) | [brew](https://formulae.brew.sh/formula/git-lfs)
Expand Down
Loading
Loading