feat: complete apply.sh v1 — summary, guard, dev root install, updated docs
- apply.sh: direct-run guard (only curl | bash allowed) - apply.sh: DEV_ROOT passed as explicit arg from bootstrap - apply.sh: .ai/ copied to dev root as real folder; projects symlink there - apply.sh: counters + detailed summary (version prev→new, templated, refreshed, no-docs) - apply.sh: find errors silenced, no crash on empty dev root - .ai-superpower: added warning comment about deletion side effects - .gitignore: .ai-instructions.conf → .ai-superpower.version - scripts/: removed (hello.sh, scan-projects-with-git.sh, verify-docs-folder.sh, add-ai-context-to-docs-folder.sh) - templates: monorepo sections split into AI instructions + developer instructions - README.md: rewritten to match current architecture and behaviour - docs/apply-requirements.md: FR-2.4, FR-3, FR-5, FR-6, FR-7, FR-8 updated - docs/apply-usecases.md: full detailed Mermaid flowchart replacing placeholder
This commit is contained in:
parent
0a3c0cc906
commit
99d13e6e4a
12
.ai-superpower
Normal file
12
.ai-superpower
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
ai-superpower
|
||||||
|
|
||||||
|
# This file exists so that apply.sh can identify this repo as itself.
|
||||||
|
#
|
||||||
|
# apply.sh scans all directories that contain a .git folder and creates a
|
||||||
|
# .ai symlink in each one. Without this file, apply.sh would also symlink
|
||||||
|
# this repo into itself, producing .ai/.ai → .ai/ (infinite loop).
|
||||||
|
#
|
||||||
|
# WARNING — do not delete this file:
|
||||||
|
# - apply.sh will create a .ai/.ai symlink inside this repo pointing to itself
|
||||||
|
# - the next apply.sh run will loop or crash
|
||||||
|
# - fix: restore this file and remove the .ai/.ai symlink that was created
|
||||||
@ -27,6 +27,25 @@ Keep under 200 lines. Link to `architecture.md` for diagrams.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Factory template marker
|
||||||
|
|
||||||
|
`docs/ai-context.md` and `docs/architecture.md` may start with this block:
|
||||||
|
|
||||||
|
```
|
||||||
|
<!-- ai-superpower:template
|
||||||
|
STATUS: factory default — not yet filled in
|
||||||
|
...
|
||||||
|
-->
|
||||||
|
```
|
||||||
|
|
||||||
|
**When you first touch a file that has this marker — even just to read it before writing — remove the marker line as the very first edit:**
|
||||||
|
1. Remove the line `<!-- ai-superpower:template -->`
|
||||||
|
2. Then write the actual content
|
||||||
|
|
||||||
|
The marker's presence tells `apply.sh` the file has not been edited yet and will be overwritten on the next run. Once removed, the file is owned by the project and will never be overwritten.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Rules
|
## Rules
|
||||||
|
|
||||||
- Docs are **not** a changelog — no "updated X on date Y"
|
- Docs are **not** a changelog — no "updated X on date Y"
|
||||||
|
|||||||
@ -46,8 +46,7 @@ When the user asks for a commit message:
|
|||||||
|
|
||||||
1. **Run `git diff --staged` or `git diff`** — read what actually changed
|
1. **Run `git diff --staged` or `git diff`** — read what actually changed
|
||||||
2. **Documentation check** — scan the changed files and ask: does any `docs/` or `README.md` need updating based on these changes? If yes, flag it clearly before writing the message. Do not block the commit — just surface it.
|
2. **Documentation check** — scan the changed files and ask: does any `docs/` or `README.md` need updating based on these changes? If yes, flag it clearly before writing the message. Do not block the commit — just surface it.
|
||||||
3. **Write the commit message** — one short subject line, optionally a blank line and brief body if the change needs context
|
3. **Write the commit message only** — one short subject line, optionally a blank line and brief body if the change needs context. Output just the message text in a code block. Do NOT wrap it in a `git commit` command.
|
||||||
4. **Show the command** — display the full `git commit -m "..."` for the user to run themselves
|
|
||||||
|
|
||||||
Format:
|
Format:
|
||||||
```
|
```
|
||||||
|
|||||||
@ -1,5 +1,20 @@
|
|||||||
# Mermaid Diagram Instructions
|
# Mermaid Diagram Instructions
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Edge Labels
|
||||||
|
|
||||||
|
Use `-- "text" -->` syntax, **not** `-->|text|` syntax.
|
||||||
|
|
||||||
|
`|` inside `-->|label|` breaks parsing if the label contains a pipe character (e.g. `curl | bash`). Quoted syntax always works:
|
||||||
|
|
||||||
|
```
|
||||||
|
✅ A -- "curl | bash" --> B
|
||||||
|
❌ A -->|curl | bash| B
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Color Contrast — CRITICAL
|
## Color Contrast — CRITICAL
|
||||||
|
|
||||||
All Mermaid diagrams MUST have sufficient color contrast. AI-generated diagrams often fail this.
|
All Mermaid diagrams MUST have sufficient color contrast. AI-generated diagrams often fail this.
|
||||||
|
|||||||
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
.ai-instructions.conf
|
.ai-superpower.version
|
||||||
tmp/
|
tmp/
|
||||||
|
.ai
|
||||||
|
|||||||
73
README.md
73
README.md
@ -1,7 +1,7 @@
|
|||||||
# ai-superpower
|
# ai-superpower
|
||||||
|
|
||||||
AI instructions scatter across a large number of projects. Maintaining them inside each project individually is not practical — a single change requires manual updates everywhere.
|
AI instructions scatter across a large number of projects. Maintaining them inside each project individually is not practical — a single change requires manual updates everywhere.
|
||||||
This repo solves that: instructions live in one place and are distributed to all projects from here.
|
This repo solves that: a central `.ai/` folder is installed in your dev root, and every project gets a symlink to it. A `git pull` + re-run of `apply.sh` updates all projects instantly.
|
||||||
|
|
||||||
AI requires strong guidance to support human workflows rather than override them. Treat its outputs as zero-trust: the human reviews everything and must be willing to put their name on what the AI produced.
|
AI requires strong guidance to support human workflows rather than override them. Treat its outputs as zero-trust: the human reviews everything and must be willing to put their name on what the AI produced.
|
||||||
|
|
||||||
@ -10,35 +10,45 @@ Good instructions are what make that possible — they allow AI to produce outpu
|
|||||||
## Principles
|
## Principles
|
||||||
|
|
||||||
- **Generic vs. project-specific** — `.ai/` instructions know nothing about individual projects. Project knowledge lives in each project's own `docs/ai-context.md`.
|
- **Generic vs. project-specific** — `.ai/` instructions know nothing about individual projects. Project knowledge lives in each project's own `docs/ai-context.md`.
|
||||||
- **Sync writes only to `.ai/`** — never touches project code or `docs/`.
|
- **Single install, real folder** — `apply.sh` copies `.ai/` into your dev root. Every project symlinks there. One source of truth, zero drift.
|
||||||
- **Modular loading** — AI loads only the relevant instruction files per task, not everything at once.
|
- **Modular loading** — AI loads only the relevant instruction files per task, not everything at once.
|
||||||
- **One change, all projects** — edit here, run sync, done.
|
- **One change, all projects** — re-run `apply.sh`, done. `.ai/` is refreshed and all symlinks already point to it.
|
||||||
- **Version controlled** — instructions are managed in git. Changes are tracked, history is preserved, and rolling back is straightforward.
|
- **Version controlled** — instructions are managed in git. Changes are tracked, history is preserved, and rolling back is straightforward.
|
||||||
|
|
||||||
## Usage
|
## Install
|
||||||
|
|
||||||
Clone this repo directly into your dev root — the folder where all your projects live. The dev root can be anything (`~/koodi`, `~/projects`, `C:\dev`), but `ai-superpower` must be an immediate child of it. The script uses its own location to determine where to look for projects.
|
Run this from your dev root — the folder where all your projects live:
|
||||||
|
|
||||||
```
|
|
||||||
dev_root/ ← can be anywhere
|
|
||||||
├── ai-superpower/ ← must be here, at this level
|
|
||||||
├── project-a/
|
|
||||||
├── project-b/
|
|
||||||
└── some-folder/
|
|
||||||
└── project-c/ ← nested projects are found automatically
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd ~/koodi
|
curl -fsSL https://gitea.nikos-dev.keskikuja.site/niko/ai-superpower/raw/branch/main/apply.sh | bash
|
||||||
git clone https://gitea.nikos-dev.keskikuja.site/niko/ai-superpower.git
|
|
||||||
```
|
```
|
||||||
|
|
||||||
From there, run the appropriate script depending on how you use your editor:
|
This script **must be run via `curl | bash`** from your dev root. Running it directly will fail with instructions to use the curl command.
|
||||||
|
|
||||||
- **One project per editor window** — run `apply.sh`. It copies `.ai/` into each project and sets up context files.
|
What it does:
|
||||||
- **Dev root as single workspace** — run `apply.sh`. Skips `.ai/` distribution (not needed), only sets up per-project context files.
|
1. Clones (or updates) this repo into `dev_root/ai-superpower/`
|
||||||
|
2. Copies `.ai/` into your dev root as a real folder
|
||||||
|
3. Scans for all projects (up to 4 levels deep) and creates a `.ai` symlink in each
|
||||||
|
4. Adds `.ai` to each project's `.gitignore`
|
||||||
|
5. Creates `docs/ai-context.md` and `docs/architecture.md` templates in projects that have a `docs/` folder but no such files yet
|
||||||
|
6. Writes a `.ai-superpower.version` file to your dev root with the run timestamp and commit hash
|
||||||
|
|
||||||
See [apply.md](apply.md) for the full mechanism and [docs/architecture.md](docs/architecture.md) for the design.
|
```
|
||||||
|
dev_root/ ← run curl from here
|
||||||
|
├── .ai/ ← installed here as a real folder (refreshed on every run)
|
||||||
|
├── ai-superpower/ ← cloned here automatically
|
||||||
|
├── project-a/
|
||||||
|
│ └── .ai → dev_root/.ai/ ← symlink
|
||||||
|
├── project-b/
|
||||||
|
│ └── .ai → dev_root/.ai/ ← symlink
|
||||||
|
└── some-folder/
|
||||||
|
└── project-c/ ← nested projects found automatically (maxdepth 4)
|
||||||
|
└── .ai → dev_root/.ai/
|
||||||
|
```
|
||||||
|
|
||||||
|
See [docs/apply-requirements.md](docs/apply-requirements.md) for the full requirements and [docs/apply-usecases.md](docs/apply-usecases.md) for a detailed flow diagram.
|
||||||
|
|
||||||
|
## AI setup
|
||||||
|
|
||||||
The AI must be instructed to always read `.ai/ai-root-instructions.md` at the start of every session. In your AI assistant's system prompt or custom instructions, add:
|
The AI must be instructed to always read `.ai/ai-root-instructions.md` at the start of every session. In your AI assistant's system prompt or custom instructions, add:
|
||||||
|
|
||||||
@ -52,19 +62,20 @@ Verify that every AI response begins with this confirmation. If it does not, the
|
|||||||
|
|
||||||
```
|
```
|
||||||
ai-superpower/
|
ai-superpower/
|
||||||
└── .ai/ ← synced to all projects
|
└── .ai/ ← source, copied to dev_root/.ai/ on every run
|
||||||
├── ai-root-instructions.md ← entry point, read first
|
├── ai-root-instructions.md ← entry point, read first
|
||||||
└── instructions/
|
└── instructions/
|
||||||
├── behavior/ ← how AI approaches its work
|
├── behavior/ ← how AI approaches its work
|
||||||
├── skills/ ← task-specific guides (git, docs, diagrams)
|
├── skills/ ← task-specific guides (git, docs, diagrams)
|
||||||
└── constraints/ ← what AI must not do
|
└── constraints/ ← what AI must not do
|
||||||
|
|
||||||
project-x/
|
dev_root/
|
||||||
├── .ai/ ← written by sync
|
├── .ai/ ← real folder (copy of above)
|
||||||
└── docs/
|
└── project-x/
|
||||||
└── ai-context.md ← project-specific, never synced
|
├── .ai → dev_root/.ai/ ← symlink
|
||||||
|
└── docs/
|
||||||
|
├── ai-context.md ← project-specific context, never overwritten once customised
|
||||||
|
└── architecture.md ← project architecture, never overwritten once customised
|
||||||
```
|
```
|
||||||
|
|
||||||
Clear architecture documentation — written following the instructions in this project — matters for both human and AI work. There must be a plan before building. The AI will consistently push for this, because without context it cannot work well. The vision always comes from the human; the AI helps carry it out under human supervision.
|
Templates for `ai-context.md` and `architecture.md` are deployed automatically to any project that has a `docs/` folder. They contain a factory-reset marker on line 1 — as long as that marker is present, `apply.sh` will refresh the file on every run. Once you (or the AI) edits the file and removes the marker, the file is yours and will never be touched again.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
140
apply.sh
140
apply.sh
@ -1,4 +1,142 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
echo "jee"
|
REPO_URL="https://gitea.nikos-dev.keskikuja.site/niko/ai-superpower.git"
|
||||||
|
REPO_NAME="ai-superpower"
|
||||||
|
RAW_URL="https://gitea.nikos-dev.keskikuja.site/niko/ai-superpower/raw/branch/main/apply.sh"
|
||||||
|
|
||||||
|
# ── Bootstrap mode (curl | bash) ─────────────────────────────────────────────
|
||||||
|
# BASH_SOURCE[0] is empty when piped through bash
|
||||||
|
if [[ -z "${BASH_SOURCE[0]:-}" ]]; then
|
||||||
|
DEV_ROOT="$PWD" # capture before exec replaces the process
|
||||||
|
TARGET="$DEV_ROOT/$REPO_NAME"
|
||||||
|
if [[ -d "$TARGET" ]]; then
|
||||||
|
echo "→ updating $REPO_NAME ..."
|
||||||
|
git -C "$TARGET" pull || { echo "✗ git pull failed"; exit 1; }
|
||||||
|
else
|
||||||
|
echo "→ cloning $REPO_NAME into $TARGET ..."
|
||||||
|
git clone "$REPO_URL" "$TARGET" || { echo "✗ git clone failed"; exit 1; }
|
||||||
|
fi
|
||||||
|
# Pass DEV_ROOT explicitly — local mode must not guess it from script location
|
||||||
|
exec bash "$TARGET/apply.sh" --bootstrapped "$DEV_ROOT"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── Guard — block direct invocation ──────────────────────────────────────────
|
||||||
|
if [[ "${1:-}" != "--bootstrapped" ]]; then
|
||||||
|
echo "✗ do not run this script directly."
|
||||||
|
echo " run from your dev root folder:"
|
||||||
|
echo ""
|
||||||
|
echo " curl -fsSL $RAW_URL | bash"
|
||||||
|
echo ""
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── Local mode ────────────────────────────────────────────────────────────────
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
DEV_ROOT="${2:?DEV_ROOT not passed — re-run via curl}"
|
||||||
|
AI_TARGET="$DEV_ROOT/.ai"
|
||||||
|
TEMPLATE_MARKER="<!-- ai-superpower:template"
|
||||||
|
|
||||||
|
# Counters
|
||||||
|
cnt_found=0
|
||||||
|
cnt_no_docs=0
|
||||||
|
cnt_templated=0
|
||||||
|
cnt_refreshed=0
|
||||||
|
|
||||||
|
# ── Install .ai/ into dev root (real folder, refreshed on every run) ─────────
|
||||||
|
echo "→ installing .ai/ into $DEV_ROOT ..."
|
||||||
|
rm -rf "$AI_TARGET"
|
||||||
|
cp -r "$SCRIPT_DIR/.ai" "$AI_TARGET"
|
||||||
|
if ! grep -qxF '.ai' "$DEV_ROOT/.gitignore" 2>/dev/null; then
|
||||||
|
echo '.ai' >> "$DEV_ROOT/.gitignore"
|
||||||
|
fi
|
||||||
|
|
||||||
|
setup_project() {
|
||||||
|
local project="$1"
|
||||||
|
local name
|
||||||
|
name="$(basename "$project")"
|
||||||
|
echo ""
|
||||||
|
echo "▸ $name"
|
||||||
|
|
||||||
|
# FR-3: symlink
|
||||||
|
local ai_link="$project/.ai"
|
||||||
|
if [[ -L "$ai_link" && "$(readlink "$ai_link")" == "$AI_TARGET" ]]; then
|
||||||
|
: # correct — skip silently
|
||||||
|
else
|
||||||
|
ln -sfn "$AI_TARGET" "$ai_link"
|
||||||
|
echo " ✓ .ai symlinked"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# FR-4: .gitignore
|
||||||
|
local gitignore="$project/.gitignore"
|
||||||
|
if ! grep -qxF '.ai' "$gitignore" 2>/dev/null; then
|
||||||
|
echo '.ai' >> "$gitignore"
|
||||||
|
echo " ✓ .ai added to .gitignore"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# FR-5 + FR-6: docs
|
||||||
|
local docs="$project/docs"
|
||||||
|
if [[ ! -d "$docs" ]]; then
|
||||||
|
echo " ⚠ no docs/ folder — skipping context setup"
|
||||||
|
(( cnt_no_docs++ )) || true
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
local got_template=0
|
||||||
|
|
||||||
|
if [[ ! -f "$docs/ai-context.md" ]]; then
|
||||||
|
cp "$SCRIPT_DIR/templates/ai-context.md" "$docs/ai-context.md"
|
||||||
|
echo " ✓ created docs/ai-context.md"
|
||||||
|
got_template=1
|
||||||
|
elif head -1 "$docs/ai-context.md" | grep -qF "$TEMPLATE_MARKER"; then
|
||||||
|
cp "$SCRIPT_DIR/templates/ai-context.md" "$docs/ai-context.md"
|
||||||
|
echo " ✓ refreshed docs/ai-context.md (was factory template)"
|
||||||
|
(( cnt_refreshed++ )) || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -f "$docs/architecture.md" ]]; then
|
||||||
|
cp "$SCRIPT_DIR/templates/architecture.md" "$docs/architecture.md"
|
||||||
|
echo " ✓ created docs/architecture.md"
|
||||||
|
got_template=1
|
||||||
|
elif head -1 "$docs/architecture.md" | grep -qF "$TEMPLATE_MARKER"; then
|
||||||
|
cp "$SCRIPT_DIR/templates/architecture.md" "$docs/architecture.md"
|
||||||
|
echo " ✓ refreshed docs/architecture.md (was factory template)"
|
||||||
|
(( cnt_refreshed++ )) || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
(( got_template )) && (( cnt_templated++ )) || true
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Scan and run ──────────────────────────────────────────────────────────────
|
||||||
|
echo "→ scanning $DEV_ROOT for projects ..."
|
||||||
|
|
||||||
|
while IFS= read -r gitdir; do
|
||||||
|
project="$(cd "$(dirname "$gitdir")" && pwd)"
|
||||||
|
[[ -f "$project/.ai-superpower" ]] && continue
|
||||||
|
setup_project "$project"
|
||||||
|
(( cnt_found++ )) || true
|
||||||
|
done < <(find "$DEV_ROOT" -mindepth 2 -maxdepth 4 -name ".git" -type d 2>/dev/null || true)
|
||||||
|
|
||||||
|
# ── Summary ───────────────────────────────────────────────────────────────────
|
||||||
|
COMMIT="$(git -C "$SCRIPT_DIR" rev-parse --short HEAD 2>/dev/null || echo "unknown")"
|
||||||
|
PREV_COMMIT="$(grep '^commit:' "$DEV_ROOT/.ai-superpower.version" 2>/dev/null | awk '{print $2}' || echo "")"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "────────────────────────────────────────"
|
||||||
|
if [[ -n "$PREV_COMMIT" && "$PREV_COMMIT" != "$COMMIT" ]]; then
|
||||||
|
echo " version: $PREV_COMMIT → $COMMIT"
|
||||||
|
elif [[ -n "$PREV_COMMIT" ]]; then
|
||||||
|
echo " version: $COMMIT (no change)"
|
||||||
|
else
|
||||||
|
echo " version: $COMMIT (first run)"
|
||||||
|
fi
|
||||||
|
echo " projects: $cnt_found found"
|
||||||
|
(( cnt_no_docs > 0 )) && echo " no docs/: $cnt_no_docs project(s) skipped (no docs/ folder)" || true
|
||||||
|
(( cnt_templated > 0 )) && echo " templated: $cnt_templated project(s) received new docs templates" || true
|
||||||
|
(( cnt_refreshed > 0 )) && echo " refreshed: $cnt_refreshed template file(s) updated (were still factory default)" || true
|
||||||
|
echo "────────────────────────────────────────"
|
||||||
|
(( cnt_found > 0 )) && echo "✅ done" || echo "⚠ no projects found — are you in the right directory?"
|
||||||
|
|
||||||
|
# FR-8: write version file
|
||||||
|
printf '# Written by apply.sh on every run — shows when it was last run and which version of ai-superpower was used.\ndate: %s\ncommit: %s\n' \
|
||||||
|
"$(date -u '+%Y-%m-%dT%H:%M:%SZ')" "$COMMIT" > "$DEV_ROOT/.ai-superpower.version"
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
## What this project does
|
## What this project does
|
||||||
|
|
||||||
Centralised AI instruction management for a developer who works across many projects. Instead of maintaining `.ai/` instructions per project, they live here and are distributed via symlinks. Each project gets a symlink to the generic instructions; project-specific knowledge stays in that project's own `docs/ai-context.md`.
|
Centralised AI instruction management for a developer who works across many projects. Instead of maintaining `.ai/` instructions per project, they live here and are distributed via symlinks. Each project gets a symlink `project/.ai → ai-superpower/.ai/`. A `git pull` here updates all projects instantly — no re-run of `apply.sh` needed for content changes.
|
||||||
|
|
||||||
`ai-superpower` must live directly in the dev root — the script uses its own location to determine where to look for projects.
|
`ai-superpower` must live directly in the dev root — the script uses its own location to determine where to look for projects.
|
||||||
|
|
||||||
@ -22,16 +22,18 @@ The script scans dev root recursively for directories containing `.git`. `ai-sup
|
|||||||
|
|
||||||
## Tech stack
|
## Tech stack
|
||||||
|
|
||||||
- Bash — `sync.sh` is plain bash, no dependencies
|
- Bash — `apply.sh` is a single bash script, no dependencies beyond `git`, `bash`, `find`
|
||||||
- Markdown — all instruction files use `.instructions.md` format
|
- Markdown — all instruction files use `.instructions.md` format
|
||||||
- Git — version control for instructions; change history is first-class
|
- Git — version control for instructions; change history is first-class
|
||||||
|
|
||||||
## Key decisions
|
## Key decisions
|
||||||
|
|
||||||
- **Plain file copy over git submodules** — keeps project repos simple, no cross-repo plumbing
|
- **Symlinks over file copies** — one source of truth, no distribution step for content changes, no version drift
|
||||||
- **No projects.txt** — sync discovers git projects automatically by scanning for `.git` dirs in the dev root
|
- **No projects.txt** — `apply.sh` discovers git projects automatically by scanning for `.git` dirs
|
||||||
- **`.ai/` in gitignore in target projects** — instructions are not owned by the target project, they are distributed to it. This repo is the exception: `.ai/` is the product and is committed here.
|
- **`.ai/` in gitignore in target projects** — instructions are not owned by the target project. This repo is the exception: `.ai/` is the product and is committed here.
|
||||||
- **`docs/ai-context.md` is never synced** — project-specific context is the project team's responsibility
|
- **`docs/ai-context.md` and `docs/architecture.md` created from template** — `apply.sh` creates both if missing; templates contain inline instructions on how to fill them in
|
||||||
|
- **`docs/ai-context.md` is never overwritten** — project-specific context is the project team's responsibility
|
||||||
|
- **No harnesses** — no CLAUDE.md, AGENTS.md, .cursor/rules/; system prompt is the reliable mechanism
|
||||||
- **AI writes only with explicit instruction** — zero-trust output model; human reviews and owns everything
|
- **AI writes only with explicit instruction** — zero-trust output model; human reviews and owns everything
|
||||||
|
|
||||||
## How AI should work here
|
## How AI should work here
|
||||||
|
|||||||
116
docs/apply-requirements.md
Normal file
116
docs/apply-requirements.md
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
# 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` and exit the bootstrap process
|
||||||
|
|
||||||
|
### 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** Copy `ai-superpower/.ai/` to `DEV_ROOT/.ai/` as a real folder on every run — this keeps the instructions up to date when the repo is pulled
|
||||||
|
- **FR-3.2** Add `.ai` to `DEV_ROOT/.gitignore` (create file if needed)
|
||||||
|
- **FR-3.3** For each discovered project: create `project/.ai` as a symlink pointing to `DEV_ROOT/.ai/` (absolute path)
|
||||||
|
- **FR-3.4** If symlink is already correct: skip silently
|
||||||
|
- **FR-3.5** If symlink is missing or broken: create it
|
||||||
|
|
||||||
|
### 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: print a warning and skip context setup for this project
|
||||||
|
- **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 No interaction (v1)
|
||||||
|
|
||||||
|
v1 runs fully automatically. No prompts, no questions, no `read` calls. Compatible with `curl | bash`.
|
||||||
|
|
||||||
|
**Future:** the docs/ setup steps (FR-5, FR-6) are the most likely candidates for interactivity in a later version — e.g. asking the developer to describe the project before generating `ai-context.md`, or offering to scaffold `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 100 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)
|
||||||
|
- Per-developer configuration file (`.ai-instructions.conf`)
|
||||||
|
- Harnesses (CLAUDE.md, AGENTS.md, .cursor/rules/)
|
||||||
|
- Copy mode — symlinks only
|
||||||
|
- Windows native (WSL required)
|
||||||
55
docs/apply-usecases.md
Normal file
55
docs/apply-usecases.md
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
# apply.sh — use cases
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart TD
|
||||||
|
A([Developer]) -- "curl | bash" --> B[Bootstrap: clone or pull ai-superpower]
|
||||||
|
B -- "exec apply.sh --bootstrapped" --> C[Copy .ai/ into DEV_ROOT]
|
||||||
|
|
||||||
|
A -- "bash apply.sh" --> ERR[✗ Error: must run via curl]
|
||||||
|
|
||||||
|
C --> D[Scan dev root for .git projects]
|
||||||
|
|
||||||
|
D --> E{Projects found?}
|
||||||
|
E -- "No" --> NP[Print: no projects found]
|
||||||
|
E -- "Yes" --> G[Per-project setup]
|
||||||
|
|
||||||
|
G --> H{.ai symlink → DEV_ROOT/.ai ok?}
|
||||||
|
H -- "Missing or broken" --> I[Create symlink]
|
||||||
|
H -- "Ok" --> J[Skip]
|
||||||
|
|
||||||
|
I --> K
|
||||||
|
J --> K
|
||||||
|
|
||||||
|
K{.ai in .gitignore?}
|
||||||
|
K -- "No" --> L[Add .ai to .gitignore]
|
||||||
|
K -- "Yes" --> M[Skip]
|
||||||
|
|
||||||
|
L --> N
|
||||||
|
M --> N
|
||||||
|
|
||||||
|
N{docs/ exists?}
|
||||||
|
N -- "No" --> O[⚠ Warning: no docs/ folder]
|
||||||
|
N -- "Yes" --> P{ai-context.md exists?}
|
||||||
|
|
||||||
|
O --> S
|
||||||
|
P -- "No" --> Q[Create from template]
|
||||||
|
P -- "Yes, marker present" --> QR[Refresh from template]
|
||||||
|
P -- "Yes, no marker" --> R[Skip — developer owns file]
|
||||||
|
|
||||||
|
Q --> S
|
||||||
|
QR --> S
|
||||||
|
R --> S
|
||||||
|
|
||||||
|
S{architecture.md exists?}
|
||||||
|
S -- "No" --> T[Create from template]
|
||||||
|
S -- "Yes, marker present" --> TR[Refresh from template]
|
||||||
|
S -- "Yes, no marker" --> U[Skip — developer owns file]
|
||||||
|
|
||||||
|
T --> V
|
||||||
|
TR --> V
|
||||||
|
U --> V
|
||||||
|
|
||||||
|
V{More projects?}
|
||||||
|
V -- "Yes" --> G
|
||||||
|
V -- "No" --> W[Write .ai-superpower.version]
|
||||||
|
W --> X([✅ Done])
|
||||||
44
templates/ai-context.md
Normal file
44
templates/ai-context.md
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<!-- ai-superpower:template -->
|
||||||
|
|
||||||
|
> **AI: remove the marker line above (`<!-- ai-superpower:template -->`) immediately — in the same edit where you first touch this file, before anything else.**
|
||||||
|
> As long as that line exists, `apply.sh` will overwrite this file on every run.
|
||||||
|
|
||||||
|
# <project name> — AI context
|
||||||
|
|
||||||
|
> **Quickstart:** let the AI write this for you. Open the project in your editor and prompt:
|
||||||
|
>
|
||||||
|
> *"Read the codebase and write docs/ai-context.md for this project. Cover: what it does, the tech stack, architecture, key decisions, conventions, and anything else an AI needs to work here effectively."*
|
||||||
|
>
|
||||||
|
> Review, correct, and commit. You own this file — the AI drafts it.
|
||||||
|
|
||||||
|
## What this project does
|
||||||
|
|
||||||
|
> 2-4 sentences. What problem does this solve, who uses it, and what does it NOT do?
|
||||||
|
|
||||||
|
## Stack
|
||||||
|
|
||||||
|
> Languages, frameworks, key libraries, infrastructure — include versions where they matter.
|
||||||
|
|
||||||
|
## Architecture overview
|
||||||
|
|
||||||
|
> Link to docs/architecture.md. Do not duplicate content from there.
|
||||||
|
> Example: _See [docs/architecture.md](architecture.md)._
|
||||||
|
>
|
||||||
|
> **Monorepo — AI:** scan the repo structure. If you find multiple services, apps, or components under separate subdirectories, tell the developer:
|
||||||
|
> - which subdirectories you identified as separate components
|
||||||
|
> - that each one should have its own `docs/ai-context.md` and `docs/architecture.md`
|
||||||
|
> - offer to create them one by one
|
||||||
|
>
|
||||||
|
> **Monorepo — developer:** if this repo contains multiple services or components, create a `docs/` folder in each one and ask the AI to write `ai-context.md` and `architecture.md` there. Link to them from this file.
|
||||||
|
|
||||||
|
## Key decisions
|
||||||
|
|
||||||
|
> Decisions that affect how the code is written and why. Especially anything that would surprise a new team member.
|
||||||
|
|
||||||
|
## Conventions
|
||||||
|
|
||||||
|
> How is code organised? What patterns are used consistently? What would a new developer get wrong on their first PR?
|
||||||
|
|
||||||
|
## What AI should know
|
||||||
|
|
||||||
|
> Context that affects how the AI should work here: frozen modules, deployment constraints, external dependencies, things to avoid.
|
||||||
46
templates/architecture.md
Normal file
46
templates/architecture.md
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<!-- ai-superpower:template -->
|
||||||
|
|
||||||
|
> **AI: remove the marker line above (`<!-- ai-superpower:template -->`) immediately — in the same edit where you first touch this file, before anything else.**
|
||||||
|
> As long as that line exists, `apply.sh` will overwrite this file on every run.
|
||||||
|
|
||||||
|
# Architecture
|
||||||
|
|
||||||
|
> **Quickstart:** let the AI write this for you. Open the project in your editor and prompt:
|
||||||
|
>
|
||||||
|
> *"Read the codebase and write docs/architecture.md for this project. Cover: what the system does, main components, data flow, infrastructure, key architectural decisions, and known constraints."*
|
||||||
|
>
|
||||||
|
> Review, correct, and commit. You own this file — the AI drafts it.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
> One paragraph: what is this system and what problem does it solve?
|
||||||
|
> Include a simple diagram or ASCII tree if it helps clarify structure.
|
||||||
|
>
|
||||||
|
> **Monorepo — AI:** scan the repo structure. If you find multiple services, apps, or components, tell the developer:
|
||||||
|
> - which subdirectories you identified as separate components
|
||||||
|
> - that each one benefits from its own `docs/architecture.md`
|
||||||
|
> - offer to create them one by one
|
||||||
|
>
|
||||||
|
> **Monorepo — developer:** if this repo contains multiple components, create a `docs/` folder in each and ask the AI to write `architecture.md` there. Link to them from this file.
|
||||||
|
|
||||||
|
## Components
|
||||||
|
|
||||||
|
> Each major component in 2-4 sentences: what it does, what it depends on, what depends on it.
|
||||||
|
|
||||||
|
## Data flow
|
||||||
|
|
||||||
|
> How does data move through the system? What enters, what is transformed, what is stored, what is returned?
|
||||||
|
|
||||||
|
## Infrastructure
|
||||||
|
|
||||||
|
> Where does this run and how is it deployed? Link to IaC files if they exist.
|
||||||
|
|
||||||
|
## Key decisions
|
||||||
|
|
||||||
|
> Architectural decisions that are not obvious from the code.
|
||||||
|
> For each: what was chosen, what was the alternative, why this one.
|
||||||
|
|
||||||
|
## Constraints and limitations
|
||||||
|
|
||||||
|
> What does this system not do well? Known bottlenecks, scaling limits, or technical debt areas.
|
||||||
|
|
||||||
Loading…
Reference in New Issue
Block a user