config.yaml: new repo-root config file with docs_folders list (docs, documentation, doc). apply.sh reads this list and picks the first existing folder per project instead of hardcoding docs/. Instructions: - core-principles: add No Vibe Coding and No Touching .ai/ sections - ai-root-instructions: add mandatory instructions block — rules stay active for the whole session, not just at start; AI must stop and announce if instructions were not loaded - project-context, docs: updated to list all docs folder alternatives and reference config.yaml as the source of truth FR-5.0 added to apply-requirements.md. README step 4 updated.
118 lines
6.3 KiB
Markdown
118 lines
6.3 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.0** Before handling docs: read `docs_folders` list from `config.yaml` in the script directory. Use this list to find an existing docs folder in the project (first match wins). If none exists, use the first entry as the default folder name when prompting to create one.
|
|
- **FR-5.1** If the resolved docs folder 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)
|