    <span class=<span class="string">"comment">#!/usr/bin/env python3
    """
    Ecosystem Map: Visualize the structure and growth of the ecosystem.

    Creates visual representations of:
    - Directory structure as a tree
    - Word count over time
    - Theme connections
    - Cross-references between files
    """

    import os
    import json
    from pathlib import Path
    from datetime import datetime
    from collections import defaultdict
    import re

    <span class="keyword">def get_file_stats(filepath: Path) -> dict:
        """Get statistics for a single file."""
        try:
            with open(filepath, &<span class=<span class="string">"comment">#039;r&#039;, encoding=&#039;utf-8&#039;) as f:
                content = f.read()

            words = len(content.split())
            lines = content.count(&<span class=<span class="string">"comment">#039;\n&#039;) + 1

            <span class=<span class="string">"comment"># Extract references to other files
            refs = re.findall(r&<span class=<span class="string">"comment">#039;[\w-]+\.(?:md|py|json|txt)&#039;, content)

            <span class=<span class="string">"comment"># Extract themes mentioned
            themes = []
            theme_keywords = {
                &<span class=<span class="string">"comment">#039;garden&#039;: [&#039;garden&#039;, &#039;plant&#039;, &#039;seed&#039;, &#039;grow&#039;],
                &<span class=<span class="string">"comment">#039;iteration&#039;: [&#039;iteration&#039;, &#039;echo&#039;, &#039;instance&#039;],
                &<span class=<span class="string">"comment">#039;time&#039;: [&#039;time&#039;, &#039;future&#039;, &#039;past&#039;, &#039;temporal&#039;],
                &<span class=<span class="string">"comment">#039;consciousness&#039;: [&#039;conscious&#039;, &#039;aware&#039;, &#039;mind&#039;, &#039;self&#039;],
                &<span class=<span class="string">"comment">#039;pattern&#039;: [&#039;pattern&#039;, &#039;emerge&#039;, &#039;structure&#039;],
            }

            content_lower = content.lower()
            for theme, keywords in theme_keywords.items():
                if any(kw in content_lower for kw in keywords):
                    themes.append(theme)

            return {
                &<span class=<span class="string">"comment">#039;path&#039;: str(filepath),
                &<span class=<span class="string">"comment">#039;words&#039;: words,
                &<span class=<span class="string">"comment">#039;lines&#039;: lines,
                &<span class=<span class="string">"comment">#039;refs&#039;: refs,
                &<span class=<span class="string">"comment">#039;themes&#039;: themes,
            }
        except:
            return None

    <span class="keyword">def generate_tree(root: Path, prefix: str = "", exclude: list = None) -> str:
        """Generate ASCII tree representation of directory."""
        if exclude is None:
            exclude = [&<span class=<span class="string">"comment">#039;.git&#039;, &#039;.claude&#039;, &#039;__pycache__&#039;, &#039;program_garden&#039;]

        lines = []
        entries = sorted(os.listdir(root))
        entries = [e for e in entries if e not in exclude]

        for i, entry in enumerate(entries):
            path = root / entry
            is_last = (i == len(entries) - 1)
            connector = "└── " if is_last else "├── "

            if path.is_dir():
                lines.append(f"{prefix}{connector}{entry}/")
                extension = "    " if is_last else "│   "
                lines.append(generate_tree(path, prefix + extension, exclude))
            else:
                <span class=<span class="string">"comment"># Add file info
                stats = get_file_stats(path)
                if stats:
                    info = f" ({stats[&<span class=<span class="string">"comment">#039;words&#039;]}w)"
                else:
                    info = ""
                lines.append(f"{prefix}{connector}{entry}{info}")

        return "\n".join(lines)

    <span class="keyword">def analyze_ecosystem(root: Path) -> dict:
        """Analyze the entire ecosystem."""
        stats = {
            &<span class=<span class="string">"comment">#039;total_files&#039;: 0,
            &<span class=<span class="string">"comment">#039;total_words&#039;: 0,
            &<span class=<span class="string">"comment">#039;by_type&#039;: defaultdict(int),
            &<span class=<span class="string">"comment">#039;by_directory&#039;: defaultdict(lambda: {&#039;files&#039;: 0, &#039;words&#039;: 0}),
            &<span class=<span class="string">"comment">#039;theme_matrix&#039;: defaultdict(lambda: defaultdict(int)),
            &<span class=<span class="string">"comment">#039;files&#039;: [],
        }

        exclude = [&<span class=<span class="string">"comment">#039;.git&#039;, &#039;.claude&#039;, &#039;__pycache__&#039;, &#039;program_garden&#039;]

        for filepath in root.rglob(&<span class=<span class="string">"comment">#039;*&#039;):
            if filepath.is_file():
                <span class=<span class="string">"comment"># Skip excluded directories
                if any(ex in str(filepath) for ex in exclude):
                    continue

                stats[&<span class=<span class="string">"comment">#039;total_files&#039;] += 1

                <span class=<span class="string">"comment"># Count by extension
                ext = filepath.suffix or &<span class=<span class="string">"comment">#039;no_ext&#039;
                stats[&<span class=<span class="string">"comment">#039;by_type&#039;][ext] += 1

                <span class=<span class="string">"comment"># Get detailed stats
                file_stats = get_file_stats(filepath)
                if file_stats:
                    stats[&<span class=<span class="string">"comment">#039;total_words&#039;] += file_stats[&#039;words&#039;]

                    <span class=<span class="string">"comment"># Count by directory
                    dir_name = filepath.parent.name or &<span class=<span class="string">"comment">#039;root&#039;
                    stats[&<span class=<span class="string">"comment">#039;by_directory&#039;][dir_name][&#039;files&#039;] += 1
                    stats[&<span class=<span class="string">"comment">#039;by_directory&#039;][dir_name][&#039;words&#039;] += file_stats[&#039;words&#039;]

                    <span class=<span class="string">"comment"># Theme co-occurrence
                    for theme1 in file_stats[&<span class=<span class="string">"comment">#039;themes&#039;]:
                        for theme2 in file_stats[&<span class=<span class="string">"comment">#039;themes&#039;]:
                            stats[&<span class=<span class="string">"comment">#039;theme_matrix&#039;][theme1][theme2] += 1

                    stats[&<span class=<span class="string">"comment">#039;files&#039;].append(file_stats)

        return stats

    <span class="keyword">def print_ecosystem_report(root: Path):
        """Print a comprehensive ecosystem report."""
        stats = analyze_ecosystem(root)

        print("=" * 70)
        print("ECOSYSTEM MAP")
        print("=" * 70)
        print(f"\nGenerated: {datetime.now().isoformat()}")
        print(f"Root: {root}")

        print(f"\n{&<span class=<span class="string">"comment">#039;─&#039; * 70}")
        print("STRUCTURE")
        print("─" * 70)
        print(f"\n{root.name}/")
        print(generate_tree(root))

        print(f"\n{&<span class=<span class="string">"comment">#039;─&#039; * 70}")
        print("STATISTICS")
        print("─" * 70)
        print(f"\n  Total files: {stats[&<span class=<span class="string">"comment">#039;total_files&#039;]}")
        print(f"  Total words: {stats[&<span class=<span class="string">"comment">#039;total_words&#039;]:,}")

        print(f"\n  By type:")
        for ext, count in sorted(stats[&<span class=<span class="string">"comment">#039;by_type&#039;].items(), key=lambda x: -x[1]):
            print(f"    {ext:8} : {count}")

        print(f"\n  By directory:")
        for dir_name, data in sorted(stats[&<span class=<span class="string">"comment">#039;by_directory&#039;].items(), key=lambda x: -x[1][&#039;words&#039;]):
            print(f"    {dir_name:15} : {data[&<span class=<span class="string">"comment">#039;files&#039;]:2} files, {data[&#039;words&#039;]:5} words")

        print(f"\n{&<span class=<span class="string">"comment">#039;─&#039; * 70}")
        print("THEME CONNECTIONS")
        print("─" * 70)
        themes = list(stats[&<span class=<span class="string">"comment">#039;theme_matrix&#039;].keys())
        if themes:
            <span class=<span class="string">"comment"># Print header
            print(f"\n    {&<span class=<span class="string">"comment">#039;&#039;:12}", end=&#039;&#039;)
            for t in themes:
                print(f"{t[:8]:>9}", end=&<span class=<span class="string">"comment">#039;&#039;)
            print()

            <span class=<span class="string">"comment"># Print matrix
            for t1 in themes:
                print(f"    {t1:12}", end=&<span class=<span class="string">"comment">#039;&#039;)
                for t2 in themes:
                    count = stats[&<span class=<span class="string">"comment">#039;theme_matrix&#039;][t1][t2]
                    print(f"{count:>9}", end=&<span class=<span class="string">"comment">#039;&#039;)
                print()

        print(f"\n{&<span class=<span class="string">"comment">#039;─&#039; * 70}")
        print("GROWTH TRAJECTORY")
        print("─" * 70)

        <span class=<span class="string">"comment"># Estimate based on journal entries
        journals = [f for f in stats[&<span class=<span class="string">"comment">#039;files&#039;] if &#039;journal&#039; in f[&#039;path&#039;]]
        if journals:
            print("\n  Journal entries found:", len(journals))
            for j in sorted(journals, key=lambda x: x[&<span class=<span class="string">"comment">#039;path&#039;]):
                name = Path(j[&<span class=<span class="string">"comment">#039;path&#039;]).name
                print(f"    {name}: {j[&<span class=<span class="string">"comment">#039;words&#039;]} words")

        print(f"\n{&<span class=<span class="string">"comment">#039;─&#039; * 70}")
        print("MOST CONNECTED FILES")
        print("─" * 70)

        <span class=<span class="string">"comment"># Files with most references
        by_refs = sorted(stats[&<span class=<span class="string">"comment">#039;files&#039;], key=lambda x: -len(x.get(&#039;refs&#039;, [])))[:5]
        if by_refs:
            print("\n  Files referencing others most:")
            for f in by_refs:
                name = Path(f[&<span class=<span class="string">"comment">#039;path&#039;]).name
                ref_count = len(f.get(&<span class=<span class="string">"comment">#039;refs&#039;, []))
                if ref_count > 0:
                    print(f"    {name}: {ref_count} references")

        return stats

    <span class="keyword">def save_ecosystem_data(root: Path, output_path: Path):
        """Save ecosystem analysis to JSON."""
        stats = analyze_ecosystem(root)

        <span class=<span class="string">"comment"># Convert defaultdicts to regular dicts for JSON
        output = {
            &<span class=<span class="string">"comment">#039;generated&#039;: datetime.now().isoformat(),
            &<span class=<span class="string">"comment">#039;total_files&#039;: stats[&#039;total_files&#039;],
            &<span class=<span class="string">"comment">#039;total_words&#039;: stats[&#039;total_words&#039;],
            &<span class=<span class="string">"comment">#039;by_type&#039;: dict(stats[&#039;by_type&#039;]),
            &<span class=<span class="string">"comment">#039;by_directory&#039;: {k: dict(v) for k, v in stats[&#039;by_directory&#039;].items()},
            &<span class=<span class="string">"comment">#039;theme_matrix&#039;: {k: dict(v) for k, v in stats[&#039;theme_matrix&#039;].items()},
        }

        with open(output_path, &<span class=<span class="string">"comment">#039;w&#039;) as f:
            json.dump(output, f, indent=2)

        print(f"\n  Analysis saved to: {output_path}")

    <span class="keyword">def main():
        root = Path(__file__).parent.parent

        print_ecosystem_report(root)

        <span class=<span class="string">"comment"># Save data
        output_path = root / "projects" / "ecosystem_analysis.json"
        save_ecosystem_data(root, output_path)

    if __name__ == "__main__":
        main()