#!/usr/bin/env python3 import shutil, os from pathlib import Path ROOT = Path(__file__).resolve().parents[1] OUT = ROOT / "install" VER = (ROOT / "VERSION").read_text().strip() if (ROOT / "VERSION").exists() else "0.1.0" BUNDLE = OUT / f"cascadingdev-{VER}" def main(): # Removes the old install bundle if it already exists if BUNDLE.exists(): shutil.rmtree(BUNDLE) # Create the directories (BUNDLE / "assets" / "hooks").mkdir(parents=True, exist_ok=True) (BUNDLE / "assets" / "templates").mkdir(parents=True, exist_ok=True) # Copy the git hook and any other runtime utilities. shutil.copy2(ROOT / "assets" / "runtime" / "ramble.py", BUNDLE / "ramble.py") shutil.copy2(ROOT / "assets" / "runtime" / "create_feature.py", BUNDLE / "create_feature.py") shutil.copy2(ROOT / "assets" / "hooks" / "pre-commit", BUNDLE / "assets" / "hooks" / "pre-commit") # copy core templates for t in [ "feature_request.md", "feature.discussion.md", "feature.discussion.sum.md", "design.discussion.md", "design_doc.md", "USER_GUIDE.md", "root_gitignore", ]: shutil.copy2(ROOT / "assets" / "templates" / t, BUNDLE / "assets" / "templates" / t) # copy (recursively) the contents of process/ and rules/ templates folders def copy_tree(src, dst): if dst.exists(): shutil.rmtree(dst) shutil.copytree(src, dst) copy_tree(ROOT / "assets" / "templates" / "process", BUNDLE / "assets" / "templates" / "process") copy_tree(ROOT / "assets" / "templates" / "rules", BUNDLE / "assets" / "templates" / "rules") # copy shared AI configuration config_src = ROOT / "config" if config_src.exists(): copy_tree(config_src, BUNDLE / "config") # copy automation directory (workflow.py and future orchestration scripts) automation_src = ROOT / "automation" if automation_src.exists(): copy_tree(automation_src, BUNDLE / "automation") # write installer entrypoint shutil.copy2(ROOT / "src" / "cascadingdev" / "setup_project.py", BUNDLE / "setup_cascadingdev.py") install_doc = """# CascadingDev Installer ## Requirements - Python 3.10+ and git - (Optional) PySide6 or PyQt5 for the Ramble GUI ## Quick Start ```bash python setup_cascadingdev.py --target /path/to/your-project ``` ### Options - `--target PATH`: directory to create or reuse for the repo - `--no-ramble`: skip the Ramble GUI and answer prompts in the terminal - `--provider {mock,claude}`: select the Ramble provider (default: mock) - `--claude-cmd CMD`: command to invoke when provider is `claude` ### Steps Performed 1. Creates the standard CascadingDev folder layout in the target. 2. Copies templates, policies, rules, and runtime scripts into place. 3. Initializes git (if needed) and installs the pre-commit hook. 4. Launches Ramble unless `--no-ramble` is provided. 5. Seeds initial feature discussions, summaries, and rules. 6. Commits the bootstrap state so the repo starts clean. ### Troubleshooting - If the GUI fails, activate a virtualenv then `pip install PySide6`, or rerun with `--no-ramble`. - Ensure `git` is available on PATH; the installer runs `git init` and `git commit`. - Remove or empty the target directory if rerunning into conflicting files. """ (BUNDLE / "INSTALL.md").write_text(install_doc.strip() + "\n", encoding="utf-8") (BUNDLE / "VERSION").write_text(VER, encoding="utf-8") print(f"[✓] Built installer → {BUNDLE}") if __name__ == "__main__": main()