- 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
99 lines
4.1 KiB
Markdown
99 lines
4.1 KiB
Markdown
# apply.sh — use cases
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
DEV([Developer in dev root]) -- "curl -fsSL ...apply.sh | bash" --> BS1
|
||
DEV -- "bash apply.sh directly" --> GUARD["✗ must run via curl\nprint curl command\nexit 1"]
|
||
|
||
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
|
||
|
||
BS4 --> L1
|
||
|
||
subgraph LOCAL ["── Local mode --bootstrapped flag present ──"]
|
||
L1["SCRIPT_DIR = dir of apply.sh\nDEV_ROOT = arg 2\nAI_TARGET = DEV_ROOT/.ai"]
|
||
|
||
subgraph INSTALL ["── Install .ai/ into dev root ──"]
|
||
L1 --> L2["rm -rf DEV_ROOT/.ai"]
|
||
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
|
||
|
||
subgraph SCAN ["── Scan DEV_ROOT ──"]
|
||
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
|
||
|
||
subgraph PROJ ["── Per-project setup ──"]
|
||
P1["print ▸ project-name"]
|
||
|
||
P1 --> P2{"project/.ai symlink\n→ DEV_ROOT/.ai?"}
|
||
P2 -- "Yes" --> P3["skip silently"]
|
||
P2 -- "No / wrong / broken" --> P4["ln -sfn DEV_ROOT/.ai project/.ai\nprint ✓ .ai symlinked"]
|
||
P3 --> P5
|
||
P4 --> P5
|
||
|
||
P5{".ai in project/.gitignore?"}
|
||
P5 -- "Yes" --> P6["skip silently"]
|
||
P5 -- "No" --> P7["append .ai print ✓"]
|
||
P6 --> P8
|
||
P7 --> P8
|
||
|
||
P8{"project/docs/ exists?"}
|
||
P8 -- "Yes" --> P10
|
||
P8 -- "No" --> TTY{"stdin is TTY?\n[ -t 0 ]"}
|
||
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
|
||
|
||
P10{"docs/ai-context.md exists?"}
|
||
P10 -- "No" --> P11["cp templates/ai-context.md\nprint ✓ created\ncnt_templated++"]
|
||
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
|
||
|
||
P14{"docs/architecture.md exists?"}
|
||
P14 -- "No" --> P15["cp templates/architecture.md\nprint ✓ created\ncnt_templated++"]
|
||
P14 -- "Yes marker on line 1" --> P16["cp templates/architecture.md\nprint ✓ refreshed\ncnt_refreshed++"]
|
||
P14 -- "Yes no marker" --> P17["skip — developer owns file"]
|
||
P15 --> NEXT
|
||
P16 --> NEXT
|
||
P17 --> NEXT
|
||
WARN --> SCAN1
|
||
SKIP2 --> SCAN1
|
||
end
|
||
|
||
NEXT --> SCAN1
|
||
SCAN1 -- "all projects done" --> S1
|
||
|
||
subgraph SUMMARY ["── Summary + version file ──"]
|
||
S1{"cnt_found > 0?"}
|
||
S1 -- "No" --> S2["print ⚠ no projects found\nare you in the right directory?"]
|
||
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
|
||
```
|