feat: interactive docs/ creation per project
- ask [y/N] per project when docs/ folder is missing - bootstrap reopens stdin from /dev/tty so prompts work through curl | bash - fallback to silent skip when stdin is not a TTY (non-interactive) - docs/apply-requirements.md: FR-1.4 and FR-5.1 updated
This commit is contained in:
parent
99d13e6e4a
commit
8d3758cd6c
22
apply.sh
22
apply.sh
@ -18,7 +18,8 @@ if [[ -z "${BASH_SOURCE[0]:-}" ]]; then
|
|||||||
git clone "$REPO_URL" "$TARGET" || { echo "✗ git clone failed"; exit 1; }
|
git clone "$REPO_URL" "$TARGET" || { echo "✗ git clone failed"; exit 1; }
|
||||||
fi
|
fi
|
||||||
# Pass DEV_ROOT explicitly — local mode must not guess it from script location
|
# Pass DEV_ROOT explicitly — local mode must not guess it from script location
|
||||||
exec bash "$TARGET/apply.sh" --bootstrapped "$DEV_ROOT"
|
# Reopen stdin from /dev/tty so local mode can prompt interactively
|
||||||
|
exec bash "$TARGET/apply.sh" --bootstrapped "$DEV_ROOT" </dev/tty
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# ── Guard — block direct invocation ──────────────────────────────────────────
|
# ── Guard — block direct invocation ──────────────────────────────────────────
|
||||||
@ -77,9 +78,22 @@ setup_project() {
|
|||||||
# FR-5 + FR-6: docs
|
# FR-5 + FR-6: docs
|
||||||
local docs="$project/docs"
|
local docs="$project/docs"
|
||||||
if [[ ! -d "$docs" ]]; then
|
if [[ ! -d "$docs" ]]; then
|
||||||
echo " ⚠ no docs/ folder — skipping context setup"
|
if [[ -t 0 ]]; then
|
||||||
(( cnt_no_docs++ )) || true
|
printf " ? no docs/ folder — create it? [y/N] "
|
||||||
return
|
read -r answer
|
||||||
|
if [[ "${answer,,}" == "y" ]]; then
|
||||||
|
mkdir -p "$docs"
|
||||||
|
echo " ✓ created docs/"
|
||||||
|
else
|
||||||
|
echo " – skipped"
|
||||||
|
(( cnt_no_docs++ )) || true
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo " ⚠ no docs/ folder — skipping context setup"
|
||||||
|
(( cnt_no_docs++ )) || true
|
||||||
|
return
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local got_template=0
|
local got_template=0
|
||||||
|
|||||||
@ -13,7 +13,7 @@ A single bash script that gives any developer AI superpowers across all their pr
|
|||||||
- **FR-1.1** When run via `curl | bash`, the script detects it has no filesystem location (`BASH_SOURCE[0]` is empty)
|
- **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.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.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-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-2 Project discovery
|
### FR-2 Project discovery
|
||||||
|
|
||||||
@ -38,7 +38,8 @@ A single bash script that gives any developer AI superpowers across all their pr
|
|||||||
|
|
||||||
### FR-5 ai-context.md
|
### 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.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.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.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.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
|
||||||
|
|||||||
@ -2,54 +2,97 @@
|
|||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
flowchart TD
|
flowchart TD
|
||||||
A([Developer]) -- "curl | bash" --> B[Bootstrap: clone or pull ai-superpower]
|
DEV([Developer in dev root]) -- "curl -fsSL ...apply.sh | bash" --> BS1
|
||||||
B -- "exec apply.sh --bootstrapped" --> C[Copy .ai/ into DEV_ROOT]
|
DEV -- "bash apply.sh directly" --> GUARD["✗ must run via curl\nprint curl command\nexit 1"]
|
||||||
|
|
||||||
A -- "bash apply.sh" --> ERR[✗ Error: must run via curl]
|
subgraph BOOTSTRAP ["── Bootstrap BASH_SOURCE empty ──"]
|
||||||
|
BS1{"ai-superpower/\nexists in DEV_ROOT?"}
|
||||||
|
BS1 -- "No" --> BS2["git clone REPO_URL ai-superpower/"]
|
||||||
|
BS1 -- "Yes" --> BS3["git pull ai-superpower/"]
|
||||||
|
BS2 -- "fail" --> BSE1["✗ print error, exit 1"]
|
||||||
|
BS3 -- "fail" --> BSE2["✗ print error, exit 1"]
|
||||||
|
BS2 -- "ok" --> BS4["exec bash apply.sh --bootstrapped DEV_ROOT\nstdin reopened from /dev/tty"]
|
||||||
|
BS3 -- "ok" --> BS4
|
||||||
|
end
|
||||||
|
|
||||||
C --> D[Scan dev root for .git projects]
|
BS4 --> L1
|
||||||
|
|
||||||
D --> E{Projects found?}
|
subgraph LOCAL ["── Local mode --bootstrapped flag present ──"]
|
||||||
E -- "No" --> NP[Print: no projects found]
|
L1["SCRIPT_DIR = dir of apply.sh\nDEV_ROOT = arg 2\nAI_TARGET = DEV_ROOT/.ai"]
|
||||||
E -- "Yes" --> G[Per-project setup]
|
|
||||||
|
|
||||||
G --> H{.ai symlink → DEV_ROOT/.ai ok?}
|
subgraph INSTALL ["── Install .ai/ into dev root ──"]
|
||||||
H -- "Missing or broken" --> I[Create symlink]
|
L1 --> L2["rm -rf DEV_ROOT/.ai"]
|
||||||
H -- "Ok" --> J[Skip]
|
L2 --> L3["cp -r ai-superpower/.ai → DEV_ROOT/.ai"]
|
||||||
|
L3 --> L4{".ai in DEV_ROOT/.gitignore?"}
|
||||||
|
L4 -- "No" --> L5["append .ai"]
|
||||||
|
L4 -- "Yes" --> L6["skip"]
|
||||||
|
L5 --> SCAN1
|
||||||
|
L6 --> SCAN1
|
||||||
|
end
|
||||||
|
|
||||||
I --> K
|
subgraph SCAN ["── Scan DEV_ROOT ──"]
|
||||||
J --> K
|
SCAN1["find DEV_ROOT\n-mindepth 2 -maxdepth 4\n-name .git -type d"]
|
||||||
|
SCAN1 --> SCAN2{".ai-superpower\nin project root?"}
|
||||||
|
SCAN2 -- "Yes" --> SKIP["skip — this is ai-superpower repo"]
|
||||||
|
SKIP --> SCAN1
|
||||||
|
SCAN2 -- "No" --> P1
|
||||||
|
end
|
||||||
|
|
||||||
K{.ai in .gitignore?}
|
subgraph PROJ ["── Per-project setup ──"]
|
||||||
K -- "No" --> L[Add .ai to .gitignore]
|
P1["print ▸ project-name"]
|
||||||
K -- "Yes" --> M[Skip]
|
|
||||||
|
|
||||||
L --> N
|
P1 --> P2{"project/.ai symlink\n→ DEV_ROOT/.ai?"}
|
||||||
M --> N
|
P2 -- "Yes" --> P3["skip silently"]
|
||||||
|
P2 -- "No / wrong / broken" --> P4["ln -sfn DEV_ROOT/.ai project/.ai\nprint ✓ .ai symlinked"]
|
||||||
|
P3 --> P5
|
||||||
|
P4 --> P5
|
||||||
|
|
||||||
N{docs/ exists?}
|
P5{".ai in project/.gitignore?"}
|
||||||
N -- "No" --> O[⚠ Warning: no docs/ folder]
|
P5 -- "Yes" --> P6["skip silently"]
|
||||||
N -- "Yes" --> P{ai-context.md exists?}
|
P5 -- "No" --> P7["append .ai print ✓"]
|
||||||
|
P6 --> P8
|
||||||
|
P7 --> P8
|
||||||
|
|
||||||
O --> S
|
P8{"project/docs/ exists?"}
|
||||||
P -- "No" --> Q[Create from template]
|
P8 -- "Yes" --> P10
|
||||||
P -- "Yes, marker present" --> QR[Refresh from template]
|
P8 -- "No" --> TTY{"stdin is TTY?\n[ -t 0 ]"}
|
||||||
P -- "Yes, no marker" --> R[Skip — developer owns file]
|
TTY -- "No" --> WARN["print ⚠ no docs/ skipping\ncnt_no_docs++ return"]
|
||||||
|
TTY -- "Yes" --> ASK["print: no docs/ — create it? [y/N]"]
|
||||||
|
ASK -- "n / enter" --> SKIP2["print – skipped\ncnt_no_docs++ return"]
|
||||||
|
ASK -- "y" --> MK["mkdir docs/\nprint ✓ created docs/"]
|
||||||
|
MK --> P10
|
||||||
|
|
||||||
Q --> S
|
P10{"docs/ai-context.md exists?"}
|
||||||
QR --> S
|
P10 -- "No" --> P11["cp templates/ai-context.md\nprint ✓ created\ncnt_templated++"]
|
||||||
R --> S
|
P10 -- "Yes marker on line 1" --> P12["cp templates/ai-context.md\nprint ✓ refreshed\ncnt_refreshed++"]
|
||||||
|
P10 -- "Yes no marker" --> P13["skip — developer owns file"]
|
||||||
|
P11 --> P14
|
||||||
|
P12 --> P14
|
||||||
|
P13 --> P14
|
||||||
|
|
||||||
S{architecture.md exists?}
|
P14{"docs/architecture.md exists?"}
|
||||||
S -- "No" --> T[Create from template]
|
P14 -- "No" --> P15["cp templates/architecture.md\nprint ✓ created\ncnt_templated++"]
|
||||||
S -- "Yes, marker present" --> TR[Refresh from template]
|
P14 -- "Yes marker on line 1" --> P16["cp templates/architecture.md\nprint ✓ refreshed\ncnt_refreshed++"]
|
||||||
S -- "Yes, no marker" --> U[Skip — developer owns file]
|
P14 -- "Yes no marker" --> P17["skip — developer owns file"]
|
||||||
|
P15 --> NEXT
|
||||||
|
P16 --> NEXT
|
||||||
|
P17 --> NEXT
|
||||||
|
WARN --> SCAN1
|
||||||
|
SKIP2 --> SCAN1
|
||||||
|
end
|
||||||
|
|
||||||
T --> V
|
NEXT --> SCAN1
|
||||||
TR --> V
|
SCAN1 -- "all projects done" --> S1
|
||||||
U --> V
|
|
||||||
|
|
||||||
V{More projects?}
|
subgraph SUMMARY ["── Summary + version file ──"]
|
||||||
V -- "Yes" --> G
|
S1{"cnt_found > 0?"}
|
||||||
V -- "No" --> W[Write .ai-superpower.version]
|
S1 -- "No" --> S2["print ⚠ no projects found\nare you in the right directory?"]
|
||||||
W --> X([✅ Done])
|
S1 -- "Yes" --> S3["print ✅ done"]
|
||||||
|
S2 --> S4
|
||||||
|
S3 --> S4
|
||||||
|
S4["read PREV_COMMIT from .ai-superpower.version"]
|
||||||
|
S4 --> S5["print:\nversion: prev → new\nprojects: N found\nno docs/: M skipped\ntemplated: X new\nrefreshed: Y updated"]
|
||||||
|
S5 --> S6["write DEV_ROOT/.ai-superpower.version\ndate + commit hash"]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user