curl ... | bash -s -- --update pulls the latest .ai/ files and exits without scanning projects or touching docs templates. Bootstrap captures the pre-pull commit hash and forwards it to local mode; local mode compares with HEAD and either reports "already up to date" or prints new commit messages with git log --oneline. FR-1.5 added to apply-requirements.md. README and apply.md updated.
117 lines
6.0 KiB
Markdown
117 lines
6.0 KiB
Markdown
# apply.sh — requirements
|
|
|
|
## Goal
|
|
|
|
A single bash script that gives any developer AI superpowers across all their projects in one command. Run once to set up, run again to repair. No configuration, no questions.
|
|
|
|
---
|
|
|
|
## Functional requirements
|
|
|
|
### FR-1 Bootstrap via curl
|
|
|
|
- **FR-1.1** When run via `curl | bash`, the script detects it has no filesystem location (`BASH_SOURCE[0]` is empty)
|
|
- **FR-1.2** If `ai-superpower/` does not exist in `$PWD`: clone the repo there
|
|
- **FR-1.3** If `ai-superpower/` already exists: run `git pull` to update it
|
|
- **FR-1.4** After clone/pull: re-exec the local copy of `apply.sh` with `--bootstrapped DEV_ROOT` and stdin reopened from `/dev/tty` so interactive prompts work even when piped through curl
|
|
- **FR-1.5** If `--update` is passed as the first argument (`curl ... | bash -s -- --update`): forward it through the re-exec along with the commit hash captured before `git pull`; local mode detects the flag at `$3`, compares `$4` (pre-pull commit) with the current HEAD, and either reports "already up to date" or prints new commit messages with `git log --oneline`; skips all project scanning and setup
|
|
|
|
### FR-2 Project discovery
|
|
|
|
- **FR-2.1** Scan dev root recursively for directories containing `.git`
|
|
- **FR-2.2** Dev root is the parent directory of the script's own location
|
|
- **FR-2.3** Exclude any project containing a `.ai-superpower` marker file in its root — this identifies the ai-superpower repo itself regardless of what the directory is named
|
|
- **FR-2.4** Maximum scan depth: 4 levels below dev root (`-maxdepth 4` from dev root)
|
|
|
|
### FR-3 Symlink
|
|
|
|
- **FR-3.1** For each discovered project: create `project/.ai` as a symlink pointing directly to `ai-superpower/.ai/` in the repo (absolute path)
|
|
- **FR-3.2** If symlink is already correct: skip silently
|
|
- **FR-3.3** If symlink is missing or broken: create it
|
|
- **FR-3.4** This means changes made to `.ai/` instruction files from any project are immediately reflected in the git working tree of `ai-superpower/` — no sync step needed
|
|
|
|
### FR-4 .gitignore
|
|
|
|
- **FR-4.1** Check if `.ai` is present in `project/.gitignore`
|
|
- **FR-4.2** If missing: append `.ai` to the file (create file if it does not exist)
|
|
- **FR-4.3** If already present: skip silently
|
|
|
|
### FR-5 ai-context.md
|
|
|
|
- **FR-5.1** If `project/docs/` does not exist and stdin is a TTY: ask the developer `[y/N]` whether to create it; create it on `y`, skip on anything else
|
|
- **FR-5.1b** If `project/docs/` does not exist and stdin is not a TTY (non-interactive environment): print a warning and skip
|
|
- **FR-5.2** If `project/docs/ai-context.md` does not exist: create it from a template
|
|
- **FR-5.3** The template contains section headings and inline instructions explaining what each section should contain and how to fill it in (manually or by asking the AI)
|
|
- **FR-5.4** If file already exists and the first line is the factory-reset marker (`<!-- ai-superpower:template`): overwrite with the current template — the file has not yet been customised
|
|
- **FR-5.5** If file already exists and marker is absent: skip silently — the developer owns this file
|
|
- **FR-5.6 (future)** Interactive mode: before creating the template, ask the developer for a one-line project description and pre-fill it into the template
|
|
|
|
### FR-6 architecture.md
|
|
|
|
- **FR-6.1** If `project/docs/architecture.md` does not exist: create it from a template
|
|
- **FR-6.2** The template contains section headings and inline instructions explaining what each section should contain and how to fill it in (manually or by asking the AI)
|
|
- **FR-6.3** If file already exists and the first line is the factory-reset marker: overwrite with the current template — the file has not yet been customised
|
|
- **FR-6.4** If file already exists and marker is absent: skip silently — the developer owns this file
|
|
- **FR-6.5 (future)** Interactive mode: offer to scaffold a richer `architecture.md` based on a brief description from the developer
|
|
|
|
### FR-7 Idempotency
|
|
|
|
- **FR-7.1** Running `apply.sh` multiple times produces the same result
|
|
- **FR-7.2** Files that have been customised by the developer (factory-reset marker absent) are never overwritten
|
|
- **FR-7.3** No duplicate lines added to `.gitignore`
|
|
|
|
### FR-8 Version file
|
|
|
|
- **FR-8.1** After each run, write `$DEV_ROOT/.ai-superpower.version` with the current UTC timestamp and the short git commit hash of the ai-superpower repo
|
|
- **FR-8.2** The file is overwritten on every run (always reflects the last run)
|
|
- **FR-8.3** `$DEV_ROOT/.ai-superpower.version` is listed in this repo's `.gitignore`
|
|
|
|
---
|
|
|
|
## Non-functional requirements
|
|
|
|
### NFR-1 Minimal interaction
|
|
|
|
The script is designed to run non-interactively. One exception: when `project/docs/` does not exist and stdin is a TTY, the script asks `[y/N]` before creating the folder. This is gated on TTY detection — in non-interactive environments (piped through curl, CI) it falls back to a printed warning and skip. All other steps run without prompts.
|
|
|
|
**Future:** FR-5.6 and FR-6.5 describe potential interactive scaffolding for `ai-context.md` and `architecture.md`. The code structure must allow this to be added per-project without redesigning the main loop.
|
|
|
|
### NFR-2 Output
|
|
|
|
Each project prints a short status line per action taken. Silent for skipped steps.
|
|
|
|
```
|
|
▸ project-name
|
|
✓ .ai symlinked
|
|
✓ .ai added to .gitignore
|
|
✓ created docs/ai-context.md
|
|
⚠ no docs/architecture.md
|
|
```
|
|
|
|
### NFR-3 Error handling
|
|
|
|
- `set -euo pipefail` — fail fast on errors
|
|
- Failed `git clone` or `git pull`: print clear error message and exit
|
|
- Failed write to `.gitignore` or docs files: script exits immediately (inherits pipefail behaviour)
|
|
|
|
### NFR-4 Size
|
|
|
|
Target: under 150 lines. Single file, no external scripts.
|
|
|
|
### NFR-5 Compatibility
|
|
|
|
- macOS (zsh + bash)
|
|
- Linux (bash)
|
|
- Windows via WSL
|
|
- No dependencies beyond `git`, `bash`, `find`
|
|
|
|
---
|
|
|
|
## Out of scope (v1)
|
|
|
|
- Interactive project selection checklist
|
|
- Interactive docs/ scaffolding (deferred to future version — see FR-5.6, FR-6.5)
|
|
- Harnesses (CLAUDE.md, AGENTS.md, .cursor/rules/)
|
|
- Copy mode — symlinks only
|
|
- Windows native (WSL required)
|