#!/usr/bin/env python3 import os, sys def load_manifest(path): # Minimal YAML parser for our simple manifests: # keys: name (ignored), include: [..], modules: [..] data = {"include": [], "modules": []} key = None with open(path, 'r', encoding='utf-8') as f: for raw in f: line = raw.rstrip('\n') s = line.strip() if not s or s.startswith('#'): continue if s.startswith('include:'): key = 'include' continue if s.startswith('modules:'): key = 'modules' continue if s.startswith('name:'): key = None continue # list item under current key if key in ('include', 'modules') and s.startswith('- '): item = s[2:].strip() data[key].append(item) return data def resolve(path, seen): m = load_manifest(path) includes = m.get('include', []) or [] modules = m.get('modules', []) or [] for inc in includes: resolve(inc, seen) for mod in modules: if mod not in seen: seen.append(mod) return seen def words(s: str) -> int: return len(s.split()) def main(): if len(sys.argv) != 3: print("Usage: prompt_build.py ", file=sys.stderr) sys.exit(2) manifest, out_path = sys.argv[1], sys.argv[2] mods = resolve(manifest, []) if not mods: print(f"No modules resolved from {manifest}", file=sys.stderr) sys.exit(1) if out_path != '-': os.makedirs(os.path.dirname(out_path), exist_ok=True) def read(p): with open(p, 'r', encoding='utf-8') as f: return f.read().strip() + "\n\n" parts = ["Generated Prompt Pack\n\n"] for m in mods: parts.append(f"--- {m} ---\n") parts.append(read(m)) content = "".join(parts) # budgets total_words = words(content) BASE_BUDGET = 1200 if total_words > BASE_BUDGET: print(f"ERROR: Pack exceeds budget: {total_words} > {BASE_BUDGET}", file=sys.stderr) sys.exit(3) ERRORS = 0 MOD_BUDGET = 400 for m in mods: with open(m, 'r', encoding='utf-8') as f: wc = words(f.read()) if wc > MOD_BUDGET: print(f"ERROR: Module {m} exceeds budget: {wc} > {MOD_BUDGET}", file=sys.stderr) ERRORS += 1 if ERRORS: sys.exit(4) if out_path == '-': sys.stdout.write(content) else: with open(out_path, 'w', encoding='utf-8') as out: out.write(content) print(f"Built {out_path} with {total_words} words across {len(mods)} modules.", file=sys.stderr) if __name__ == '__main__': main()