ai-workflow-test/workflow-init.py

105 lines
3.9 KiB
Python
Executable File

#!/usr/bin/env python3
"""workflow-init.py
Interactive initializer for the AI workflow repo.
- Replaces placeholders like ai-workflow-test, https://gitea.brrd.tech/rob/test-workflow, rob, 40 messages, main
- Honors default syntax default
- Optionally git init + first commit
Usage:
python3 workflow-init.py [--path .] [--no-git]
"""
import argparse, os, re, sys, subprocess
from pathlib import Path
PLACEHOLDER_PATTERN = re.compile(r"\{\{([^}|]+)(?:\|([^}]*))?\}\}")
TEXT_EXTS = {".md", ".txt", ".yml", ".yaml", ".json", ".toml", ".py", ".sh", ".gitignore", ""}
def prompt(question, default=None):
val = input(f"{question}" + (f" [{default}]" if default else "") + ": ").strip()
return val or (default or "")
def is_text_file(p: Path):
if p.name.startswith(".git"): return False
if p.is_dir(): return False
if p.suffix in TEXT_EXTS: return True
try:
p.read_bytes().decode("utf-8")
return True
except Exception:
return False
def replace_placeholders(text: str, mapping: dict) -> str:
def sub(m):
var, default = m.group(1), m.group(2)
return mapping.get(var, default or "")
return PLACEHOLDER_PATTERN.sub(sub, text)
def replace_in_file(p: Path, mapping: dict):
try:
orig = p.read_text(encoding="utf-8")
except Exception:
return False
new = replace_placeholders(orig, mapping)
if new != orig:
p.write_text(new, encoding="utf-8")
return True
return False
def git(cmd, cwd):
return subprocess.run(["git"] + cmd, cwd=cwd, check=False, capture_output=True, text=True)
def main():
ap = argparse.ArgumentParser()
ap.add_argument("--path", default=".", help="Repository root path")
ap.add_argument("--no-git", action="store_true", help="Do not run git init/commit")
args = ap.parse_args()
root = Path(args.path).resolve()
if not root.exists():
print(f"Path not found: {root}", file=sys.stderr); sys.exit(1)
print("Welcome! Let's initialize your AI workflow repository.\n")
mapping = {
"PROJECT_NAME": prompt("Project name", "MyProject"),
"PRIMARY_OWNER": prompt("Primary owner/handle (for CODEOWNERS)", "your-handle"),
"REPO_URL": prompt("Gitea repo URL (you can set later)", "https://gitea.example.com/you/myproject"),
"TIMEBOX": prompt("Default timebox (e.g., '40 messages or 60 minutes')", "40 messages or 60 minutes"),
"DEFAULT_BRANCH": prompt("Default branch", "main"),
}
print("\nReplacing placeholders...")
changed = 0
for p in root.rglob("*"):
if is_text_file(p):
if replace_in_file(p, mapping):
changed += 1
print(f"Updated {changed} files with your settings.")
(root / "reports").mkdir(parents=True, exist_ok=True)
(root / "project/tasks.yaml").write_text("# tasks: []\n", encoding="utf-8") if not (root / "project/tasks.yaml").exists() else None
if not args.no_git:
if not (root / ".git").exists():
print("\nInitializing git repository...")
r = git(["init"], cwd=root)
if r.returncode != 0:
print("git init failed:", r.stderr, file=sys.stderr)
if mapping["DEFAULT_BRANCH"] != "master":
r = git(["checkout", "-B", mapping["DEFAULT_BRANCH"]], cwd=root)
if r.returncode != 0:
print("git branch setup failed:", r.stderr, file=sys.stderr)
git(["add", "-A"], cwd=root)
r = git(["commit", "-m", "chore(init): bootstrap AI workflow repository"], cwd=root)
if r.returncode != 0:
print("git commit failed:", r.stderr, file=sys.stderr)
print("\nDone. Next steps:")
print(f" 1) Review {root/'project/plan.md'} and {root/'project/state.md'}")
print(f" 2) Set remote: git remote add origin {mapping['REPO_URL']}")
print(f" 3) Push: git push -u origin {mapping['DEFAULT_BRANCH']}")
print(" 4) Start Mission Control with: python3 workflow.py start-mc")
if __name__ == '__main__':
main()