Skip to content

Commit edf0d79

Browse files
committed
Adding story profiler to prompt foo
1 parent 32b2da0 commit edf0d79

1 file changed

Lines changed: 121 additions & 1 deletion

File tree

prompt_foo.py

Lines changed: 121 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -798,6 +798,125 @@ def annotate_foo_files_in_place():
798798
except Exception as e:
799799
logger.print(f"Warning: Failed to auto-annotate foo_files.py: {e}")
800800

801+
# ============================================================================
802+
# --- Orphanage & Repository Profiling ---
803+
# ============================================================================
804+
STORY_EXTENSIONS = {
805+
'.py', '.js', '.css', '.html', '.md', '.markdown', '.txt',
806+
'.json', '.nix', '.sh', '.ipynb', '.toml', '.in', '.cfg',
807+
'.svg', '.xsd',
808+
}
809+
810+
def collect_repo_files(repo_root: str) -> set:
811+
"""Use `git ls-files` to get only tracked, non-ignored files."""
812+
try:
813+
result = subprocess.run(
814+
['git', 'ls-files'],
815+
capture_output=True, text=True, cwd=repo_root, check=True
816+
)
817+
repo_files = set()
818+
for line in result.stdout.strip().splitlines():
819+
line = line.strip()
820+
if not line:
821+
continue
822+
ext = os.path.splitext(line)[1].lower()
823+
if ext in STORY_EXTENSIONS:
824+
repo_files.add(line)
825+
return repo_files
826+
except (subprocess.CalledProcessError, FileNotFoundError):
827+
logger.print("⚠️ `git ls-files` failed. Cannot run Orphanage check.\n")
828+
return set()
829+
830+
def update_orphanage_in_place():
831+
"""Finds unmapped files in the repo and injects them into the Orphanage section of foo_files.py."""
832+
foo_path = os.path.join(REPO_ROOT, "foo_files.py")
833+
if not os.path.exists(foo_path):
834+
return
835+
836+
try:
837+
with open(foo_path, "r", encoding="utf-8") as f:
838+
lines = f.readlines()
839+
840+
# Phase 1: Parse the current map to see what is already "claimed"
841+
in_story_section = False
842+
all_claimed_files = set()
843+
844+
for line in lines:
845+
line = line.strip()
846+
if "AI_PHOOEY_CHOP =" in line:
847+
in_story_section = True
848+
continue
849+
if not in_story_section:
850+
continue
851+
if "VIII. THE ORPHANAGE" in line:
852+
break # Stop before parsing the orphans themselves
853+
854+
clean_line = line.lstrip("#").strip()
855+
if (not clean_line or clean_line.startswith("=") or
856+
clean_line.startswith("CHAPTER") or clean_line.startswith("THE 404") or
857+
clean_line.startswith("!") or clean_line.startswith("http")):
858+
continue
859+
860+
file_path = clean_line.split()[0]
861+
ext = os.path.splitext(file_path)[1].lower()
862+
if ext in STORY_EXTENSIONS or ('/' in file_path and '.' in file_path):
863+
if os.path.isabs(file_path):
864+
if file_path.startswith(REPO_ROOT):
865+
rel_path = os.path.relpath(file_path, REPO_ROOT)
866+
all_claimed_files.add(os.path.normpath(rel_path))
867+
else:
868+
all_claimed_files.add(os.path.normpath(file_path))
869+
870+
# Phase 2: Diff the map against the territory
871+
repo_files = collect_repo_files(REPO_ROOT)
872+
if not repo_files:
873+
return # Bail if git failed
874+
875+
orphans = sorted(repo_files - all_claimed_files)
876+
877+
# Phase 3: Inject the orphans idempotently
878+
with open(foo_path, "r", encoding="utf-8") as f:
879+
foo_content = f.read()
880+
881+
ORPHAN_MARKER = "# ============================================================================\n# VIII. THE ORPHANAGE (Uncovered Files)\n# ============================================================================"
882+
marker_index = foo_content.find(ORPHAN_MARKER)
883+
884+
if marker_index != -1:
885+
base_content = foo_content[:marker_index].rstrip() + "\n\n"
886+
else:
887+
end_quote_idx = foo_content.rfind('"""')
888+
base_content = foo_content[:end_quote_idx].rstrip() + "\n\n"
889+
890+
if not orphans:
891+
with open(foo_path, "w", encoding="utf-8") as f:
892+
f.write(base_content + '\n"""\n')
893+
return # Clean exit, no orphans
894+
895+
orphan_lines = [
896+
ORPHAN_MARKER,
897+
"# Files tracked by git but not listed in any chapter above.",
898+
"# Move these into the active chapters to grant the AI visibility.\n"
899+
]
900+
901+
logger.print(f"👻 Injecting {len(orphans)} unmapped files into the Orphanage...")
902+
for orphan_path in orphans:
903+
full_path = os.path.join(REPO_ROOT, orphan_path)
904+
try:
905+
with open(full_path, "r", encoding="utf-8") as f:
906+
content = f.read()
907+
tokens = count_tokens(content)
908+
b_size = len(content.encode('utf-8'))
909+
orphan_lines.append(f"# {orphan_path} # [{tokens:,} tokens | {b_size:,} bytes]")
910+
except Exception:
911+
orphan_lines.append(f"# {orphan_path} # [Error reading file]")
912+
913+
final_content = base_content + "\n".join(orphan_lines) + '\n"""\n'
914+
915+
with open(foo_path, "w", encoding="utf-8") as f:
916+
f.write(final_content)
917+
918+
except Exception as e:
919+
logger.print(f"Warning: Failed to update the Orphanage: {e}")
801920

802921
# ============================================================================
803922
# --- Main Execution Logic ---
@@ -862,7 +981,8 @@ def main():
862981
with open("prompt.md", 'r', encoding='utf-8') as f: prompt_content = f.read()
863982

864983
# 2. Process all specified files
865-
annotate_foo_files_in_place() # <-- ADD THIS LINE
984+
annotate_foo_files_in_place()
985+
update_orphanage_in_place() # <-- THE NEW SENSOR PING
866986
files_to_process = parse_file_list_from_config()
867987
processed_files_data = []
868988

0 commit comments

Comments
 (0)