diff --git a/AI-MAP.md b/AI-MAP.md new file mode 100644 index 000000000..ef7631c92 --- /dev/null +++ b/AI-MAP.md @@ -0,0 +1,189 @@ +# מפת התיעוד לסוכני AI + + + +שורה לכל עמוד ידני באתר התיעוד: נתיב, כותרת, והתקציר שהעמוד מצהיר עליו בראשו (`:summary:` ב-rst, `summary` ב-front matter). עמוד בלי הצהרה מופיע עם הכותרת בלבד. ההיררכיה נגזרת מה-toctree. עמודי פיגום של autodoc מסוננים — התוכן שלהם נוצר רק בזמן בנייה; לחתימות קראו את הקוד עצמו. + +## למפתחים ולסוכני AI + +- `docs/quickstart-ai.rst` — **התחלה מהירה - סוכני AI**: מסמך זה נועד לאפשר לסוכן AI להתחיל לעבוד על הריפו במהירות ובבטחה, בהתאם למדיניות הפרויקט. +- `docs/quickstart.rst` — **התחלה מהירה - מפתחים**: הצעדים להרצה מקומית מהירה של הבוט, מהתקנה ועד הפעלה. +- `docs/quickstart-contrib.rst` — **Quickstart לתרומה**: דף קצר שמאפשר להתחיל לתרום במהירות ובבטחה. +- `docs/ai-guidelines.rst` — **הנחיות מלאות לסוכני AI**: ההנחיות המלאות לסוכני AI שעובדים בריפו: המגבלות הקריטיות, איך מריצים פקודות, אילו כלי קבצים מאושרים, עקרונות עריכת קוד, ומדיניות הקומיטים וה-Pull Requests. +- `docs/agents/rate-limiting.md` — **🚦 מערכת Rate Limiting לסוכני AI ולווב**: מטרה: להסביר איך מפעילים ומנטרים Rate Limiting בבוט ובווב, עם דגש על Shadow Mode, ניטור וקונפיג. +- `docs/doc-authoring.rst` — **Doc Authoring Guide (Sphinx/RTD)**: כללי כתיבת תיעוד בפרויקט — הצהרת תקציר בראש כל עמוד, הטמעת קוד לפי שם או סימון ולא לפי מספרי שורות, ובנייה ללא אזהרות. +- `docs/style-glossary.rst` — **Style & Naming Glossary**: מילון המונחים והשמות בפרויקט: מיפוי בין מונחים מקבילים, כללי הניסוח, ועוגני התיעוד שמפנים אליהם. +- `docs/versioning-stable-anchors.rst` — **Versioning & Stable Anchors**: מדיניות הגרסאות והעוגנים היציבים בתיעוד: אילו עוגנים מובטחים לא להישבר, איך מתעדים שינוי ב-What's New, ודוגמאות. +- `docs/whats-new.rst` — **What's New**: יומן השינויים של הבוט וה-WebApp לפי תאריך — מה נוסף, מה השתנה ומה תוקן בכל עדכון, עם קישורים ל-Issues הרלוונטיים. +- `docs/architecture.rst` — **ארכיטקטורה**: המערכת מורכבת מבוט Telegram, שכבת שירותים (services), שכבת נתונים (MongoDB) ואפליקציית Web. הזרימה העיקרית: Handlers → Services → Database. + - `docs/architecture/clean-architecture.rst` — **Clean Architecture ב-src**: ארכיטקטורה זו מפרידה בין לוגיקה עסקית, תזמור יישומי ותשתיות כך שניתן לבדוק יחידות קוד בנפרד, להחליף מקורות נתונים בלי לשבור את שאר המערכת ולרוץ גם בסביבות ללא MongoDB. +- `docs/contributing.rst` — **מדריך תרומה**: לתת מסלול ברור לתרומות קוד, עם דגש על סוכני AI ו-CI. +- `docs/branch-protection-and-pr-rules.rst` — **Branch Protection & PR Rules**: לרכז נהלים ברורים להגנה על ענפים (Branch Protection) ולחוקי PR בפרויקט. + +## מדריכים בסיסיים + +- `docs/installation.rst` — **התקנה והגדרה**: דף זה מכיל הוראות התקנה מפורטות עבור Code Keeper Bot. +- `docs/configuration.rst` — **Rate Limiting**: רפרנס הקונפיגורציה של המערכת: Rate Limiting, משתני סביבה, Pooling ו-Timeouts למסדי הנתונים ול-Redis, לקוחות ה-HTTP הסינכרוני והאסינכרוני, Flask, הבוט והמדדים. +- `docs/environment-variables.rst` — **משתני סביבה - רפרנס**: רפרנס משתני הסביבה: הטבלה המרכזית, משתני התראות וניטור, מדדים ו-OTEL, תפעול ואינטגרציות, דגלי בדיקות, ודוגמאות קונפיגורציה כולל טבלת ה-Scopes של GitHub. +- `docs/performance-bible.md` — **🚀 The Performance Bible: CodeKeeper Optimization Guide**: עקרונות הביצועים של המערכת אחרי הרפקטור שהוריד את ה-p95 מ-1.8 שניות ל-200ms: Cache First, Projection, חישוב ב-DB, אינדקסים מורכבים, ו-Lazy Loading. +- `docs/performance-scaling.rst` — **ביצועים והרחבה (Performance & Scaling)**: עימוד, Projection, כוונון Connection Pooling ו-Timeouts, לוגי איטיות לאיתור צווארי בקבוק, והנחיות לפי סביבה. +- `docs/performance-sticky-notes.rst` — **Sticky Notes Warmup – פתרון ביצועים משולב**: העלאת timeout שכבר הוכחה בשטח, וחימום אינדקסים לפני שהתהליך מקבל תעבורה — נדבך שעדיין נבחן. כולל מה לאמת לפני rollout מלא. +- `docs/large-files-runbook.rst` — **טיפול בקבצים גדולים (Large Files)**: ראנבוק לטיפול בקבצים גדולים: המגבלות והפולבקים, הנחיות ההפעלה, ומה לנטר. + +## API Reference + +- `docs/api/index.rst` — **API Reference**: תיעוד מלא של ה-API של Code Keeper Bot. + - `docs/api/handlers.documents.rst` — **handlers.documents module**: מנתב קבצים שנשלחים לבוט לפי ``upload_mode``: שחזור ZIP לריפו GitHub, ייבוא ZIP, וקבצי טקסט שנשמרים דרך שכבת הקבצים. כולל ולידציה והגנות מפני 'פצצת ZIP'. + - `docs/api/modules.rst` — **workspace**: אינדקס המודולים של התיעוד האוטומטי — נקודת הכניסה לעמודי ה-API שנוצרים מ-autodoc בזמן הבנייה. + - `docs/api/refactoring_engine.rst` — **refactoring\_engine module**: מנוע הרפקטורינג: המדיניות והקונפיגורציה, קיבוץ לפי קוהזיה שמונע Oversplitting ו-God Class, והמקרה המיוחד של פירוק בטוח ל-models.py. +- `docs/modules/index.rst` — **מודולים ראשיים**: תיעוד מפורט של המודולים הראשיים בפרויקט. +- `docs/handlers/index.rst` — **Handlers**: תיעוד של כל ה-handlers בפרויקט. + - `docs/handlers/show.rst` — **Show Command**: מפרט פקודת /show: מבנה תגובת ה-HTML, שורות הכפתורים (מחיקה, עריכה, הערה, הורדה, שיתוף ומועדפים), והערות יישום. + - `docs/handlers/drive_menu.rst` — **Drive Menu V2**: תפריט הגיבוי ל‑Google Drive (גרסת V2) כולל בחירה מהירה (קבצי גיבוי/הכל/מתקדם), בחירת תיקיית יעד (אוטומטי/ברירת מחדל/מותאם), תזמון גיבוי, וטיפול שגיאות ברור. + - `docs/handlers/document-flow.rst` — **זרימת הטיפול במסמכים (Document Flow)**: המפה בין הרכיבים שמטפלים בקובץ שנשלח לבוט, מצבי upload_mode, התלויות שמוזרקות ל-DocumentHandler, ושכבת האחסון (FilesFacade מול ה-DB הישן). +- `docs/services/index.rst` — **Services**: תיעוד של שירותי הליבה של המערכת. + - `docs/services/google_drive_service.rst` — **Google Drive Service**: שירות Google Drive: אימות ב-Device Flow, ניהול טוקנים, יצירת ZIP והעלאה לתיקיות לפי קטגוריה (ובקטגוריית 'לפי ריפו' גם תת-תיקייה לשם הריפו). התאריך והגרסה נכנסים לשם קובץ ה-ZIP, לא למבנה התיקיות. +- `docs/database/index.rst` — **Database**: תיעוד של מערכת מסד הנתונים והמודלים. + - `docs/database/bookmarks-manager.rst` — **מנהל סימניות – BookmarksManager**: database.bookmarks_manager.BookmarksManager הוא שכבת ה-DB הראשית שמאחורי פיצ'ר הסימניות. הוא דואג לולידציה, לאכיפת מגבלות, ליצירת אינדקסים ולסנכרון הסימניות מול שינויים בקבצי הקוד. + - `docs/database/collections-manager.rst` — **מנהל אוספים – CollectionsManager**: פיצ'ר "הקולקציות שלי" נשען על database.collections_manager.CollectionsManager – שכבת שירות שמספקת CRUD מלא, חוקים חכמים, שיתוף ציבורי, ניהול פריטים ופעילות שיתופים. העמוד מסכם את המבנה כדי שיהיה קל לחבר פיצ'רים חדשים. +- `docs/database/indexing.rst` — **MongoDB Indexing Cookbook**: ספר מתכונים לאינדקסים ב-MongoDB: אילו אינדקסים מומלצים, מתכוני PyMongo, קריאת explain, ובדיקת קיום אינדקסים. +- `docs/database/cursor-pagination.rst` — **Cursor-based Pagination (created_at / _id)**: דפדוף מבוסס קורסור על created_at ו-_id: עקרונות מיון יציב, קידוד ופענוח הקורסור, תבניות שאילתה לשני הכיוונים, ודוגמת PyMongo מלאה. +- `docs/database-schema.rst` — **Database Schema**: סכמת מסד הנתונים: האוספים code_snippets, users, bookmarks ו-sessions, השדות בכל אחד, והאינדקסים. +- `docs/database/detailed-schema.rst` — **מבנה נתונים מפורט (Detailed Database Schema)**: מסמך זה מתאר בפירוט את כל האוספים, השדות, האילוצים והאינדקסים במסד הנתונים. + +## עזרה ודוגמאות + +- `docs/examples.rst` — **דוגמאות שימוש**: דף זה מכיל דוגמאות קוד לשימוש ב-API של Code Keeper Bot. +- `docs/testing.rst` — **Testing Guide**: Quickstart להרצת טסטים, ההנחיות הקריטיות, טעינת ה-stubs לטלגרם, עבודה עם tmp_path ומתכון מחיקה מוגבל ל-allowlist, ו-mocking של HTTP. +- `docs/testing-rate-limit-examples.rst` — **דוגמאות טסטים – Rate Limiting ואסינכרוניות**: קטעי דוגמה לכתיבת טסטים ל-Rate Limiting מול Redis מדומה ולקוד אסינכרוני. הקטעים אינם ניתנים להרצה כמות שהם — הם מדלגים על הקשר עם ``...`` ומניחים פונקציות מקומיות. +- `docs/performance-tests.rst` — **בדיקות ביצועים (Performance Tests)**: להריץ בדיקות ביצועים בצורה בטוחה וגמישה: ברירת מחדל מריצים את כולן; ב‑PR Draft עם תווית מתאימה מריצים רק "קלים". +- `docs/ci-cd.rst` — **CI/CD Guide**: מדריך ה-CI/CD: החוקים הקשיחים, הסטטוסים הנדרשים ב-PR, ריכוז ה-workflows, הבדיקות המומלצות ובניית התיעוד. +- `docs/conversation-handlers.rst` — **Conversation Handlers & States**: מסמך זה מרכז את הזרימות העיקריות של ה‑ConversationHandlers וה‑states. +- `docs/troubleshooting.rst` — **Troubleshooting Guide**: מדריך פתרון תקלות: שגיאות ייבוא בזמן טסטים, שגיאות parse_mode, בעיות event loop של asyncio, וכלים לדיבוג מהיר כולל בדיקת חיבור ל-MongoDB. +- `docs/development.rst` — **Development Workflow**: זרימת העבודה בפיתוח: הוספת handler חדש לבוט, הוספת endpoint ל-WebApp, ועדכון סכמה במסד הנתונים. +- `docs/development/pre-commit.rst` — **Pre-commit Hooks**: להבטיח איכות קוד עקבית לפני קומיט/PR. +- `docs/development/tools.rst` — **כלי עזר למפתחים**: הכלים שתחת tools/: ניתוח שאילתות איטיות ואיתור קוד כפול, מתי להריץ כל אחד ומה לקרוא בפלט. +- `docs/development/scripts.rst` — **סקריפטים שימושיים**: תיקיית scripts/ מכילה כלים חד-פעמיים ותהליכי תחזוקה. לפני ההרצה ודאו שסביבת ה-DB היא סביבת ניסוי/פיתוח ושיש גיבוי עדכני. +- `docs/development/i18n.rst` — **בינאום ותמיכה בשפות**: מודול i18n/ מספק שכבת תרגום פשוטה לבוט הטלגרם וה-WebApp. נכון לעכשיו קיימת חבילת מחרוזות בעברית (strings_he.py), אך המבנה מאפשר הוספת שפות חדשות ללא שינוי בלוגיקה העסקית. +- `docs/integrations.rst` — **Integrations**: להפעלת פעולות שונות מול GitHub נדרש להגדיר לטוקן \(`GITHUB_TOKEN` או טוקן משתמש שנשמר במערכת\) את מרחבי ההרשאות המינימליים. הקפידו על עיקרון ההרשאות המצומצמות. +- `docs/mcp-server.rst` — **שרת ה-MCP — חיבור Claude ל-CodeKeeper**: שרת ה-MCP שחושף את CodeKeeper ל-Claude: הכלים, האימות וההרשאות, פריימר הסוכן, עריכה מהדפדפן, והפעלה צעד אחר צעד מול Claude.ai ומול Claude Code. +- `docs/repository-integrations.rst` — **Repository Integrations**: מסמך זה מרכז את התמיכה בספקי מאגרי קוד. מטרתו למנוע בלבול ולהבהיר מה נתמך ומה לא. +- `docs/security.rst` — **Security Guide**: אל תרשום סודות/PII בלוגים, השתמש ב‑ENV בלבד. +- `docs/monitoring.md` — **Smart Observability v7 – Predictive Health & Adaptive Feedback**: חיבור Grafana לטלגרם דרך Webhook, אנוטציות, ספים דינמיים, הפרדה בין שגיאות פנימיות לחיצוניות, ו-Predictive Health. +- `docs/git-lfs.rst` — **Git LFS Integration**: להסביר מתי ואיך להשתמש ב‑Git Large File Storage (LFS) עבור קבצים גדולים. +- `docs/user/bookmarks.rst` — **סימניות (Bookmarks)**: סימניות בקבצים: איך מוסיפים, פאנל הסימניות, העוגן היציב שמחזיק אותן גם כשהקוד זז, ומגבלות הפרטיות והאבטחה. +- `docs/user/sticky_notes.rst` — **פתקים דביקים (Sticky Notes)**: הצמדת הערות קצרות על תצוגת קובץ (קוד/Markdown/HTML): הוספה וניהול, עיגון יציב לעומת מיקום קבוע, השילוב עם סימניות, ומגבלות הפרטיות והאבטחה. +- `docs/user/reminders.rst` — **תזכורות בבוט**: מערכת התזכורות מאפשרת למשתמשי הבוט ליצור, לדחות ולנהל תזכורות אישיות דרך שיחה אינטראקטיבית או פקודות קצרות. המידע נשמר ב-MongoDB (`reminders/database.py`) ומנוהל דרך ישויות `Reminder` ו-`ReminderConfig`. +- `docs/user/my_collections.rst` — **האוספים שלי (My Collections)**: אוספים מאפשרים לאגד יחד קבצים/קטעי קוד/סימניות תחת נושא משותף (פרויקט, משימה, מודול), כדי לשתף, לנווט ולעקוב בקלות. כל אוסף כולל שם, תיאור קצר ורשימת פריטים עם סדר מותאם. +- `docs/user/share_code.rst` — **שיתוף קוד (חשוב)**: כפתור "🔗 שתף קוד" יוצר שיתוף מהיר של קובץ דרך GitHub Gist או Pastebin. הכפתור נושא את ה-ObjectId של הגרסה שהייתה קיימת כשהוא נוצר, ולכן הוא מצמיד גרסה ואינו מבטיח את התוכן העדכני. +- `docs/user/github_browse.rst` — **עיון בקוד GitHub (כולל חיפוש בשם קובץ)**: שורת הכלים, חיפוש לפי שם קובץ, וניווט בעץ הריפו — הכול מתוך הבוט. +- `docs/user/download_repo.rst` — **הורדת ריפו**: בתפריט /github ← 📥 הורד קובץ מריפו, נווטו לתיקייה הרצויה. בתחתית הרשימה יופיע כפתור שמציין במפורש מה ייארז, למשל 📦 הורד תיקייה כ־ZIP: "logo-designer". +- `docs/BOT_TEST_PLAN_CONTAINER.md` — **תכנית בדיקות לבוט – Composition Root (Container) לשירות Snippet**: מסמך זה מתאר בדיקות ידניות מהירות לבוט לאחר העברת יצירת התלויות ל־Container דומייני/אפליקטיבי. המטרה: לוודא שה־handlers צורכים את השירות מאותה נקודת אמת, בלי לשנות לוגיקה. + +## זרימות עבודה + +- `docs/workflows/index.rst` — **זרימות עבודה (Workflows)**: מסמכים אלה מתארים את הזרימות המרכזיות במערכת. + - `docs/workflows/save-flow.rst` — **זרימת שמירת קוד (Save Flow)**: מצבי השמירה, מצב האיסוף הארוך, זיהוי סודות, טיפול בכפילויות, ונרמול הקוד לפני השמירה. + - `docs/workflows/search-flow.rst` — **זרימת חיפוש (Search Flow)**: סוגי החיפוש בזרימת הבוט — טקסט, Regex, Fuzzy, פונקציות ותוכן — עם מבנה ה-SearchIndex, הפילטרים, הטיפול בשגיאות Regex ומיון התוצאות. החיפוש הסמנטי הוא מסלול נפרד ב-WebApp. + - `docs/workflows/refactor-flow.rst` — **זרימת רפקטורינג (Refactor Flow)**: מנוע הרפקטורינג מאפשר שינוי מבנה קוד בצורה בטוחה עם אימות לפני ואחרי. + - `docs/workflows/backup-flow.rst` — **זרימת גיבוי ושחזור (Backup Flow)**: זרימת הגיבוי והשחזור מקצה לקצה: סוגי הגיבויים, יצירת גיבוי מלא, שחזור, העלאה ל-Google Drive, ניהול הגיבויים הקיימים, וייבוא ZIP חיצוני. + - `docs/workflows/gist-flow.rst` — **זרימת שיתוף ב-Gist (Gist Flow)**: נקודות הכניסה לשיתוף ב-Gist, למה ה-Gist נוצר תחת חשבון ה-GitHub של המשתמש ולא של המערכת, מצבי auth_failed, וההתנהגות fail-closed בכל מסלול כשל. + +## מנועי המערכת + +- `docs/engines/overview.rst` — **מנועי המערכת (System Engines)**: מסמך זה מתאר את המנועים המרכזיים במערכת וכיצד הם עובדים. + +## Edge Cases וטיפול בשגיאות + +- `docs/edge-cases.rst` — **Edge Cases וטיפול בשגיאות**: מסמך זה מתאר Edge Cases נפוצים במערכת וכיצד לטפל בהם. + +## איכות וקונבנציות + +- `docs/quality/type-safety.md` — **📝 Type Hints – Best Practices**: מטרה: לשמר בטיחות טיפוסים ברורה, להקשיח מודולים בהדרגה, ולא להסתמך על `type: ignore`. +- `docs/quality/code-normalization.md` — **נרמול קוד (Code Normalization)**: מסמך זה מרכז את כל מה שסוכן או מפתח צריך לדעת על מנגנון נרמול הקוד של Code Keeper Bot – למה הוא קיים, איך הוא עובד ואיך משתמשים בו ביום־יום. +- `docs/ARCHITECTURE_LAYER_RULES.md` — **כללי שכבות – CodeBot**: מטרה: לשמור גבולות שכבות ברורים ולמנוע תלות מעגלית/דליפת תשתית. + +## WebApp + +- `docs/webapp/overview.rst` — **המיני Web App (סקירה)**: מאוגוסט 2026 האייקונים אינם אמוג'ים אלא אייקונים מצוירים (SVG) בסגנון אחיד, שנשלפים מספרייט אחד. המבנה המלא, הגדלים, אופן ההוספה והמלכודות מתועדים בנפרד: language-icons. +- `docs/webapp/code-browser.rst` — **דפדפן קוד (Code Browser)**: דפדפן הקוד מאפשר צפייה וניווט בריפוזיטורים מ-GitHub ישירות בממשק ה-WebApp. +- `docs/DEV_WEB_PUSH.md` — **Web Push – Sticky Notes Reminders**: מסמך זה מסביר כיצד להפעיל ולבדוק התראות Web Push עבור תזכורות של Sticky Notes. +- `docs/webapp/user-interfaces.rst` — **ממשקי משתמשים (Web)**: אוסף המסכים והתהליכים האינטראקטיביים ב-WebApp, איפה כל אחד נמצא, ומה הוא עושה. +- `docs/webapp/snippet-library.rst` — **ספריית סניפטים (Web)**: גלריית קטעי קוד קצרים עם הדגשת תחביר, מאפייני ה-UI, והפעולות שאפשר לבצע עליה. +- `docs/webapp/onboarding.md` — **🧭 WebApp Onboarding – Welcome Modal, Interactive Tour & Theme Wizard**: תהליך ה-Onboarding ב-WebApp: Welcome Modal, סיור אינטראקטיבי מבוסס Driver.js, ואשף בחירת ערכת הנושא — כולל מנגנוני האיפוס והנקודות למפתחים. +- `docs/webapp/caching.rst` — **Caching & HTTP Validators (ETag / Last-Modified / 304)**: להקטין רוחב‑פס וזמני תגובה: אם התוכן לא השתנה, נחזיר 304 Not Modified במקום גוף מלא. כך דפדפנים ולקוחות יכולים להשתמש במטמון מקומי בצורה בטוחה ויעילה. +- `docs/webapp/advanced-caching.md` — **מערכת Caching מתקדמת עם TTL דינמי**: מסמך זה מרכז את ההמלצות והדוגמאות להטמעת מערכת caching חכמה עם TTL דינמי, כפי שגובש ב-Feature Suggestion. המטרה: שיפור מהיר של זמני תגובה, הורדת עומסים על DB, ושימור עקביות בין שרתים. +- `docs/webapp/cache-inspector.rst` — **Cache Inspector (לוח בקרה של Redis)**: כלי אדמין לצפייה ולניהול של ה-Redis cache: סטטיסטיקות כלליות, חיפוש מפתחות, הצגת TTL וסטטוס, ומחיקה בטוחה של מפתחות. +- `docs/webapp/config-inspector.rst` — **Config Inspector (סקירת משתני סביבה)**: כלי אדמין שמציג תמונת מצב של הקונפיגורציה ומשתני הסביבה, עם הסתרת ערכים רגישים. +- `docs/webapp/static-checklist.rst` — **Static Performance & Security Checklist (gzip/br, Cache, SRI)**: להבטיח טעינה מהירה ובטוחה של נכסים סטטיים (CSS/JS/Images). +- `docs/webapp/commands-catalog.rst` — **תחזוקת קטלוג הפקודות (``commands.json``)**: תחזוקת commands.json — הקטלוג שמזין את כרטיסי "קיצורי הדרך" בחיפוש הגלובלי. global_search.js טוען אותו רק בדפים שמכילים את globalSearchInput ואת searchBtn, ומוסיף כרטיסים לפי סוג (chatops/cli/playbook). +- `docs/webapp/code-execution.rst` — **הרצת קוד (Code Execution Playground)**: ב‑WebApp יש כלי שמאפשר להריץ קוד Python מתוך הדפדפן, דרך API ייעודי. +- `docs/webapp/api-reference.rst` — **WebApp API Reference**: רפרנס ה-API של ה-WebApp: ה-endpoints, זרימת האימות מול Telegram, מבנה התשובה, וקודי השגיאה הנפוצים. +- `docs/webapp/bulk-actions.rst` — **Bulk actions (בחירה מרובה)**: דף זה מתאר את יכולות הבחירה המרובה והפעולות הקבוצתיות בממשק הווב. +- `docs/webapp/editor.md` — **⌨️ עורך קוד (WebApp Editor)**: תוכן זה מסביר את טעינת העורך, מנגנון הגיבוי, וניהול העדפות. +- `docs/webapp/markdown-folding.rst` — **Markdown – מצב מצומצם (קיפול כותרות ###) – אדמין בלבד**: מטרת הפיצ'ר: לאפשר לעורכים לקפל מקומית סעיפים לפי כותרות ### (H3) בתצוגת Markdown, בלי לשנות את קובץ ה־Markdown ובלי להשפיע על תצוגה ציבורית. +- `docs/markdown_style_guide.rst` — **מדריך סגנונות וארכיטקטורת Markdown**: המסמך הזה הוא Source of Truth לעיצוב וארכיטקטורת Markdown בפרויקט. הוא מיועד למפתחים ול‑QA ויזואלי. +- `docs/webapp/smooth-scrolling.rst` — **Smooth Scrolling (WebApp) — מדריך תמציתי לסוכני AI**: מדריך זה מסביר את יכולות הגלילה החלקה שהוטמעו ב‑WebApp, כיצד להשתמש בהן באופן בטוח, ומה הדגשים לסוכני AI כדי לשמור על נגישות וביצועים. +- `docs/webapp/system-modules.rst` — **מודולים פנימיים ב-WebApp**: הקבצים הבאים בתיקיית webapp/ מנהלים תשתיות שאינן מכוסות במדריכים קודמים. העמוד מסביר את ה‑API, התלויות והסיבות לכל רכיב כדי שיהיה אפשר להרחיב או לדבג במהירות. + +## Frontend > Theming + +- `docs/webapp/theming_and_css.rst` — **מערכת ערכות הנושא והטוקנים החדשה**: ארכיטקטורת הצבעים, משתני ה-CSS והבדיקות שנדרשות לשימור חוויית הממשק בכל ערכות הנושא. מקור האמת לכל שינוי ב-CSS של ה-WebApp. +- `docs/webapp/custom_themes_guide.rst` — **ערכות נושא מותאמות אישית – מדריך מקיף**: מדריך זה מכסה את כל היבטי מערכת ערכות הנושא המותאמות אישית (Custom Themes) – מייבוא VS Code themes ועד יצירה ידנית, הגדרות מתקדמות והדגשת תחביר. +- `docs/webapp/language-icons.rst` — **אייקוני שפות התכנות**: כל קובץ ב-Web App מוצג עם אייקון שמייצג את שפת התכנות שלו. עד אוגוסט 2026 אלה היו אמוג'ים (🐍 לפייתון, 📜 ל-JavaScript); היום אלה אייקונים מצוירים בסגנון אחיד — אריח ריבועי עם גרדיאנט וסימן לבן. + +## Observability + +- `docs/observability.rst` — **אובזרווביליות (Observability)**: המטרות וקהלי היעד, התצורה, בחירת Backend ל-Traces, הגדרת OTLP לסביבות, ואינסטרומנטציה ידנית. +- `docs/observability/background-jobs-monitor.rst` — **Background Jobs Monitor**: פיצ'ר ה-Background Jobs Monitor מספק נראות (Observability) מלאה לכל ה-Jobs הרצים ברקע במערכת, כולל פעולות משתמש דינמיות (Drive, Reminders, Batch Operations). +- `docs/observability/observability_dashboard.md` — **📡 Observability Dashboard & API**: מסך ה-Admin ב-/admin/observability מרכז נתוני ניטור בזמן אמת ל-SRE ולמפתחים: כרטיסי מצב וגרפים, טבלת התראות עם סינון, ו-API מתועד למסלולי alerts, timeseries, aggregations, export, replay, runbook, quickfix ו-ai_explain. +- `docs/observability/query-performance-profiler.rst` — **Query Performance Profiler**: כלי ניטור לשאילתות MongoDB איטיות: דשבורד ב-WebApp שמציג את השאילתות הכבדות, ה-API שמאחוריו, ומה הכלי במפורש אינו עושה. +- `docs/observability/quick_fix_rules.md` — **🧠 Quick Fix חכם (Queue Delay + עומס/DB) – הנחיות למפתחים ולסוכני AI**: המטרה של Quick Fix היא לתת המלצה קצרה, בטוחה ושימושית על “מה לעשות עכשיו”, לפי אותות שאנחנו כבר מודדים. +- `docs/observability/asyncio-loop-safety.rst` — **Asyncio תחת WSGI: הרצת קורוטינות בבטחה**: ב-WebApp שמורץ תחת WSGI (Flask + Gunicorn/gevent), עלולה להיות לולאת Event פעילה כבר בתוך ה-thread של הבקשה. במצב כזה קריאה ל-asyncio.run תזרוק חריגה ותפיל את הבקשה, ולעתים תשאיר קורוטינה "תלויה" ללא await. +- `docs/visual-rule-engine.rst` — **Visual Rule Engine - מנוע כללים ויזואלי**: מנוע כללים ויזואלי ליצירת התראות מורכבות מהממשק בלי לכתוב קוד: זרימת ההחלטה, מסך הכללים, יצירה והפעלה, וסכמת ה-JSON של כלל. +- `docs/observability/coverage_report.rst` — **Coverage Report (Runbooks / Quick Fixes)**: עמוד ה-Coverage נועד להיות Gap Analysis קבוע: To‑Do List לצוות שמראה אילו alert_type נצפו במערכת ועדיין חסר להם Runbook/Quick Fix, ואילו הגדרות בקונפיג הפכו ליתומות. +- `docs/api/ai_explain.md` — **🧠 Observability AI Explain API**: שירות ה-AI שמתרגם הקשר של התראה להסבר קצר בשפה טבעית: הבקשה והתגובה של POST /api/ai/explain, האימות והבקרות, וקודי השגיאה. +- `docs/rate-limiting.rst` — **Rate Limiting**: מערכת הגבלת קצב אחודה לבוט ולווב, עם Shadow Mode, Soft‑Warning ב‑80% ועקיפת מנהלים. +- `docs/observability/guidelines.md` — **📊 הנחיות Observability ואירועים**: מטרה: לקבוע תבנית ברורה ללוגים ולאירועים, להפחית רעש, ולאפשר תחקור מהיר בעזרת request_id. +- `docs/logging_schema.rst` — **סכמת לוגים**: סכמת הלוגים: שדות החובה והשדות המומלצים בכל רשומה, דוגמה מלאה, וטקסונומיית קודי השגיאה. +- `docs/metrics.rst` — **מדדים (Metrics)**: המדדים שהמערכת חושפת ב-/metrics: המטריקות הקיימות, מדדי ה-handlers והפקודות, מטריקות OpenTelemetry, ודוגמאות PromQL ו-SLO. +- `docs/resilience.rst` — **Resilience לשירותים חיצוניים**: שכבת Retry ו-Circuit Breaker לקריאות חוץ. היא חלה על קריאות שעוברות דרך http_sync.py ו-http_async.py; שירותים שקוראים ישירות ל-requests, httpx או aiohttp אינם מכוסים עדיין. +- `docs/alerts.rst` — **התראות (Alerts)**: מערכת ההתראות: חוקי ברירת המחדל, איך מתאימים אותם, מדדי Health ו-Startup ל-Prometheus, קונפיגורציית alert_manager, ובדיקת הזרימה מקצה לקצה. +- `docs/observability/log_based_alerts.rst` — **התראות מבוססות לוגים (Log‑based Alerts)**: התראות שנגזרות מזרם הלוגים של האפליקציה: סיווג שגיאות לפי חתימות, Allowlist, קיבוץ אירועים ו-Cooldown, עם קבצי הקונפיג ומשתני הסביבה שמפעילים אותן. +- `docs/observability/log-aggregator.rst` — **מנוע ניתוח לוגים (Log Event Aggregator)**: הארכיטקטורה, קבצי הקונפיג, הרצה מקומית ב-CLI, השילוב במערכת, וניפוי התקלות הנפוצות. +- `docs/sentry.rst` — **Sentry**: ברירת מחדל: Sentry מציג Issues בממשק ושולח מיילים, אבל לא מזרים את זה אוטומטית למערכת ההתראות הפנימית שלנו (Telegram + Observability). +- `docs/runbooks/incident-checklist.rst` — **Incident Checklist (On‑Call)**: צ'קליסט לתורן בעת פתיחת Incident, וסטטוסי המעקב האחידים שבהם מדווחים עליו. +- `docs/runbooks/logging-levels.rst` — **שינוי רמות לוגים**: איך משנים רמות לוג בזמן ריצה, ומתי כדאי להעלות ל-DEBUG. +- `docs/runbooks/github_backup_restore.rst` — **GitHub Backup & Restore Runbook**: מדריך צעד‑אחר‑צעד לגיבוי ושחזור מאגר GitHub, כולל יצירת נקודת בדיקה (Checkpoint Tag) ושחזור בטוח. +- `docs/runbooks/slo.md` — **Runbooks – SLO Incidents**: ראנבוקים לתקלות SLO: HighErrorRate, חריגת זמינות מתחת ל-99.9%, וחריגת P95 מעל חצי שנייה — עם שאילתות ה-PromQL של כל אחת. + +## פריסה ו-Workers + +- `docs/deployment/workers.rst` — **עובדי Push**: מסלולי ה-Web Push של הבוט — המסלול המקומי ב-pywebpush ועובד ה-Node — החיבור ל-WebApp דרך push_api.py, ובדיקות. + +## ChatOps + +- `docs/chatops/overview.md` — **ChatOps – סקירה כללית**: העקרונות שמאחורי ChatOps — פלט הבוט כמקור אמת, פקודה אחת לכל החלטה, ואיסור על סודות בפלטים — עם קישורים לעמודי Monitoring, Observability, Git LFS ו-Backup/Restore. +- `docs/chatops/commands.md` — **פקודות ChatOps**: להלן מבנה אחיד לכל פקודה: מתי להשתמש, פרמטרים, הרשאות, מה לחפש בפלט, ודוגמה קצרה אם יש ערך מוסף. +- `docs/chatops/observe.md` — **ChatOps – /observe: הרחבות -v ו- -vv**: מסמך זה מפרט את מצב ההרחבה של הפקודה `/observe` לצורכי תחקור ומהירות תגובה בזמן אמת. +- `docs/chatops/ratelimit.rst` — **הגבלת קצב לפקודות רגישות**: העקרונות מאחורי הגבלת הקצב לפקודות רגישות, הדקורטור שמפעיל אותה, הקונפיגורציה, והשילוב בבוט. +- `docs/chatops/playbooks.md` — **Playbooks – תרחישים נפוצים**: פלייבוקים לתרחישים נפוצים: עלייה ב-p95, שיעור שגיאות מעל אחוז, זיכרון שמטפס, שירות חיצוני איטי, ותקלה חוזרת בתוך רבע שעה. +- `docs/chatops/permissions.md` — **הרשאות ו-Rate Limit**: מי מורשה להריץ אילו פקודות ChatOps, ומהן מגבלות הקצב עליהן. +- `docs/chatops/troubleshooting.md` — **פתרון תקלות (FAQ)**: שאלות נפוצות ופתרון תקלות בהפעלת פקודות ChatOps. +- `docs/chatops/faq.md` — **שאלות נפוצות**: איך נמנעים מדליפת סודות? + +## סוכני AI + +- `docs/ai-agents/guide.md` — **🤖 מדריך לסוכני AI**: מטרה: לקצר זמן חיבור של סוכנים לפרויקט, לשמור על איכות ועמידה במדיניות. + +## Observability – Advanced + +- `docs/observability/events_catalog.rst` — **קטלוג אירועים קנוניים**: הקטלוג הקנוני של שמות האירועים — GitHub, שיתוף ווב, התראות, Repo Analyzer ואירועי ביזנס — עם הכלל לשמות ב-snake_case ובלי PII. +- `docs/observability/error_codes.rst` — **מילון קודי שגיאה (Error Codes)**: הקודים הקנוניים, דוגמאות מיפוי מחריגה לקוד, והנחיות לשימוש בהם. +- `docs/observability/tracing_hotspots.rst` — **Tracing ממוקד בנקודות חמות**: מדריך קצר להתמקדות ב‑Tracing בנקודות בעלות השפעה גבוהה (Hotspots) בבוט וב‑WebApp. +- `docs/observability/metrics_promql.rst` — **שאילתות PromQL שימושיות**: שאילתות מוכנות לזמן תגובה, לשיעור שגיאות ולאירועי ביזנס. +- `docs/observability/alerts_playbook.rst` — **Playbook קצר להתראות**: הזרימה מזיהוי האירוע ועד שליחת ההתראה, הקישורים בקוד, וכיוונון רעש. + +--- + +עמודי פיגום autodoc שסוננו: 92. עמודים שנסרקו: 228. diff --git a/backup_menu_handler.py b/backup_menu_handler.py index 6fe7ac87e..d2d3145aa 100644 --- a/backup_menu_handler.py +++ b/backup_menu_handler.py @@ -270,6 +270,7 @@ async def show_backup_menu(self, update: Update, context: ContextTypes.DEFAULT_T pass await message("בחר פעולה מתפריט הגיבוי/שחזור:", reply_markup=reply_markup) + # docs:backup-callback-dispatch:start — הקטע מוטמע בתיעוד (docs/conversation-handlers.rst); אל תסיר את הסימון async def handle_callback_query(self, update: Update, context: ContextTypes.DEFAULT_TYPE): query = update.callback_query user_id = query.from_user.id @@ -301,6 +302,7 @@ async def handle_callback_query(self, update: Update, context: ContextTypes.DEFA elif data.startswith("backup_details:"): backup_id = data.split(":", 1)[1] await self._show_backup_details(update, context, backup_id) + # docs:backup-callback-dispatch:end elif data.startswith("backup_rate_menu:"): # פתיחת מסך תיוג עם 3 כפתורים (🏆 / 👍 / 🤷) backup_id = data.split(":", 1)[1] diff --git a/docs/ARCHITECTURE_LAYER_RULES.md b/docs/ARCHITECTURE_LAYER_RULES.md index 2460eab87..77a66c9fd 100644 --- a/docs/ARCHITECTURE_LAYER_RULES.md +++ b/docs/ARCHITECTURE_LAYER_RULES.md @@ -1,6 +1,8 @@ -# כללי שכבות – CodeBot +--- +summary: 'מטרה: לשמור גבולות שכבות ברורים ולמנוע תלות מעגלית/דליפת תשתית.' +--- -מטרה: לשמור גבולות שכבות ברורים ולמנוע תלות מעגלית/דליפת תשתית. +# כללי שכבות – CodeBot ## שכבות - **domain**: ישויות, שירותים טהורים (ללא IO). אין תלות ב־handlers/infra/services/database. diff --git a/docs/BOT_TEST_PLAN_CONTAINER.md b/docs/BOT_TEST_PLAN_CONTAINER.md index 635c312b2..7b6d9b49b 100644 --- a/docs/BOT_TEST_PLAN_CONTAINER.md +++ b/docs/BOT_TEST_PLAN_CONTAINER.md @@ -1,6 +1,8 @@ -# תכנית בדיקות לבוט – Composition Root (Container) לשירות Snippet +--- +summary: 'מסמך זה מתאר בדיקות ידניות מהירות לבוט לאחר העברת יצירת התלויות ל־Container דומייני/אפליקטיבי. המטרה: לוודא שה־handlers צורכים את השירות מאותה נקודת אמת, בלי לשנות לוגיקה.' +--- -מסמך זה מתאר בדיקות ידניות מהירות לבוט לאחר העברת יצירת התלויות ל־Container דומייני/אפליקטיבי. המטרה: לוודא שה־handlers צורכים את השירות מאותה נקודת אמת, בלי לשנות לוגיקה. +# תכנית בדיקות לבוט – Composition Root (Container) לשירות Snippet ## איך לבדוק - **מטרה**: שמירה עובדת, השפה מזוהה נכון, ותצוגה/עריכה ממשיכות כרגיל. diff --git a/docs/DEV_WEB_PUSH.md b/docs/DEV_WEB_PUSH.md index efe258380..3d1c4abc1 100644 --- a/docs/DEV_WEB_PUSH.md +++ b/docs/DEV_WEB_PUSH.md @@ -1,6 +1,8 @@ -# Web Push – Sticky Notes Reminders +--- +summary: מסמך זה מסביר כיצד להפעיל ולבדוק התראות Web Push עבור תזכורות של Sticky Notes. +--- -מסמך זה מסביר כיצד להפעיל ולבדוק התראות Web Push עבור תזכורות של Sticky Notes. +# Web Push – Sticky Notes Reminders קישור למסמך המקורי עם דוגמאות והסברים מפורטים: - https://code-keeper-webapp.onrender.com/share/k8yuEWIeQ1ZqdlGP diff --git a/docs/agents/rate-limiting.md b/docs/agents/rate-limiting.md index f90c8021b..d5f722be1 100644 --- a/docs/agents/rate-limiting.md +++ b/docs/agents/rate-limiting.md @@ -1,8 +1,8 @@ -# 🚦 מערכת Rate Limiting לסוכני AI ולווב - -מטרה: להסביר איך מפעילים ומנטרים Rate Limiting בבוט ובווב, עם דגש על Shadow Mode, ניטור וקונפיג. - --- +summary: 'מטרה: להסביר איך מפעילים ומנטרים Rate Limiting בבוט ובווב, עם דגש על Shadow Mode, ניטור וקונפיג.' +--- + +# 🚦 מערכת Rate Limiting לסוכני AI ולווב ## אסטרטגיה – Shadow Mode תחילה - הפעילו תחילה ב־Shadow Mode: סופרים פגיעות בלימיט אך לא חוסמים. diff --git a/docs/ai-agents/guide.md b/docs/ai-agents/guide.md index 832c00993..cf1c8e534 100644 --- a/docs/ai-agents/guide.md +++ b/docs/ai-agents/guide.md @@ -1,8 +1,8 @@ -# 🤖 מדריך לסוכני AI - -מטרה: לקצר זמן חיבור של סוכנים לפרויקט, לשמור על איכות ועמידה במדיניות. - --- +summary: 'מטרה: לקצר זמן חיבור של סוכנים לפרויקט, לשמור על איכות ועמידה במדיניות.' +--- + +# 🤖 מדריך לסוכני AI ## נקודת פתיחה מהירה - קראו את הקובץ `.cursorrules` – הוא מגדיר כללי עבודה, פורמט תשובות וחוקי בטיחות. diff --git a/docs/ai-guidelines.rst b/docs/ai-guidelines.rst index 33c37f439..cd91c73b9 100644 --- a/docs/ai-guidelines.rst +++ b/docs/ai-guidelines.rst @@ -1,5 +1,6 @@ הנחיות מלאות לסוכני AI ======================== +:summary: ההנחיות המלאות לסוכני AI שעובדים בריפו: המגבלות הקריטיות, איך מריצים פקודות, אילו כלי קבצים מאושרים, עקרונות עריכת קוד, ומדיניות הקומיטים וה-Pull Requests. מגבלות קריטיות -------------- diff --git a/docs/alerts.rst b/docs/alerts.rst index d54af2931..eb15d7a0c 100644 --- a/docs/alerts.rst +++ b/docs/alerts.rst @@ -1,5 +1,6 @@ התראות (Alerts) ================ +:summary: מערכת ההתראות: חוקי ברירת המחדל, איך מתאימים אותם, מדדי Health ו-Startup ל-Prometheus, קונפיגורציית alert_manager, ובדיקת הזרימה מקצה לקצה. סקירה מהירה ----------- diff --git a/docs/api/ai_explain.md b/docs/api/ai_explain.md index 14570e277..79664ed38 100644 --- a/docs/api/ai_explain.md +++ b/docs/api/ai_explain.md @@ -1,3 +1,7 @@ +--- +summary: 'שירות ה-AI שמתרגם הקשר של התראה להסבר קצר בשפה טבעית: הבקשה והתגובה של POST /api/ai/explain, האימות והבקרות, וקודי השגיאה.' +--- + # 🧠 Observability AI Explain API שירות זה מספק שכבת AI רשמית שמתרגמת הקשרי התראות (Context) להסבר קצר בשפה טבעית, כולל שורש הבעיה, פעולות מומלצות ואותות תומכים. השירות נפרס כחלק מה־`webserver` (AioHTTP) תחת הנתיב `POST /api/ai/explain` ומשמש את לוח ה-Observability דרך המשתנה `OBS_AI_EXPLAIN_URL`. diff --git a/docs/api/handlers.documents.rst b/docs/api/handlers.documents.rst index 4ff126093..515a795f6 100644 --- a/docs/api/handlers.documents.rst +++ b/docs/api/handlers.documents.rst @@ -1,5 +1,6 @@ handlers.documents module ========================= +:summary: מנתב קבצים שנשלחים לבוט לפי ``upload_mode``: שחזור ZIP לריפו GitHub, ייבוא ZIP, וקבצי טקסט שנשמרים דרך שכבת הקבצים. כולל ולידציה והגנות מפני 'פצצת ZIP'. תיאור כללי ----------- diff --git a/docs/api/index.rst b/docs/api/index.rst index 5dff06a0b..87da0960e 100644 --- a/docs/api/index.rst +++ b/docs/api/index.rst @@ -1,7 +1,6 @@ API Reference ============= - -תיעוד מלא של ה-API של Code Keeper Bot. +:summary: תיעוד מלא של ה-API של Code Keeper Bot. .. toctree:: :maxdepth: 2 diff --git a/docs/api/modules.rst b/docs/api/modules.rst index 3195f9637..a8b6f8013 100644 --- a/docs/api/modules.rst +++ b/docs/api/modules.rst @@ -1,5 +1,6 @@ workspace ========= +:summary: אינדקס המודולים של התיעוד האוטומטי — נקודת הכניסה לעמודי ה-API שנוצרים מ-autodoc בזמן הבנייה. .. toctree:: :maxdepth: 4 diff --git a/docs/api/refactoring_engine.rst b/docs/api/refactoring_engine.rst index 9df1946b5..7040d802d 100644 --- a/docs/api/refactoring_engine.rst +++ b/docs/api/refactoring_engine.rst @@ -1,5 +1,6 @@ refactoring\_engine module ========================== +:summary: מנוע הרפקטורינג: המדיניות והקונפיגורציה, קיבוץ לפי קוהזיה שמונע Oversplitting ו-God Class, והמקרה המיוחד של פירוק בטוח ל-models.py. מדיניות וקונפיגורציה --------------------- diff --git a/docs/architecture.rst b/docs/architecture.rst index 800cf4f1b..288a638e8 100644 --- a/docs/architecture.rst +++ b/docs/architecture.rst @@ -1,11 +1,6 @@ ארכיטקטורה =========== - -סקירה כללית ------------- - -המערכת מורכבת מבוט Telegram, שכבת שירותים (services), שכבת נתונים (MongoDB) ואפליקציית Web. -הזרימה העיקרית: Handlers → Services → Database. +:summary: המערכת מורכבת מבוט Telegram, שכבת שירותים (services), שכבת נתונים (MongoDB) ואפליקציית Web. הזרימה העיקרית: Handlers → Services → Database. תרשים רכיבים (תמציתי) ---------------------- diff --git a/docs/architecture/clean-architecture.rst b/docs/architecture/clean-architecture.rst index ba660316b..448056134 100644 --- a/docs/architecture/clean-architecture.rst +++ b/docs/architecture/clean-architecture.rst @@ -1,9 +1,6 @@ Clean Architecture ב-src ======================== - -למה Clean Architecture ----------------------- -ארכיטקטורה זו מפרידה בין לוגיקה עסקית, תזמור יישומי ותשתיות כך שניתן לבדוק יחידות קוד בנפרד, להחליף מקורות נתונים בלי לשבור את שאר המערכת ולרוץ גם בסביבות ללא MongoDB. +:summary: ארכיטקטורה זו מפרידה בין לוגיקה עסקית, תזמור יישומי ותשתיות כך שניתן לבדוק יחידות קוד בנפרד, להחליף מקורות נתונים בלי לשבור את שאר המערכת ולרוץ גם בסביבות ללא MongoDB. תרשים שכבות ------------ diff --git a/docs/branch-protection-and-pr-rules.rst b/docs/branch-protection-and-pr-rules.rst index c91810cfb..09f3ef922 100644 --- a/docs/branch-protection-and-pr-rules.rst +++ b/docs/branch-protection-and-pr-rules.rst @@ -1,9 +1,6 @@ Branch Protection & PR Rules ============================ - -מטרה ------ -לרכז נהלים ברורים להגנה על ענפים (Branch Protection) ולחוקי PR בפרויקט. +:summary: לרכז נהלים ברורים להגנה על ענפים (Branch Protection) ולחוקי PR בפרויקט. כללי ענפים ----------- diff --git a/docs/chatops/commands.md b/docs/chatops/commands.md index ff47e7cf9..dc212f1e0 100644 --- a/docs/chatops/commands.md +++ b/docs/chatops/commands.md @@ -1,6 +1,8 @@ -# פקודות ChatOps +--- +summary: 'להלן מבנה אחיד לכל פקודה: מתי להשתמש, פרמטרים, הרשאות, מה לחפש בפלט, ודוגמה קצרה אם יש ערך מוסף.' +--- -להלן מבנה אחיד לכל פקודה: מתי להשתמש, פרמטרים, הרשאות, מה לחפש בפלט, ודוגמה קצרה אם יש ערך מוסף. +# פקודות ChatOps ## כרטיסיות חיפוש (Ctrl/Cmd+K) - ניתן לפתוח את החיפוש הגלובלי (`Ctrl/Cmd+K`) ולמצוא כל פקודת ChatOps במהירות. הכרטיסים מוזנים מקובץ `webapp/static/data/commands.json` ולכן חובה לעדכן אותו בכל פעם שמוסיפים פקודה חדשה. diff --git a/docs/chatops/faq.md b/docs/chatops/faq.md index b03348310..348a5a257 100644 --- a/docs/chatops/faq.md +++ b/docs/chatops/faq.md @@ -1,3 +1,7 @@ +--- +summary: איך נמנעים מדליפת סודות? +--- + # שאלות נפוצות **למה ChatOps?** diff --git a/docs/chatops/observe.md b/docs/chatops/observe.md index 7c4c40c01..e91ab28e5 100644 --- a/docs/chatops/observe.md +++ b/docs/chatops/observe.md @@ -1,6 +1,8 @@ -# ChatOps – /observe: הרחבות -v ו- -vv +--- +summary: מסמך זה מפרט את מצב ההרחבה של הפקודה `/observe` לצורכי תחקור ומהירות תגובה בזמן אמת. +--- -מסמך זה מפרט את מצב ההרחבה של הפקודה `/observe` לצורכי תחקור ומהירות תגובה בזמן אמת. +# ChatOps – /observe: הרחבות -v ו- -vv - **מתי להשתמש**: כשצריך תמונת Observability עמוקה (ברמת מערכת) בזמן אמת, כולל הצלבת מקורות נתונים וזיהוי מגמות/חריגות. - **הרשאות**: מנהלים בלבד. diff --git a/docs/chatops/overview.md b/docs/chatops/overview.md index 72e07e6d6..b52700acc 100644 --- a/docs/chatops/overview.md +++ b/docs/chatops/overview.md @@ -1,3 +1,7 @@ +--- +summary: העקרונות שמאחורי ChatOps — פלט הבוט כמקור אמת, פקודה אחת לכל החלטה, ואיסור על סודות בפלטים — עם קישורים לעמודי Monitoring, Observability, Git LFS ו-Backup/Restore. +--- + # ChatOps – סקירה כללית - מקור אמת בזמן אמת: נתונים מהבוט קודמים להשערות מבוססות קוד. diff --git a/docs/chatops/permissions.md b/docs/chatops/permissions.md index 7d4f9b3bc..cdece8691 100644 --- a/docs/chatops/permissions.md +++ b/docs/chatops/permissions.md @@ -1,3 +1,7 @@ +--- +summary: מי מורשה להריץ אילו פקודות ChatOps, ומהן מגבלות הקצב עליהן. +--- + # הרשאות ו-Rate Limit - פקודות רגישות (מנהלים בלבד): `/errors`, `/triage`, `/rate_limit`, `/enable_backoff`, `/disable_backoff`, `/ban`, `/unban`, `/blocked`. diff --git a/docs/chatops/playbooks.md b/docs/chatops/playbooks.md index db69ea61a..4e8f7617d 100644 --- a/docs/chatops/playbooks.md +++ b/docs/chatops/playbooks.md @@ -1,3 +1,7 @@ +--- +summary: 'פלייבוקים לתרחישים נפוצים: עלייה ב-p95, שיעור שגיאות מעל אחוז, זיכרון שמטפס, שירות חיצוני איטי, ותקלה חוזרת בתוך רבע שעה.' +--- + # Playbooks – תרחישים נפוצים ## p95 Latency עלה מעל הסף diff --git a/docs/chatops/ratelimit.rst b/docs/chatops/ratelimit.rst index 1cd9d74bc..72614c7dc 100644 --- a/docs/chatops/ratelimit.rst +++ b/docs/chatops/ratelimit.rst @@ -1,5 +1,6 @@ הגבלת קצב לפקודות רגישות ========================= +:summary: העקרונות מאחורי הגבלת הקצב לפקודות רגישות, הדקורטור שמפעיל אותה, הקונפיגורציה, והשילוב בבוט. ``chatops.ratelimit`` מרכז את שכבת ההגנה הקלה נגד ספאם לפקודות רגישות במערכת ה-ChatOps (למשל `/deploy`, `/restart`, `/secrets`). במקום diff --git a/docs/chatops/troubleshooting.md b/docs/chatops/troubleshooting.md index 97835da95..252bd44e4 100644 --- a/docs/chatops/troubleshooting.md +++ b/docs/chatops/troubleshooting.md @@ -1,3 +1,7 @@ +--- +summary: שאלות נפוצות ופתרון תקלות בהפעלת פקודות ChatOps. +--- + # פתרון תקלות (FAQ) - אין פלט מהבוט: ודאו הרשאות וצ'אט מותר. diff --git a/docs/ci-cd.rst b/docs/ci-cd.rst index 7e9b1ab72..f67619e3f 100644 --- a/docs/ci-cd.rst +++ b/docs/ci-cd.rst @@ -1,5 +1,6 @@ CI/CD Guide =========== +:summary: מדריך ה-CI/CD: החוקים הקשיחים, הסטטוסים הנדרשים ב-PR, ריכוז ה-workflows, הבדיקות המומלצות ובניית התיעוד. חוקים קשיחים ------------- diff --git a/docs/configuration.rst b/docs/configuration.rst index eb6a24a99..a74b6f882 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -1,5 +1,6 @@ Rate Limiting ============= +:summary: רפרנס הקונפיגורציה של המערכת: Rate Limiting, משתני סביבה, Pooling ו-Timeouts למסדי הנתונים ול-Redis, לקוחות ה-HTTP הסינכרוני והאסינכרוני, Flask, הבוט והמדדים. Environment variables --------------------- diff --git a/docs/contributing.rst b/docs/contributing.rst index 54f496e4e..c48a30824 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -1,9 +1,6 @@ מדריך תרומה ============ - -מטרה ------ -לתת מסלול ברור לתרומות קוד, עם דגש על סוכני AI ו-CI. +:summary: לתת מסלול ברור לתרומות קוד, עם דגש על סוכני AI ו-CI. כללים כלליים ------------- diff --git a/docs/conversation-handlers.rst b/docs/conversation-handlers.rst index 715cd4e99..1edcf984f 100644 --- a/docs/conversation-handlers.rst +++ b/docs/conversation-handlers.rst @@ -1,9 +1,6 @@ Conversation Handlers & States ============================== - -סקירה ------ -מסמך זה מרכז את הזרימות העיקריות של ה‑ConversationHandlers וה‑states. +:summary: מסמך זה מרכז את הזרימות העיקריות של ה‑ConversationHandlers וה‑states. רשימת States (מבחר בפועל) -------------------------- @@ -161,27 +158,27 @@ Save – שלבים עיקריים .. literalinclude:: ../handlers/save_flow.py :language: python - :lines: 123-137 + :pyobject: start_save_flow :caption: handlers/save_flow.py – start_save_flow .. literalinclude:: ../handlers/save_flow.py :language: python - :lines: 279-304 + :pyobject: get_code :caption: handlers/save_flow.py – get_code .. literalinclude:: ../handlers/save_flow.py :language: python - :lines: 307-338 + :pyobject: get_filename :caption: handlers/save_flow.py – get_filename .. literalinclude:: ../handlers/save_flow.py :language: python - :lines: 341-349 + :pyobject: get_note :caption: handlers/save_flow.py – get_note .. literalinclude:: ../handlers/save_flow.py :language: python - :lines: 352-401 + :pyobject: save_file_final :caption: handlers/save_flow.py – save_file_final GitHub – תפריט ושיחת העלאה @@ -194,20 +191,22 @@ GitHub – תפריט ושיחת העלאה .. literalinclude:: ../main.py :language: python - :lines: 739-759 - :caption: main.py – הגדרת upload_conv_handler (FILE_UPLOAD/REPO_SELECT/FOLDER_SELECT) + :start-after: docs:upload-conv:start + :end-before: docs:upload-conv:end + :caption: main.py – הגדרת upload_conv_handler Backup – תפריט ~~~~~~~~~~~~~~~ .. literalinclude:: ../backup_menu_handler.py :language: python - :lines: 146-160 + :pyobject: BackupMenuHandler.show_backup_menu :caption: backup_menu_handler.py – show_backup_menu .. literalinclude:: ../backup_menu_handler.py :language: python - :lines: 162-210 + :start-after: docs:backup-callback-dispatch:start + :end-before: docs:backup-callback-dispatch:end :caption: backup_menu_handler.py – handle_callback_query (קטע ראשון) Drive – תפריט @@ -215,12 +214,13 @@ Drive – תפריט .. literalinclude:: ../handlers/drive/menu.py :language: python - :lines: 142-187 + :pyobject: GoogleDriveMenuHandler.menu :caption: handlers/drive/menu.py – GoogleDriveMenuHandler.menu .. literalinclude:: ../handlers/drive/menu.py :language: python - :lines: 188-210 + :start-after: docs:drive-callback-open:start + :end-before: docs:drive-callback-open:end :caption: handlers/drive/menu.py – GoogleDriveMenuHandler.handle_callback (קטע ראשון) מוקשים נפוצים ופתרונות diff --git a/docs/database-schema.rst b/docs/database-schema.rst index 85cc2006e..6773134a4 100644 --- a/docs/database-schema.rst +++ b/docs/database-schema.rst @@ -1,5 +1,6 @@ Database Schema =============== +:summary: סכמת מסד הנתונים: האוספים code_snippets, users, bookmarks ו-sessions, השדות בכל אחד, והאינדקסים. Collections ----------- diff --git a/docs/database/bookmarks-manager.rst b/docs/database/bookmarks-manager.rst index 4611315ec..76d108f5d 100644 --- a/docs/database/bookmarks-manager.rst +++ b/docs/database/bookmarks-manager.rst @@ -1,5 +1,6 @@ מנהל סימניות – BookmarksManager =============================== +:summary: database.bookmarks_manager.BookmarksManager הוא שכבת ה-DB הראשית שמאחורי פיצ'ר הסימניות. הוא דואג לולידציה, לאכיפת מגבלות, ליצירת אינדקסים ולסנכרון הסימניות מול שינויים בקבצי הקוד. ``database.bookmarks_manager.BookmarksManager`` הוא שכבת ה-DB הראשית שמאחורי פיצ'ר הסימניות. הוא דואג לולידציה, לאכיפת מגבלות, ליצירת diff --git a/docs/database/collections-manager.rst b/docs/database/collections-manager.rst index d1d55753e..e06e37e4a 100644 --- a/docs/database/collections-manager.rst +++ b/docs/database/collections-manager.rst @@ -1,5 +1,6 @@ מנהל אוספים – CollectionsManager ================================ +:summary: פיצ'ר "הקולקציות שלי" נשען על database.collections_manager.CollectionsManager – שכבת שירות שמספקת CRUD מלא, חוקים חכמים, שיתוף ציבורי, ניהול פריטים ופעילות שיתופים. העמוד מסכם את המבנה כדי שיהיה קל לחבר פיצ'רים חדשים. פיצ'ר "הקולקציות שלי" נשען על ``database.collections_manager.CollectionsManager`` – שכבת שירות שמספקת CRUD מלא, חוקים חכמים, שיתוף ציבורי, ניהול פריטים diff --git a/docs/database/cursor-pagination.rst b/docs/database/cursor-pagination.rst index f05755034..48b15350d 100644 --- a/docs/database/cursor-pagination.rst +++ b/docs/database/cursor-pagination.rst @@ -2,6 +2,7 @@ Cursor-based Pagination (created_at / _id) ========================================== +:summary: דפדוף מבוסס קורסור על created_at ו-_id: עקרונות מיון יציב, קידוד ופענוח הקורסור, תבניות שאילתה לשני הכיוונים, ודוגמת PyMongo מלאה. למה? ----- diff --git a/docs/database/detailed-schema.rst b/docs/database/detailed-schema.rst index 60640f638..75f8fe98b 100644 --- a/docs/database/detailed-schema.rst +++ b/docs/database/detailed-schema.rst @@ -1,10 +1,6 @@ מבנה נתונים מפורט (Detailed Database Schema) ============================================== - -סקירה כללית ------------- - -מסמך זה מתאר בפירוט את כל האוספים, השדות, האילוצים והאינדקסים במסד הנתונים. +:summary: מסמך זה מתאר בפירוט את כל האוספים, השדות, האילוצים והאינדקסים במסד הנתונים. אוסף: code_snippets -------------------- diff --git a/docs/database/index.rst b/docs/database/index.rst index a0b3fff3d..a537caf2d 100644 --- a/docs/database/index.rst +++ b/docs/database/index.rst @@ -1,7 +1,6 @@ Database ======== - -תיעוד של מערכת מסד הנתונים והמודלים. +:summary: תיעוד של מערכת מסד הנתונים והמודלים. Database Manager ---------------- diff --git a/docs/database/indexing.rst b/docs/database/indexing.rst index 96bea845d..f83f575f7 100644 --- a/docs/database/indexing.rst +++ b/docs/database/indexing.rst @@ -2,6 +2,7 @@ MongoDB Indexing Cookbook ========================= +:summary: ספר מתכונים לאינדקסים ב-MongoDB: אילו אינדקסים מומלצים, מתכוני PyMongo, קריאת explain, ובדיקת קיום אינדקסים. למה? ----- diff --git a/docs/deployment/workers.rst b/docs/deployment/workers.rst index 08204c844..09c8e8f2c 100644 --- a/docs/deployment/workers.rst +++ b/docs/deployment/workers.rst @@ -1,5 +1,6 @@ עובדי Push =========== +:summary: מסלולי ה-Web Push של הבוט — המסלול המקומי ב-pywebpush ועובד ה-Node — החיבור ל-WebApp דרך push_api.py, ובדיקות. ל-Code Keeper Bot יש שני מסלולים לשליחת Web Push: diff --git a/docs/development.rst b/docs/development.rst index a0b14351b..f934a0791 100644 --- a/docs/development.rst +++ b/docs/development.rst @@ -1,5 +1,6 @@ Development Workflow ==================== +:summary: זרימת העבודה בפיתוח: הוספת handler חדש לבוט, הוספת endpoint ל-WebApp, ועדכון סכמה במסד הנתונים. הוספת Handler חדש ------------------ diff --git a/docs/development/i18n.rst b/docs/development/i18n.rst index 0e38de848..7cce47f08 100644 --- a/docs/development/i18n.rst +++ b/docs/development/i18n.rst @@ -1,5 +1,6 @@ בינאום ותמיכה בשפות ==================== +:summary: מודול i18n/ מספק שכבת תרגום פשוטה לבוט הטלגרם וה-WebApp. נכון לעכשיו קיימת חבילת מחרוזות בעברית (strings_he.py), אך המבנה מאפשר הוספת שפות חדשות ללא שינוי בלוגיקה העסקית. מודול ``i18n/`` מספק שכבת תרגום פשוטה לבוט הטלגרם וה-WebApp. נכון לעכשיו קיימת חבילת מחרוזות בעברית (``strings_he.py``), אך המבנה מאפשר הוספת שפות חדשות ללא שינוי בלוגיקה העסקית. diff --git a/docs/development/pre-commit.rst b/docs/development/pre-commit.rst index e624ecab3..376b50f01 100644 --- a/docs/development/pre-commit.rst +++ b/docs/development/pre-commit.rst @@ -1,9 +1,6 @@ Pre-commit Hooks ================ - -מטרה ------ -להבטיח איכות קוד עקבית לפני קומיט/PR. +:summary: להבטיח איכות קוד עקבית לפני קומיט/PR. התקנה והרצה ------------ diff --git a/docs/development/scripts.rst b/docs/development/scripts.rst index 14c39e7cc..f1617320d 100644 --- a/docs/development/scripts.rst +++ b/docs/development/scripts.rst @@ -1,5 +1,6 @@ סקריפטים שימושיים ================== +:summary: תיקיית scripts/ מכילה כלים חד-פעמיים ותהליכי תחזוקה. לפני ההרצה ודאו שסביבת ה-DB היא סביבת ניסוי/פיתוח ושיש גיבוי עדכני. תיקיית ``scripts/`` מכילה כלים חד-פעמיים ותהליכי תחזוקה. לפני ההרצה ודאו שסביבת ה-DB היא סביבת ניסוי/פיתוח ושיש גיבוי עדכני. diff --git a/docs/development/tools.rst b/docs/development/tools.rst index e30718a06..bcf90810a 100644 --- a/docs/development/tools.rst +++ b/docs/development/tools.rst @@ -1,5 +1,6 @@ כלי עזר למפתחים ================ +:summary: הכלים שתחת tools/: ניתוח שאילתות איטיות ואיתור קוד כפול, מתי להריץ כל אחד ומה לקרוא בפלט. עמוד זה מרכז שני כלים ייעודיים שנמצאים תחת ``tools/`` ונועדו לסייע באיתור צווארי בקבוק במאגר ובסדר הקוד. לפני השימוש ודאו שהקבצים אינם מתועדים במקום אחר כדי למנוע כפילות. diff --git a/docs/doc-authoring.rst b/docs/doc-authoring.rst index c150a9aed..b578b2f16 100644 --- a/docs/doc-authoring.rst +++ b/docs/doc-authoring.rst @@ -1,5 +1,6 @@ Doc Authoring Guide (Sphinx/RTD) ================================ +:summary: כללי כתיבת תיעוד בפרויקט — הצהרת תקציר בראש כל עמוד, הטמעת קוד לפי שם או סימון ולא לפי מספרי שורות, ובנייה ללא אזהרות. מטרות ------ @@ -12,6 +13,25 @@ Doc Authoring Guide (Sphinx/RTD) - ``autodoc_mock_imports``: רשימת מודולים כבדים/לא זמינים בזמן build. - אין להריץ קוד בזמן import ברמת מודול. +הצהרת תקציר בראש העמוד +----------------------- +- כל עמוד ידני **מצהיר** על תקציר בראשו. ``AI-MAP.md`` — מפת הניווט לסוכני AI — קורא את ההצהרה הזו ולא מנסה לנחש אותה מהגוף. +- ב-``.rst``: שדה ``:summary:`` מיד מתחת לקו הכותרת. ``docutils`` מקדם field list שבא ראשון אחרי כותרת המסמך ל-``docinfo``, והוא **מוצג בעמוד**. הגלוּת מכוונת: תקציר שרואים הוא תקציר שמתיישן בקול. +- ב-``.md``: מפתח ``summary`` ב-front matter, שנקרא ב-``yaml.safe_load`` בדיוק כמו ש-MyST קורא אותו. +- אין הצהרה ← המפה מציגה את הכותרת בלבד. ``python3 scripts/generate_ai_map.py --check`` מתריע על עמודים כאלה ואינו מפיל את הבנייה. +- משפט אחד או שניים, בגוף ההווה, שעונים על "מה יש בעמוד הזה". שורת המפה נחתכת ב-220 תווים; ההצהרה בעמוד נשארת מלאה. +- **אל תתחילו בשם העמוד.** שורת המפה היא ``נתיב — **כותרת**: תקציר``, כך שהכותרת כבר שם; תקציר שפותח בה מייצר כפילות מיידית (``Playbook קצר להתראות: פלייבוק קצר להתראות: ...``). התחילו בתוכן. +- **אל תכתבו בתקציר ספירה או הבטחת יכולת.** "שבעה מסלולי API", "28 אייקונים", "דוגמאות מוכנות להרצה", "תומך בחיפוש סמנטי" — כל אלה טענות שדורשות אימות מול הקוד, והן מתיישנות בלי שאיש ישים לב. שלושה סבבי ריוויו רצופים בפרויקט הזה נפלו בדיוק על זה: ספירה שהשתנתה, קוד עם ``...`` שהוצג כרץ, ו-``SearchType`` שקיים ב-enum ואינו ממומש. תארו **מה יש בעמוד**, לא כמה ולא מה עובד. ``tests/test_doc_summary_style.py`` אוכף את זה על ספירה במילים ועל ספירה בספרות שאחריה מילה עברית — והוא רשת לצורות הנפוצות, לא אישור שהתקציר נכון; מה שהוא במפורש אינו תופס מתועד ב-docstring שלו. +- **אל תשאירו כותרת יתומה.** אם ההצהרה מחליפה פסקת פתיחה והסעיף שהכיל אותה נשאר ריק — מחקו גם את הכותרת. סעיף ריק מרונדר בעמוד כשורה ללא גוף. +- **למה הצהרה ולא חילוץ אוטומטי:** הגרסה הקודמת חילצה את פסקת הפרוזה הראשונה, וכדי לעשות זאת מימשה חלקים מ-GFM ומ-RST ביד. ארבעה סבבי ריוויו רצופים מצאו שם מקרי קצה — כולל תקציר שיצא טבלה שלמה ותקציר שיצא ריק. מי שכתב את העמוד יודע מה התקציר. + +הטמעת קוד מהמקור (``literalinclude``) +-------------------------------------- +- **אסור** למען לפי מספרי שורות (``:lines:``) — הקוד זז והתיעוד ממשיך להציג את הטווח הישן בלי שום אזהרה. זה דפוס ``line-number-coupling`` (ראו amir-bug-patterns), והוא כבר קרה כאן: בלוק שהצביע על ``main.py:739`` הציג פנימיות של פונקציה אחרת, במרחק 2,900 שורות מהיעד. +- פונקציה או מחלקה שלמה ← ``:pyobject:``. הקוד נמשך לפי שם בכל בנייה, ושינוי שם מפיל את הבנייה ברעש. +- קטע בתוך פונקציה ← הערות סימון בקוד בפורמט ``# docs:<שם>:start`` / ``# docs:<שם>:end``, ומיעון ב-``:start-after:`` / ``:end-before:``. הערת ה-start חייבת לומר שהתיעוד תלוי בה ולאיזה דף — אחרת הריפקטור הבא ימחק אותה כהערה סתומה. +- marker חסר מפיל את הבנייה תחת ``-W`` (אזהרת docutils, שאינה מושתקת בקונפיגורציה) — נבדק. marker כפול מסוכן יותר: הבלוק ירונדר מהמופע הראשון בלי אזהרה, ולכן כל שם מופיע פעם אחת בדיוק. ``tests/test_docs_literalinclude_anchors.py`` אוכף את שני הכללים. + טיפים מהירים ------------ - בדקו לוקאלית עם ``make html SPHINXOPTS='-W --keep-going'``. diff --git a/docs/edge-cases.rst b/docs/edge-cases.rst index 4e0e81ae4..0665dd128 100644 --- a/docs/edge-cases.rst +++ b/docs/edge-cases.rst @@ -1,10 +1,6 @@ Edge Cases וטיפול בשגיאות =========================== - -סקירה כללית ------------- - -מסמך זה מתאר Edge Cases נפוצים במערכת וכיצד לטפל בהם. +:summary: מסמך זה מתאר Edge Cases נפוצים במערכת וכיצד לטפל בהם. קבצים גדולים ------------- diff --git a/docs/engines/overview.rst b/docs/engines/overview.rst index 499ad601d..84f4af2be 100644 --- a/docs/engines/overview.rst +++ b/docs/engines/overview.rst @@ -1,10 +1,6 @@ מנועי המערכת (System Engines) =============================== - -סקירה כללית ------------- - -מסמך זה מתאר את המנועים המרכזיים במערכת וכיצד הם עובדים. +:summary: מסמך זה מתאר את המנועים המרכזיים במערכת וכיצד הם עובדים. מנוע חיפוש (Search Engine) ---------------------------- diff --git a/docs/environment-variables.rst b/docs/environment-variables.rst index 62ecb6fe7..3800b30ab 100644 --- a/docs/environment-variables.rst +++ b/docs/environment-variables.rst @@ -1,5 +1,6 @@ משתני סביבה - רפרנס ===================== +:summary: רפרנס משתני הסביבה: הטבלה המרכזית, משתני התראות וניטור, מדדים ו-OTEL, תפעול ואינטגרציות, דגלי בדיקות, ודוגמאות קונפיגורציה כולל טבלת ה-Scopes של GitHub. .. note:: בכל פעם שמוסיפים או משנים משתני סביבה בקוד/Infra **חייבים** לעדכן עמוד זה (רפרנס משתני הסביבה) וכן לציין זאת ב-PR. בכך אנו מבטיחים שהמידע הופך ל-Single Source of Truth גם למפתחים וגם לאנשי DevOps. diff --git a/docs/examples.rst b/docs/examples.rst index 9f44ac8ca..49f321822 100644 --- a/docs/examples.rst +++ b/docs/examples.rst @@ -1,7 +1,6 @@ דוגמאות שימוש ============= - -דף זה מכיל דוגמאות קוד לשימוש ב-API של Code Keeper Bot. +:summary: דף זה מכיל דוגמאות קוד לשימוש ב-API של Code Keeper Bot. שימוש בסיסי ----------- diff --git a/docs/git-lfs.rst b/docs/git-lfs.rst index e10130620..cb5667a6a 100644 --- a/docs/git-lfs.rst +++ b/docs/git-lfs.rst @@ -1,9 +1,6 @@ Git LFS Integration =================== - -מטרה ------ -להסביר מתי ואיך להשתמש ב‑Git Large File Storage (LFS) עבור קבצים גדולים. +:summary: להסביר מתי ואיך להשתמש ב‑Git Large File Storage (LFS) עבור קבצים גדולים. מתי להשתמש ב‑LFS ------------------ diff --git a/docs/handlers/document-flow.rst b/docs/handlers/document-flow.rst index 659db3638..8d9a4ec04 100644 --- a/docs/handlers/document-flow.rst +++ b/docs/handlers/document-flow.rst @@ -1,5 +1,6 @@ זרימת הטיפול במסמכים (Document Flow) ===================================== +:summary: המפה בין הרכיבים שמטפלים בקובץ שנשלח לבוט, מצבי upload_mode, התלויות שמוזרקות ל-DocumentHandler, ושכבת האחסון (FilesFacade מול ה-DB הישן). מפה ותפקידים ------------- diff --git a/docs/handlers/drive_menu.rst b/docs/handlers/drive_menu.rst index 14677db5d..64cb7de45 100644 --- a/docs/handlers/drive_menu.rst +++ b/docs/handlers/drive_menu.rst @@ -1,9 +1,6 @@ Drive Menu V2 ============= - -סקירה ------ -תפריט הגיבוי ל‑Google Drive (גרסת V2) כולל בחירה מהירה (קבצי גיבוי/הכל/מתקדם), בחירת תיקיית יעד (אוטומטי/ברירת מחדל/מותאם), תזמון גיבוי, וטיפול שגיאות ברור. +:summary: תפריט הגיבוי ל‑Google Drive (גרסת V2) כולל בחירה מהירה (קבצי גיבוי/הכל/מתקדם), בחירת תיקיית יעד (אוטומטי/ברירת מחדל/מותאם), תזמון גיבוי, וטיפול שגיאות ברור. דגל פיצ'ר ---------- diff --git a/docs/handlers/index.rst b/docs/handlers/index.rst index b85b6cfce..404c937ab 100644 --- a/docs/handlers/index.rst +++ b/docs/handlers/index.rst @@ -1,7 +1,6 @@ Handlers ======== - -תיעוד של כל ה-handlers בפרויקט. +:summary: תיעוד של כל ה-handlers בפרויקט. זרימת פקודה בסיסית ------------------ diff --git a/docs/handlers/show.rst b/docs/handlers/show.rst index 1a9aa5642..3f200a0c1 100644 --- a/docs/handlers/show.rst +++ b/docs/handlers/show.rst @@ -1,5 +1,6 @@ Show Command ============ +:summary: מפרט פקודת /show: מבנה תגובת ה-HTML, שורות הכפתורים (מחיקה, עריכה, הערה, הורדה, שיתוף ומועדפים), והערות יישום. מפרט פקודת `/show` -------------------- diff --git a/docs/index.rst b/docs/index.rst index d09061a3b..0acd2ff0e 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -2,8 +2,7 @@ Code Keeper Bot - תיעוד API ============================ - -ברוכים הבאים לתיעוד ה-API של Code Keeper Bot! +:summary: ברוכים הבאים לתיעוד ה-API של Code Keeper Bot! בוט זה מספק ממשק טלגרם מתקדם לניהול ושמירת קטעי קוד, עם תמיכה בשפות תכנות מרובות, אינטגרציה עם GitHub, וכלי ניהול מתקדמים. diff --git a/docs/installation.rst b/docs/installation.rst index 74ad644d0..bb85e3064 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -1,7 +1,6 @@ התקנה והגדרה ============= - -דף זה מכיל הוראות התקנה מפורטות עבור Code Keeper Bot. +:summary: דף זה מכיל הוראות התקנה מפורטות עבור Code Keeper Bot. דרישות מערכת ------------- diff --git a/docs/integrations.rst b/docs/integrations.rst index 0e642b8ff..fce39bef6 100644 --- a/docs/integrations.rst +++ b/docs/integrations.rst @@ -1,5 +1,6 @@ Integrations ============ +:summary: להפעלת פעולות שונות מול GitHub נדרש להגדיר לטוקן \(`GITHUB_TOKEN` או טוקן משתמש שנשמר במערכת\) את מרחבי ההרשאות המינימליים. הקפידו על עיקרון ההרשאות המצומצמות. GitHub API ---------- diff --git a/docs/large-files-runbook.rst b/docs/large-files-runbook.rst index 5dcbfa9d2..7bed7d1d8 100644 --- a/docs/large-files-runbook.rst +++ b/docs/large-files-runbook.rst @@ -1,5 +1,6 @@ טיפול בקבצים גדולים (Large Files) ================================== +:summary: ראנבוק לטיפול בקבצים גדולים: המגבלות והפולבקים, הנחיות ההפעלה, ומה לנטר. מגבלות ופולבקים ---------------- diff --git a/docs/logging_schema.rst b/docs/logging_schema.rst index c8c2d4bfc..37348128e 100644 --- a/docs/logging_schema.rst +++ b/docs/logging_schema.rst @@ -1,5 +1,6 @@ סכמת לוגים ========== +:summary: סכמת הלוגים: שדות החובה והשדות המומלצים בכל רשומה, דוגמה מלאה, וטקסונומיית קודי השגיאה. שדות חובה --------- diff --git a/docs/markdown_style_guide.rst b/docs/markdown_style_guide.rst index 5e700ae39..67d7eca1d 100644 --- a/docs/markdown_style_guide.rst +++ b/docs/markdown_style_guide.rst @@ -1,5 +1,6 @@ מדריך סגנונות וארכיטקטורת Markdown ================================== +:summary: המסמך הזה הוא Source of Truth לעיצוב וארכיטקטורת Markdown בפרויקט. הוא מיועד למפתחים ול‑QA ויזואלי. המסמך הזה הוא **Source of Truth** לעיצוב וארכיטקטורת Markdown בפרויקט. הוא מיועד למפתחים ול‑QA ויזואלי. diff --git a/docs/mcp-server.rst b/docs/mcp-server.rst index f3f40463e..44e43dafe 100644 --- a/docs/mcp-server.rst +++ b/docs/mcp-server.rst @@ -1,5 +1,6 @@ שרת ה-MCP — חיבור Claude ל-CodeKeeper ====================================== +:summary: שרת ה-MCP שחושף את CodeKeeper ל-Claude: הכלים, האימות וההרשאות, פריימר הסוכן, עריכה מהדפדפן, והפעלה צעד אחר צעד מול Claude.ai ומול Claude Code. שרת `MCP `_ (Model Context Protocol) שחושף את CodeKeeper ל-Claude: הקבצים והאוספים האישיים של כל משתמש, ולאדמין — גם **דפדפן diff --git a/docs/metrics.rst b/docs/metrics.rst index 2c977d3c9..82ad2b4e2 100644 --- a/docs/metrics.rst +++ b/docs/metrics.rst @@ -1,5 +1,6 @@ מדדים (Metrics) ================ +:summary: המדדים שהמערכת חושפת ב-/metrics: המטריקות הקיימות, מדדי ה-handlers והפקודות, מטריקות OpenTelemetry, ודוגמאות PromQL ו-SLO. נקודת קצה --------- diff --git a/docs/modules/index.rst b/docs/modules/index.rst index 443bfabf5..11941deb9 100644 --- a/docs/modules/index.rst +++ b/docs/modules/index.rst @@ -1,7 +1,6 @@ מודולים ראשיים =============== - -תיעוד מפורט של המודולים הראשיים בפרויקט. +:summary: תיעוד מפורט של המודולים הראשיים בפרויקט. File Management --------------- diff --git a/docs/monitoring.md b/docs/monitoring.md index 7bf4d1f06..9e35d994f 100644 --- a/docs/monitoring.md +++ b/docs/monitoring.md @@ -1,3 +1,7 @@ +--- +summary: חיבור Grafana לטלגרם דרך Webhook, אנוטציות, ספים דינמיים, הפרדה בין שגיאות פנימיות לחיצוניות, ו-Predictive Health. +--- + # Smart Observability v7 – Predictive Health & Adaptive Feedback ## חיבור Grafana → Telegram (Webhook) diff --git a/docs/observability.rst b/docs/observability.rst index 2cba4f34b..c12bbd427 100644 --- a/docs/observability.rst +++ b/docs/observability.rst @@ -1,5 +1,6 @@ אובזרווביליות (Observability) ============================== +:summary: המטרות וקהלי היעד, התצורה, בחירת Backend ל-Traces, הגדרת OTLP לסביבות, ואינסטרומנטציה ידנית. מטרות ------ diff --git a/docs/observability/alerts_playbook.rst b/docs/observability/alerts_playbook.rst index 9a301b695..13830c91b 100644 --- a/docs/observability/alerts_playbook.rst +++ b/docs/observability/alerts_playbook.rst @@ -1,5 +1,6 @@ Playbook קצר להתראות ====================== +:summary: הזרימה מזיהוי האירוע ועד שליחת ההתראה, הקישורים בקוד, וכיוונון רעש. זרימה ----- diff --git a/docs/observability/asyncio-loop-safety.rst b/docs/observability/asyncio-loop-safety.rst index 2b55597f0..5428d5d0e 100644 --- a/docs/observability/asyncio-loop-safety.rst +++ b/docs/observability/asyncio-loop-safety.rst @@ -1,5 +1,6 @@ Asyncio תחת WSGI: הרצת קורוטינות בבטחה ====================================== +:summary: ב-WebApp שמורץ תחת WSGI (Flask + Gunicorn/gevent), עלולה להיות לולאת Event פעילה כבר בתוך ה-thread של הבקשה. במצב כזה קריאה ל-asyncio.run תזרוק חריגה ותפיל את הבקשה, ולעתים תשאיר קורוטינה "תלויה" ללא await. רקע קצר ------- diff --git a/docs/observability/background-jobs-monitor.rst b/docs/observability/background-jobs-monitor.rst index e89e534d8..42c12717d 100644 --- a/docs/observability/background-jobs-monitor.rst +++ b/docs/observability/background-jobs-monitor.rst @@ -1,12 +1,10 @@ Background Jobs Monitor ======================= +:summary: פיצ'ר ה-Background Jobs Monitor מספק נראות (Observability) מלאה לכל ה-Jobs הרצים ברקע במערכת, כולל פעולות משתמש דינמיות (Drive, Reminders, Batch Operations). סקירה כללית ----------- -פיצ'ר ה-Background Jobs Monitor מספק נראות (Observability) מלאה לכל ה-Jobs הרצים ברקע במערכת, -כולל פעולות משתמש דינמיות (Drive, Reminders, Batch Operations). - **מה הפיצ'ר נותן:** - רישום מרכזי של כל ה-Jobs במערכת (``JobRegistry``) diff --git a/docs/observability/coverage_report.rst b/docs/observability/coverage_report.rst index 52a6da07d..60ce10e82 100644 --- a/docs/observability/coverage_report.rst +++ b/docs/observability/coverage_report.rst @@ -1,5 +1,6 @@ Coverage Report (Runbooks / Quick Fixes) ======================================== +:summary: עמוד ה-Coverage נועד להיות Gap Analysis קבוע: To‑Do List לצוות שמראה אילו alert_type נצפו במערכת ועדיין חסר להם Runbook/Quick Fix, ואילו הגדרות בקונפיג הפכו ליתומות. מטרה ----- diff --git a/docs/observability/error_codes.rst b/docs/observability/error_codes.rst index 1b033fade..95bd6574a 100644 --- a/docs/observability/error_codes.rst +++ b/docs/observability/error_codes.rst @@ -1,5 +1,6 @@ מילון קודי שגיאה (Error Codes) =============================== +:summary: הקודים הקנוניים, דוגמאות מיפוי מחריגה לקוד, והנחיות לשימוש בהם. .. admonition:: DoD :class: important diff --git a/docs/observability/events_catalog.rst b/docs/observability/events_catalog.rst index e43ced20a..8d237f629 100644 --- a/docs/observability/events_catalog.rst +++ b/docs/observability/events_catalog.rst @@ -1,5 +1,6 @@ קטלוג אירועים קנוניים ====================== +:summary: הקטלוג הקנוני של שמות האירועים — GitHub, שיתוף ווב, התראות, Repo Analyzer ואירועי ביזנס — עם הכלל לשמות ב-snake_case ובלי PII. .. admonition:: עיקרון :class: tip diff --git a/docs/observability/guidelines.md b/docs/observability/guidelines.md index d6fbab82f..b6ce230be 100644 --- a/docs/observability/guidelines.md +++ b/docs/observability/guidelines.md @@ -1,8 +1,8 @@ -# 📊 הנחיות Observability ואירועים - -מטרה: לקבוע תבנית ברורה ללוגים ולאירועים, להפחית רעש, ולאפשר תחקור מהיר בעזרת request_id. - --- +summary: 'מטרה: לקבוע תבנית ברורה ללוגים ולאירועים, להפחית רעש, ולאפשר תחקור מהיר בעזרת request_id.' +--- + +# 📊 הנחיות Observability ואירועים ## תבנית אירוע/לוג – שדות חובה - request_id: מזהה מתואם לבקשה/פעולה diff --git a/docs/observability/log-aggregator.rst b/docs/observability/log-aggregator.rst index 28879fd47..0a7824f26 100644 --- a/docs/observability/log-aggregator.rst +++ b/docs/observability/log-aggregator.rst @@ -1,5 +1,6 @@ מנוע ניתוח לוגים (Log Event Aggregator) ======================================== +:summary: הארכיטקטורה, קבצי הקונפיג, הרצה מקומית ב-CLI, השילוב במערכת, וניפוי התקלות הנפוצות. ``monitoring/log_analyzer.py`` מרכז את כל האינטליגנציה שמטרתה להמיר זרם לוגים רועש להתראות פעולה. העמוד מפרט את רכיבי המערכת, הארכיטקטורה והקונפיגורציה שבין ``monitoring/log_analyzer.py``, ``monitoring/error_signatures.py`` ו-``scripts/run_log_aggregator.py``. diff --git a/docs/observability/log_based_alerts.rst b/docs/observability/log_based_alerts.rst index 201619df5..33b9c2d44 100644 --- a/docs/observability/log_based_alerts.rst +++ b/docs/observability/log_based_alerts.rst @@ -1,5 +1,6 @@ התראות מבוססות לוגים (Log‑based Alerts) ========================================= +:summary: התראות שנגזרות מזרם הלוגים של האפליקציה: סיווג שגיאות לפי חתימות, Allowlist, קיבוץ אירועים ו-Cooldown, עם קבצי הקונפיג ומשתני הסביבה שמפעילים אותן. מה זה ולמה ----------- diff --git a/docs/observability/metrics_promql.rst b/docs/observability/metrics_promql.rst index 03d90576a..ae8b16d1b 100644 --- a/docs/observability/metrics_promql.rst +++ b/docs/observability/metrics_promql.rst @@ -1,5 +1,6 @@ שאילתות PromQL שימושיות ========================= +:summary: שאילתות מוכנות לזמן תגובה, לשיעור שגיאות ולאירועי ביזנס. ראו גם :doc:`../metrics`. diff --git a/docs/observability/observability_dashboard.md b/docs/observability/observability_dashboard.md index ae68aff41..da3918f2b 100644 --- a/docs/observability/observability_dashboard.md +++ b/docs/observability/observability_dashboard.md @@ -1,3 +1,7 @@ +--- +summary: 'מסך ה-Admin ב-/admin/observability מרכז נתוני ניטור בזמן אמת ל-SRE ולמפתחים: כרטיסי מצב וגרפים, טבלת התראות עם סינון, ו-API מתועד למסלולי alerts, timeseries, aggregations, export, replay, runbook, quickfix ו-ai_explain.' +--- + # 📡 Observability Dashboard & API > קישורים מהירים: [README של Code Keeper Bot](https://github.com/amirbiron/CodeBot#-קוד-שומר) · [מדריך Config Radar](https://github.com/amirbiron/CodeBot/blob/main/GUIDES/CONFIG_RADAR_GUIDE.md) @@ -6,7 +10,7 @@ 1. **שקיפות** – כרטיסי מצב וגרפים קלים לקריאה עם קונטקסט של זמן. 2. **חקירה מהירה** – טבלת התראות עם סינון מתקדם ופג'ינציה חסכונית. -3. **API מתועד** – שלושה Endpoints סימטריים שניתנים לצריכה אוטומטית ע"י Grafana, Slack או סקריפטים. +3. **API מתועד** – מסלולי `GET` ו-`POST` תחת `/api/observability/` שניתנים לצריכה אוטומטית ע"י Grafana, Slack או סקריפטים. סעיף ה-API Reference שלמטה מתעד את מסלולי נתוני הליבה של המסך. המסך צורך גם משפחות נוספות תחת אותה קידומת — תגיות וסיפורי Incident — ואלה אינן מתועדות כאן, וכך גם coverage ו-drills. המסמך הזה מתאר את מבנה המסך, את פרטי ה־API, שיקולי אבטחה וביצועים, וכן דוגמאות אינטגרציה לצריכה חיצונית. diff --git a/docs/observability/query-performance-profiler.rst b/docs/observability/query-performance-profiler.rst index 42c1273ab..22c96213a 100644 --- a/docs/observability/query-performance-profiler.rst +++ b/docs/observability/query-performance-profiler.rst @@ -1,5 +1,6 @@ Query Performance Profiler ========================== +:summary: כלי ניטור לשאילתות MongoDB איטיות: דשבורד ב-WebApp שמציג את השאילתות הכבדות, ה-API שמאחוריו, ומה הכלי במפורש אינו עושה. .. contents:: תוכן עניינים :local: diff --git a/docs/observability/quick_fix_rules.md b/docs/observability/quick_fix_rules.md index c9028084d..279175ea9 100644 --- a/docs/observability/quick_fix_rules.md +++ b/docs/observability/quick_fix_rules.md @@ -1,3 +1,7 @@ +--- +summary: המטרה של Quick Fix היא לתת המלצה קצרה, בטוחה ושימושית על “מה לעשות עכשיו”, לפי אותות שאנחנו כבר מודדים. +--- + # 🧠 Quick Fix חכם (Queue Delay + עומס/DB) – הנחיות למפתחים ולסוכני AI המטרה של **Quick Fix** היא לתת המלצה קצרה, בטוחה ושימושית על “מה לעשות עכשיו”, לפי אותות שאנחנו כבר מודדים. diff --git a/docs/observability/tracing_hotspots.rst b/docs/observability/tracing_hotspots.rst index b333e488b..2675a162f 100644 --- a/docs/observability/tracing_hotspots.rst +++ b/docs/observability/tracing_hotspots.rst @@ -1,7 +1,6 @@ Tracing ממוקד בנקודות חמות =========================== - -מדריך קצר להתמקדות ב‑Tracing בנקודות בעלות השפעה גבוהה (Hotspots) בבוט וב‑WebApp. +:summary: מדריך קצר להתמקדות ב‑Tracing בנקודות בעלות השפעה גבוהה (Hotspots) בבוט וב‑WebApp. תרשימי זרימה ------------- diff --git a/docs/performance-bible.md b/docs/performance-bible.md index a3c2a07e2..8c5995718 100644 --- a/docs/performance-bible.md +++ b/docs/performance-bible.md @@ -1,3 +1,7 @@ +--- +summary: 'עקרונות הביצועים של המערכת אחרי הרפקטור שהוריד את ה-p95 מ-1.8 שניות ל-200ms: Cache First, Projection, חישוב ב-DB, אינדקסים מורכבים, ו-Lazy Loading.' +--- + 🚀 The Performance Bible: CodeKeeper Optimization Guide ====================================================== diff --git a/docs/performance-scaling.rst b/docs/performance-scaling.rst index 35564ed91..9c8fded63 100644 --- a/docs/performance-scaling.rst +++ b/docs/performance-scaling.rst @@ -1,5 +1,6 @@ ביצועים והרחבה (Performance & Scaling) ======================================= +:summary: עימוד, Projection, כוונון Connection Pooling ו-Timeouts, לוגי איטיות לאיתור צווארי בקבוק, והנחיות לפי סביבה. עימוד (Pagination) ------------------- diff --git a/docs/performance-sticky-notes.rst b/docs/performance-sticky-notes.rst index f2c7bd3a0..a5f28f121 100644 --- a/docs/performance-sticky-notes.rst +++ b/docs/performance-sticky-notes.rst @@ -1,5 +1,6 @@ Sticky Notes Warmup – פתרון ביצועים משולב =========================================== +:summary: העלאת timeout שכבר הוכחה בשטח, וחימום אינדקסים לפני שהתהליך מקבל תעבורה — נדבך שעדיין נבחן. כולל מה לאמת לפני rollout מלא. מבצע "Sticky Notes Warmup" מחולק לשני נדבכים משלימים: העלאת timeout מידית (מוכחת בשטח) וחימום אינדקסים לפני שה-process מקבל תעבורה (שיפור קוד שעדיין נבחן). המסמך מרכז את כל diff --git a/docs/performance-tests.rst b/docs/performance-tests.rst index 891bbcc3a..df23f3740 100644 --- a/docs/performance-tests.rst +++ b/docs/performance-tests.rst @@ -1,9 +1,6 @@ בדיקות ביצועים (Performance Tests) =================================== - -מטרה ------ -להריץ בדיקות ביצועים בצורה בטוחה וגמישה: ברירת מחדל מריצים את כולן; ב‑PR Draft עם תווית מתאימה מריצים רק "קלים". +:summary: להריץ בדיקות ביצועים בצורה בטוחה וגמישה: ברירת מחדל מריצים את כולן; ב‑PR Draft עם תווית מתאימה מריצים רק "קלים". סימון טסטים ----------- diff --git a/docs/quality/code-normalization.md b/docs/quality/code-normalization.md index f49e0aa71..7617249d1 100644 --- a/docs/quality/code-normalization.md +++ b/docs/quality/code-normalization.md @@ -1,8 +1,8 @@ -# נרמול קוד (Code Normalization) - -מסמך זה מרכז את כל מה שסוכן או מפתח צריך לדעת על מנגנון נרמול הקוד של Code Keeper Bot – למה הוא קיים, איך הוא עובד ואיך משתמשים בו ביום־יום. - --- +summary: מסמך זה מרכז את כל מה שסוכן או מפתח צריך לדעת על מנגנון נרמול הקוד של Code Keeper Bot – למה הוא קיים, איך הוא עובד ואיך משתמשים בו ביום־יום. +--- + +# נרמול קוד (Code Normalization) ## למה בכלל מנרמלים? - **אחידות בנתונים** – ניהול Snippets ממקורות שונים (טלגרם, WebApp, ייבוא קבצים) בלי הפתעות של CRLF, BOM או תווים נסתרים. diff --git a/docs/quality/type-safety.md b/docs/quality/type-safety.md index d54467478..d3c10c7f8 100644 --- a/docs/quality/type-safety.md +++ b/docs/quality/type-safety.md @@ -1,8 +1,8 @@ -# 📝 Type Hints – Best Practices - -מטרה: לשמר בטיחות טיפוסים ברורה, להקשיח מודולים בהדרגה, ולא להסתמך על `type: ignore`. - --- +summary: 'מטרה: לשמר בטיחות טיפוסים ברורה, להקשיח מודולים בהדרגה, ולא להסתמך על `type: ignore`.' +--- + +# 📝 Type Hints – Best Practices ## אסטרטגיה: הקשחה הדרגתית - התחילו ממודולים מרכזיים (DB, Web) והוסיפו טיפוסים ברורים לפונקציות ציבוריות. diff --git a/docs/quickstart-ai.rst b/docs/quickstart-ai.rst index f885b6a32..bf210ce1e 100644 --- a/docs/quickstart-ai.rst +++ b/docs/quickstart-ai.rst @@ -1,9 +1,6 @@ התחלה מהירה - סוכני AI ========================= - -מטרה ------ -מסמך זה נועד לאפשר לסוכן AI להתחיל לעבוד על הריפו במהירות ובבטחה, בהתאם למדיניות הפרויקט. +:summary: מסמך זה נועד לאפשר לסוכן AI להתחיל לעבוד על הריפו במהירות ובבטחה, בהתאם למדיניות הפרויקט. מה אסור -------- diff --git a/docs/quickstart-contrib.rst b/docs/quickstart-contrib.rst index cef5fa2c1..2b4a0db61 100644 --- a/docs/quickstart-contrib.rst +++ b/docs/quickstart-contrib.rst @@ -1,9 +1,6 @@ Quickstart לתרומה ================= - -מטרה ------ -דף קצר שמאפשר להתחיל לתרום במהירות ובבטחה. +:summary: דף קצר שמאפשר להתחיל לתרום במהירות ובבטחה. צעדי הכנה --------- diff --git a/docs/quickstart.rst b/docs/quickstart.rst index cf4d82f79..55179d3ab 100644 --- a/docs/quickstart.rst +++ b/docs/quickstart.rst @@ -1,9 +1,6 @@ התחלה מהירה - מפתחים ====================== - -מטרה ------ -שלושה צעדים כדי להריץ מקומית במהירות. +:summary: הצעדים להרצה מקומית מהירה של הבוט, מהתקנה ועד הפעלה. שלב 1: התקנה -------------- diff --git a/docs/rate-limiting.rst b/docs/rate-limiting.rst index a9f7b7c56..db45cb9fe 100644 --- a/docs/rate-limiting.rst +++ b/docs/rate-limiting.rst @@ -1,9 +1,6 @@ Rate Limiting ============= - -מבוא ----- -מערכת הגבלת קצב אחודה לבוט ולווב, עם Shadow Mode, Soft‑Warning ב‑80% ועקיפת מנהלים. +:summary: מערכת הגבלת קצב אחודה לבוט ולווב, עם Shadow Mode, Soft‑Warning ב‑80% ועקיפת מנהלים. Shadow Mode ----------- diff --git a/docs/repository-integrations.rst b/docs/repository-integrations.rst index c35ffbade..c6165850b 100644 --- a/docs/repository-integrations.rst +++ b/docs/repository-integrations.rst @@ -1,9 +1,6 @@ Repository Integrations ======================= - -סקירה ------ -מסמך זה מרכז את התמיכה בספקי מאגרי קוד. מטרתו למנוע בלבול ולהבהיר מה נתמך ומה לא. +:summary: מסמך זה מרכז את התמיכה בספקי מאגרי קוד. מטרתו למנוע בלבול ולהבהיר מה נתמך ומה לא. מצב תמיכה ---------- diff --git a/docs/resilience.rst b/docs/resilience.rst index b828b68bd..ff1025f36 100644 --- a/docs/resilience.rst +++ b/docs/resilience.rst @@ -1,11 +1,22 @@ Resilience לשירותים חיצוניים ============================= +:summary: שכבת Retry ו-Circuit Breaker לקריאות חוץ. היא חלה על קריאות שעוברות דרך http_sync.py ו-http_async.py; שירותים שקוראים ישירות ל-requests, httpx או aiohttp אינם מכוסים עדיין. למה שכבה מרוכזת? ----------------- -המעבר למודול ``resilience.py`` יוצר אחידות: כל קריאה החוצה עוברת דרך אותה מדיניות Retry + Circuit Breaker. +מודול ``resilience.py`` מרכז מדיניות אחת של Retry + Circuit Breaker לקריאות חוץ. התוצאה: פחות רעשים זמניים, ניטור ברור יותר, ויכולת להבין בזמן אמת מתי שירות חוץ "שורף" אותנו. +.. note:: + + הכיסוי אינו מלא. המדיניות חלה על קריאות שעוברות דרך ``http_sync.py`` ו-``http_async.py`` בלבד. + שירותים שקוראים ישירות ל-``requests``, ל-``httpx`` או ל-``aiohttp`` אינם עוברים דרכה — + למשל ``services/embedding_service.py`` (``httpx.AsyncClient``) ו-``services/observability_dashboard.py`` + (``requests.post``). ``services/rules_evaluator.py`` דווקא **מעדיף** את המסלול המכוסה + (``from http_sync import request``) ונופל ל-``requests.post`` רק אם הייבוא נכשל — + אבל הכיסוי בו **חלקי**: ``_call_webhook`` באותו קובץ שולח ישירות ב-``requests``. + המיגרציה של השאר עדיין פתוחה. + איך זה עובד? ------------ - RetryPolicy: כמה ניסיונות חוזרים, ו‑Backoff אקספוננציאלי עם ``jitter`` למניעת "עדר". diff --git a/docs/runbooks/github_backup_restore.rst b/docs/runbooks/github_backup_restore.rst index 6ff33b9e7..988a6c717 100644 --- a/docs/runbooks/github_backup_restore.rst +++ b/docs/runbooks/github_backup_restore.rst @@ -1,9 +1,6 @@ GitHub Backup & Restore Runbook =============================== - -מטרה ------ -מדריך צעד‑אחר‑צעד לגיבוי ושחזור מאגר GitHub, כולל יצירת נקודת בדיקה (Checkpoint Tag) ושחזור בטוח. +:summary: מדריך צעד‑אחר‑צעד לגיבוי ושחזור מאגר GitHub, כולל יצירת נקודת בדיקה (Checkpoint Tag) ושחזור בטוח. דרישות מקדימות --------------- diff --git a/docs/runbooks/incident-checklist.rst b/docs/runbooks/incident-checklist.rst index f4f4b3a67..081ae03df 100644 --- a/docs/runbooks/incident-checklist.rst +++ b/docs/runbooks/incident-checklist.rst @@ -1,5 +1,6 @@ Incident Checklist (On‑Call) ============================ +:summary: צ'קליסט לתורן בעת פתיחת Incident, וסטטוסי המעקב האחידים שבהם מדווחים עליו. בעת פתיחת Incident ------------------- diff --git a/docs/runbooks/logging-levels.rst b/docs/runbooks/logging-levels.rst index 7a9f927bd..cba63cfba 100644 --- a/docs/runbooks/logging-levels.rst +++ b/docs/runbooks/logging-levels.rst @@ -1,5 +1,6 @@ שינוי רמות לוגים ================= +:summary: איך משנים רמות לוג בזמן ריצה, ומתי כדאי להעלות ל-DEBUG. מתי להעלות ל-DEBUG ------------------- diff --git a/docs/runbooks/slo.md b/docs/runbooks/slo.md index a504d5e5c..c80361e0d 100644 --- a/docs/runbooks/slo.md +++ b/docs/runbooks/slo.md @@ -1,3 +1,7 @@ +--- +summary: 'ראנבוקים לתקלות SLO: HighErrorRate, חריגת זמינות מתחת ל-99.9%, וחריגת P95 מעל חצי שנייה — עם שאילתות ה-PromQL של כל אחת.' +--- + # Runbooks – SLO Incidents > תמצית. קצר, תכל'ס, בעברית פשוטה. diff --git a/docs/security.rst b/docs/security.rst index 566b3ad2f..0dcbb8792 100644 --- a/docs/security.rst +++ b/docs/security.rst @@ -1,11 +1,10 @@ Security Guide ============== +:summary: אל תרשום סודות/PII בלוגים, השתמש ב‑ENV בלבד. סודות ופרטיות -------------- -אל תרשום סודות/PII בלוגים, השתמש ב‑ENV בלבד. - ניקוי טוקן הבוט מלוגים, חריגות ו‑Sentry ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/sentry.rst b/docs/sentry.rst index c76c9211f..b1536d5b0 100644 --- a/docs/sentry.rst +++ b/docs/sentry.rst @@ -1,5 +1,6 @@ Sentry ====== +:summary: ברירת מחדל: Sentry מציג Issues בממשק ושולח מיילים, אבל לא מזרים את זה אוטומטית למערכת ההתראות הפנימית שלנו (Telegram + Observability). הפעלה (משתני סביבה) -------------------- diff --git a/docs/services/google_drive_service.rst b/docs/services/google_drive_service.rst index 50d0144ab..4a970ea13 100644 --- a/docs/services/google_drive_service.rst +++ b/docs/services/google_drive_service.rst @@ -1,9 +1,13 @@ Google Drive Service ==================== +:summary: שירות Google Drive: אימות ב-Device Flow, ניהול טוקנים, יצירת ZIP והעלאה לתיקיות לפי קטגוריה (ובקטגוריית 'לפי ריפו' גם תת-תיקייה לשם הריפו). התאריך והגרסה נכנסים לשם קובץ ה-ZIP, לא למבנה התיקיות. סקירה ----- -שירות גוגל דרייב אחראי לאימות (Device Flow), ניהול טוקנים, יצירת ZIP, והעלאות לתיקיות ממוסלות לפי קטגוריה/תאריך/ריפו. +שירות גוגל דרייב אחראי לאימות (Device Flow), ניהול טוקנים, יצירת ZIP, והעלאה לתיקיות לפי קטגוריה. +אין קינון לפי תאריך: ``compute_subpath`` מחזיר את תווית הקטגוריה בלבד, ורק ב-``by_repo`` מתווספת תת-תיקייה +בשם הריפו. התאריך והגרסה נכנסים לשם קובץ ה-ZIP דרך ``compute_friendly_name`` +(למשל ``BKP_zip_CodeBot_v7_26-08-2025.zip``). הערות OAuth ------------ @@ -13,7 +17,8 @@ Google Drive Service מבני קבצים ----------- - שמות קבצים: BKP_{label}_{entity}_v{n}_{date}.zip -- נתיב משנה: {קטגוריה}/{YYYY}/{MM-DD} ולפי ריפו אם רלוונטי. +- נתיב משנה: ``{קטגוריה}`` בלבד, ובקטגוריית ``by_repo`` גם ``{קטגוריה}/{שם הריפו}``. + אין קינון לפי תאריך — התאריך והגרסה נמצאים בשם הקובץ. API (autodoc) ------------- diff --git a/docs/services/index.rst b/docs/services/index.rst index e0485e5cf..184a9daf2 100644 --- a/docs/services/index.rst +++ b/docs/services/index.rst @@ -1,7 +1,6 @@ Services ======== - -תיעוד של שירותי הליבה של המערכת. +:summary: תיעוד של שירותי הליבה של המערכת. Code Service ------------ diff --git a/docs/style-glossary.rst b/docs/style-glossary.rst index 5ebd7e14e..b15eb098f 100644 --- a/docs/style-glossary.rst +++ b/docs/style-glossary.rst @@ -1,5 +1,6 @@ Style & Naming Glossary ======================== +:summary: מילון המונחים והשמות בפרויקט: מיפוי בין מונחים מקבילים, כללי הניסוח, ועוגני התיעוד שמפנים אליהם. מטרות ------ diff --git a/docs/testing-rate-limit-examples.rst b/docs/testing-rate-limit-examples.rst index 9424faa94..fa121fb69 100644 --- a/docs/testing-rate-limit-examples.rst +++ b/docs/testing-rate-limit-examples.rst @@ -1,5 +1,6 @@ דוגמאות טסטים – Rate Limiting ואסינכרוניות ============================================ +:summary: קטעי דוגמה לכתיבת טסטים ל-Rate Limiting מול Redis מדומה ולקוד אסינכרוני. הקטעים אינם ניתנים להרצה כמות שהם — הם מדלגים על הקשר עם ``...`` ומניחים פונקציות מקומיות. Rate Limiting (Redis Mock) -------------------------- diff --git a/docs/testing.rst b/docs/testing.rst index 055c07a57..aec23e16a 100644 --- a/docs/testing.rst +++ b/docs/testing.rst @@ -1,5 +1,6 @@ Testing Guide ============= +:summary: Quickstart להרצת טסטים, ההנחיות הקריטיות, טעינת ה-stubs לטלגרם, עבודה עם tmp_path ומתכון מחיקה מוגבל ל-allowlist, ו-mocking של HTTP. 🚀 Quickstart לטסטים -------------------- diff --git a/docs/troubleshooting.rst b/docs/troubleshooting.rst index 5223e5cf0..5263d194e 100644 --- a/docs/troubleshooting.rst +++ b/docs/troubleshooting.rst @@ -1,5 +1,6 @@ Troubleshooting Guide ===================== +:summary: מדריך פתרון תקלות: שגיאות ייבוא בזמן טסטים, שגיאות parse_mode, בעיות event loop של asyncio, וכלים לדיבוג מהיר כולל בדיקת חיבור ל-MongoDB. שגיאות נפוצות -------------- diff --git a/docs/user/bookmarks.rst b/docs/user/bookmarks.rst index 091b6e664..481ea757d 100644 --- a/docs/user/bookmarks.rst +++ b/docs/user/bookmarks.rst @@ -1,5 +1,6 @@ סימניות (Bookmarks) ==================== +:summary: סימניות בקבצים: איך מוסיפים, פאנל הסימניות, העוגן היציב שמחזיק אותן גם כשהקוד זז, ומגבלות הפרטיות והאבטחה. מהן סימניות? ------------ diff --git a/docs/user/download_repo.rst b/docs/user/download_repo.rst index 0b5f1e9fb..9eb7be29c 100644 --- a/docs/user/download_repo.rst +++ b/docs/user/download_repo.rst @@ -1,5 +1,6 @@ הורדת ריפו ========== +:summary: בתפריט /github ← 📥 הורד קובץ מריפו, נווטו לתיקייה הרצויה. בתחתית הרשימה יופיע כפתור שמציין במפורש מה ייארז, למשל 📦 הורד תיקייה כ־ZIP: "logo-designer". מה בדיוק מוריד ---------------- diff --git a/docs/user/github_browse.rst b/docs/user/github_browse.rst index 7a12cc5b2..d3ef907c1 100644 --- a/docs/user/github_browse.rst +++ b/docs/user/github_browse.rst @@ -1,5 +1,6 @@ עיון בקוד GitHub (כולל חיפוש בשם קובץ) ====================================== +:summary: שורת הכלים, חיפוש לפי שם קובץ, וניווט בעץ הריפו — הכול מתוך הבוט. שורת כלים --------- diff --git a/docs/user/my_collections.rst b/docs/user/my_collections.rst index 7657dc174..e35eb1eac 100644 --- a/docs/user/my_collections.rst +++ b/docs/user/my_collections.rst @@ -1,10 +1,6 @@ האוספים שלי (My Collections) ============================== - -מהם אוספים? ------------- -אוספים מאפשרים לאגד יחד קבצים/קטעי קוד/סימניות תחת נושא משותף (פרויקט, משימה, מודול), -כדי לשתף, לנווט ולעקוב בקלות. כל אוסף כולל שם, תיאור קצר ורשימת פריטים עם סדר מותאם. +:summary: אוספים מאפשרים לאגד יחד קבצים/קטעי קוד/סימניות תחת נושא משותף (פרויקט, משימה, מודול), כדי לשתף, לנווט ולעקוב בקלות. כל אוסף כולל שם, תיאור קצר ורשימת פריטים עם סדר מותאם. יכולות מרכזיות --------------- diff --git a/docs/user/reminders.rst b/docs/user/reminders.rst index 0406d3cdc..a5d1572f5 100644 --- a/docs/user/reminders.rst +++ b/docs/user/reminders.rst @@ -1,9 +1,6 @@ תזכורות בבוט ============ - -סקירה קצרה ------------ -מערכת התזכורות מאפשרת למשתמשי הבוט ליצור, לדחות ולנהל תזכורות אישיות דרך שיחה אינטראקטיבית או פקודות קצרות. המידע נשמר ב-MongoDB (`reminders/database.py`) ומנוהל דרך ישויות `Reminder` ו-`ReminderConfig`. +:summary: מערכת התזכורות מאפשרת למשתמשי הבוט ליצור, לדחות ולנהל תזכורות אישיות דרך שיחה אינטראקטיבית או פקודות קצרות. המידע נשמר ב-MongoDB (`reminders/database.py`) ומנוהל דרך ישויות `Reminder` ו-`ReminderConfig`. פקודות עיקריות --------------- diff --git a/docs/user/share_code.rst b/docs/user/share_code.rst index dd2160820..ec9fdd341 100644 --- a/docs/user/share_code.rst +++ b/docs/user/share_code.rst @@ -1,10 +1,31 @@ שיתוף קוד (חשוב) ================= +:summary: כפתור "🔗 שתף קוד" יוצר שיתוף מהיר של קובץ דרך GitHub Gist או Pastebin. הכפתור נושא את ה-ObjectId של הגרסה שהייתה קיימת כשהוא נוצר, ולכן הוא מצמיד גרסה ואינו מבטיח את התוכן העדכני. מה זה עושה? ------------ כפתור "🔗 שתף קוד" מאפשר ליצור שיתוף מהיר של קובץ קוד דרך GitHub Gist או Pastebin. -השיתוף נוצר לפי מזהה הקובץ במסד (ObjectId), כך שתמיד משתף את התוכן העדכני ביותר. + +יש שתי צורות ל-``callback_data`` של הכפתור, והן מתנהגות אחרת: + +- ``share_menu_id:`` — המזהה נצרב בכפתור. זה המסלול ברוב המקומות + (``handlers/documents.py``, ``handlers/save_flow.py``, ``large_files_handler.py``). +- ``share_menu_idx:<אינדקס>`` — הכפתור נושא **אינדקס** לתוך ``files_cache`` + שב-``context.user_data`` (``handlers/file_view.py``, ``conversation_handlers.py``). + אם הקאש הוחלף מאז שהכפתור רונדר, אותו אינדקס עלול להצביע על **קובץ אחר**. + +.. warning:: + + **קובץ רגיל (``code_snippets``):** ה-ObjectId מצמיד גרסה, לא קובץ. + ``save_code_snippet`` מעלה את ``version`` ב-1 ויוצר מסמך חדש, ולכן כפתור + שרונדר לפני עריכה ישתף את הגרסה שהייתה אז. + + **קובץ גדול (``large_files``):** ``save_large_file`` מוחק את המסמך הישן + ומכניס חדש, בלי לשמור גרסה קודמת. כפתור ישן לקובץ גדול ייכשל ("קובץ לא + נמצא") במקום לשתף גרסה קודמת. + + **בכל מקרה** — לשיתוף התוכן העדכני יש לפתוח את הקובץ מחדש ולהשתמש בכפתור + שמופיע בתצוגה הנוכחית. איפה הכפתור מופיע? ------------------- diff --git a/docs/user/sticky_notes.rst b/docs/user/sticky_notes.rst index 29e73af8d..15de01c55 100644 --- a/docs/user/sticky_notes.rst +++ b/docs/user/sticky_notes.rst @@ -1,5 +1,6 @@ פתקים דביקים (Sticky Notes) ============================= +:summary: הצמדת הערות קצרות על תצוגת קובץ (קוד/Markdown/HTML): הוספה וניהול, עיגון יציב לעומת מיקום קבוע, השילוב עם סימניות, ומגבלות הפרטיות והאבטחה. מהם פתקים דביקים? ------------------- diff --git a/docs/versioning-stable-anchors.rst b/docs/versioning-stable-anchors.rst index 88562fbab..fbd0eaf20 100644 --- a/docs/versioning-stable-anchors.rst +++ b/docs/versioning-stable-anchors.rst @@ -1,5 +1,6 @@ Versioning & Stable Anchors =========================== +:summary: מדיניות הגרסאות והעוגנים היציבים בתיעוד: אילו עוגנים מובטחים לא להישבר, איך מתעדים שינוי ב-What's New, ודוגמאות. מדיניות עוגנים יציבים ---------------------- diff --git a/docs/visual-rule-engine.rst b/docs/visual-rule-engine.rst index 3c92f7df9..61f881ad5 100644 --- a/docs/visual-rule-engine.rst +++ b/docs/visual-rule-engine.rst @@ -1,5 +1,6 @@ Visual Rule Engine - מנוע כללים ויזואלי ========================================== +:summary: מנוע כללים ויזואלי ליצירת התראות מורכבות מהממשק בלי לכתוב קוד: זרימת ההחלטה, מסך הכללים, יצירה והפעלה, וסכמת ה-JSON של כלל. .. note:: פיצ'ר זה זמין רק למשתמשי אדמין (``ADMIN_USER_IDS``). diff --git a/docs/webapp/advanced-caching.md b/docs/webapp/advanced-caching.md index 2715a972d..d540925ec 100644 --- a/docs/webapp/advanced-caching.md +++ b/docs/webapp/advanced-caching.md @@ -1,6 +1,8 @@ -# מערכת Caching מתקדמת עם TTL דינמי +--- +summary: 'מסמך זה מרכז את ההמלצות והדוגמאות להטמעת מערכת caching חכמה עם TTL דינמי, כפי שגובש ב-Feature Suggestion. המטרה: שיפור מהיר של זמני תגובה, הורדת עומסים על DB, ושימור עקביות בין שרתים.' +--- -מסמך זה מרכז את ההמלצות והדוגמאות להטמעת מערכת caching חכמה עם TTL דינמי, כפי שגובש ב-Feature Suggestion. המטרה: שיפור מהיר של זמני תגובה, הורדת עומסים על DB, ושימור עקביות בין שרתים. +# מערכת Caching מתקדמת עם TTL דינמי - **למה**: הפחתת זמן תגובה, עומס DB וצריכת רוחב-פס. - **מה**: TTL דינמי לפי סוג תוכן וקונטקסט, warming, invalidation חכם, ו-sync בין שרתים. diff --git a/docs/webapp/api-reference.rst b/docs/webapp/api-reference.rst index 972edc49d..9c159fb5f 100644 --- a/docs/webapp/api-reference.rst +++ b/docs/webapp/api-reference.rst @@ -1,5 +1,6 @@ WebApp API Reference ==================== +:summary: רפרנס ה-API של ה-WebApp: ה-endpoints, זרימת האימות מול Telegram, מבנה התשובה, וקודי השגיאה הנפוצים. Endpoints --------- diff --git a/docs/webapp/bulk-actions.rst b/docs/webapp/bulk-actions.rst index c3f3e6859..715c00ddc 100644 --- a/docs/webapp/bulk-actions.rst +++ b/docs/webapp/bulk-actions.rst @@ -1,7 +1,6 @@ Bulk actions (בחירה מרובה) ============================ - -דף זה מתאר את יכולות הבחירה המרובה והפעולות הקבוצתיות בממשק הווב. +:summary: דף זה מתאר את יכולות הבחירה המרובה והפעולות הקבוצתיות בממשק הווב. סקירה ----- diff --git a/docs/webapp/cache-inspector.rst b/docs/webapp/cache-inspector.rst index b11131fea..5e5550095 100644 --- a/docs/webapp/cache-inspector.rst +++ b/docs/webapp/cache-inspector.rst @@ -2,6 +2,7 @@ Cache Inspector (לוח בקרה של Redis) ===================================== +:summary: כלי אדמין לצפייה ולניהול של ה-Redis cache: סטטיסטיקות כלליות, חיפוש מפתחות, הצגת TTL וסטטוס, ומחיקה בטוחה של מפתחות. מה זה Cache Inspector? ----------------------- diff --git a/docs/webapp/caching.rst b/docs/webapp/caching.rst index acbe0b165..a707663b4 100644 --- a/docs/webapp/caching.rst +++ b/docs/webapp/caching.rst @@ -2,6 +2,7 @@ Caching & HTTP Validators (ETag / Last-Modified / 304) ====================================================== +:summary: להקטין רוחב‑פס וזמני תגובה: אם התוכן לא השתנה, נחזיר 304 Not Modified במקום גוף מלא. כך דפדפנים ולקוחות יכולים להשתמש במטמון מקומי בצורה בטוחה ויעילה. למה זה חשוב? -------------- diff --git a/docs/webapp/code-browser.rst b/docs/webapp/code-browser.rst index bb0b8a95c..49abdd36b 100644 --- a/docs/webapp/code-browser.rst +++ b/docs/webapp/code-browser.rst @@ -1,7 +1,6 @@ דפדפן קוד (Code Browser) ========================= - -דפדפן הקוד מאפשר צפייה וניווט בריפוזיטורים מ-GitHub ישירות בממשק ה-WebApp. +:summary: דפדפן הקוד מאפשר צפייה וניווט בריפוזיטורים מ-GitHub ישירות בממשק ה-WebApp. ייבוא ריפו חדש -------------- diff --git a/docs/webapp/code-execution.rst b/docs/webapp/code-execution.rst index 907071511..83e3d9d13 100644 --- a/docs/webapp/code-execution.rst +++ b/docs/webapp/code-execution.rst @@ -1,7 +1,6 @@ הרצת קוד (Code Execution Playground) ==================================== - -ב‑WebApp יש כלי שמאפשר להריץ קוד Python מתוך הדפדפן, דרך API ייעודי. +:summary: ב‑WebApp יש כלי שמאפשר להריץ קוד Python מתוך הדפדפן, דרך API ייעודי. .. important:: diff --git a/docs/webapp/commands-catalog.rst b/docs/webapp/commands-catalog.rst index 6d311d58f..84896a1d6 100644 --- a/docs/webapp/commands-catalog.rst +++ b/docs/webapp/commands-catalog.rst @@ -1,12 +1,19 @@ תחזוקת קטלוג הפקודות (``commands.json``) ========================================= +:summary: תחזוקת commands.json — הקטלוג שמזין את כרטיסי "קיצורי הדרך" בחיפוש הגלובלי. global_search.js טוען אותו רק בדפים שמכילים את globalSearchInput ואת searchBtn, ומוסיף כרטיסים לפי סוג (chatops/cli/playbook). מבוא ---- קטלוג הפקודות ב-``webapp/static/data/commands.json`` מזין את כרטיסי ה-"קיצורי דרך" -שנראים בחיפוש הגלובלי (קיצור מקלדת ``Ctrl/Cmd+K``). בכל טעינת דף, ה-frontend מושך את -הקובץ דרך ``/static/data/commands.json`` ומוסיף את הכרטיסים שזוהו ברמת הטייפ -(``chatops``/``cli``/``playbook``) על בסיס הקוד ב-``webapp/static/js/global_search.js``. +שנראים בחיפוש הגלובלי. ``webapp/static/js/global_search.js`` נטען ומאתחל את עצמו רק +בדפים שמכילים גם את ``globalSearchInput`` וגם את ``searchBtn`` — הוא יוצא מיד אחרת — +ואז מושך את הקובץ דרך ``/static/data/commands.json`` ומוסיף את הכרטיסים שזוהו ברמת +הטייפ (``chatops``/``cli``/``playbook``). + +.. note:: + + אין קיצור מקלדת ``Ctrl/Cmd+K`` בזרימה הזו. ``global_search.js`` מאזין ל-``Enter`` + בשדה החיפוש ולקליקים, ולא למקש קיצור גלובלי. .. important:: @@ -103,7 +110,8 @@ ./scripts/start_webapp.sh -2. פתחו ``http://localhost:5000`` (או הפורט שבחרתם) ולחצו ``Ctrl/Cmd+K`` כדי לפתוח חיפוש. +2. פתחו את ``http://localhost:5000/files`` (או הפורט שבחרתם) — זה הדף שמכיל את שדה + החיפוש הגלובלי — והקלידו בשדה או לחצו על כפתור החיפוש. 3. חפשו פקודה קיימת כגון ``/triage`` כדי לוודא שהקטלוג נטען. 4. חפשו את הפקודה החדשה ובדקו: - שהטקסט והטיפוס נכונים. diff --git a/docs/webapp/config-inspector.rst b/docs/webapp/config-inspector.rst index 4f12445ea..6ad5758a5 100644 --- a/docs/webapp/config-inspector.rst +++ b/docs/webapp/config-inspector.rst @@ -2,6 +2,7 @@ Config Inspector (סקירת משתני סביבה) ===================================== +:summary: כלי אדמין שמציג תמונת מצב של הקונפיגורציה ומשתני הסביבה, עם הסתרת ערכים רגישים. מה זה Config Inspector? ------------------------ diff --git a/docs/webapp/custom_themes_guide.rst b/docs/webapp/custom_themes_guide.rst index 23583d5b3..386ea064a 100644 --- a/docs/webapp/custom_themes_guide.rst +++ b/docs/webapp/custom_themes_guide.rst @@ -1,7 +1,6 @@ ערכות נושא מותאמות אישית – מדריך מקיף ====================================== - -מדריך זה מכסה את כל היבטי מערכת ערכות הנושא המותאמות אישית (Custom Themes) – מייבוא VS Code themes ועד יצירה ידנית, הגדרות מתקדמות והדגשת תחביר. +:summary: מדריך זה מכסה את כל היבטי מערכת ערכות הנושא המותאמות אישית (Custom Themes) – מייבוא VS Code themes ועד יצירה ידנית, הגדרות מתקדמות והדגשת תחביר. .. contents:: :depth: 3 diff --git a/docs/webapp/editor.md b/docs/webapp/editor.md index 164deed28..3c72e78ef 100644 --- a/docs/webapp/editor.md +++ b/docs/webapp/editor.md @@ -1,8 +1,8 @@ -# ⌨️ עורך קוד (WebApp Editor) - -תוכן זה מסביר את טעינת העורך, מנגנון הגיבוי, וניהול העדפות. - --- +summary: תוכן זה מסביר את טעינת העורך, מנגנון הגיבוי, וניהול העדפות. +--- + +# ⌨️ עורך קוד (WebApp Editor) ## טעינת CodeMirror ומצב isLoading - נטען את CodeMirror בצורה דינמית. diff --git a/docs/webapp/language-icons.rst b/docs/webapp/language-icons.rst index ceafd47db..ae889889a 100644 --- a/docs/webapp/language-icons.rst +++ b/docs/webapp/language-icons.rst @@ -1,9 +1,6 @@ אייקוני שפות התכנות ===================== - -כל קובץ ב-Web App מוצג עם אייקון שמייצג את שפת התכנות שלו. עד אוגוסט 2026 אלה -היו אמוג'ים (🐍 לפייתון, 📜 ל-JavaScript); היום אלה 28 אייקונים מצוירים -בסגנון אחיד — אריח ריבועי עם גרדיאנט וסימן לבן. +:summary: כל קובץ ב-Web App מוצג עם אייקון שמייצג את שפת התכנות שלו. עד אוגוסט 2026 אלה היו אמוג'ים (🐍 לפייתון, 📜 ל-JavaScript); היום אלה אייקונים מצוירים בסגנון אחיד — אריח ריבועי עם גרדיאנט וסימן לבן. המסמך מתאר איך המערכת בנויה, איך מוסיפים אייקון, ובאילו מלכודות כבר נתקלנו. diff --git a/docs/webapp/markdown-folding.rst b/docs/webapp/markdown-folding.rst index 834d570f0..bf02b48fc 100644 --- a/docs/webapp/markdown-folding.rst +++ b/docs/webapp/markdown-folding.rst @@ -1,5 +1,6 @@ Markdown – מצב מצומצם (קיפול כותרות ###) – אדמין בלבד ===================================================== +:summary: מטרת הפיצ'ר: לאפשר לעורכים לקפל מקומית סעיפים לפי כותרות ### (H3) בתצוגת Markdown, בלי לשנות את קובץ ה־Markdown ובלי להשפיע על תצוגה ציבורית. מטרת הפיצ'ר: לאפשר לעורכים לקפל מקומית סעיפים לפי כותרות ``###`` (H3) בתצוגת Markdown, בלי לשנות את קובץ ה־Markdown ובלי להשפיע על תצוגה ציבורית. diff --git a/docs/webapp/onboarding.md b/docs/webapp/onboarding.md index b4df295f0..d6d4e3488 100644 --- a/docs/webapp/onboarding.md +++ b/docs/webapp/onboarding.md @@ -1,3 +1,7 @@ +--- +summary: 'תהליך ה-Onboarding ב-WebApp: Welcome Modal, סיור אינטראקטיבי מבוסס Driver.js, ואשף בחירת ערכת הנושא — כולל מנגנוני האיפוס והנקודות למפתחים.' +--- + # 🧭 WebApp Onboarding – Welcome Modal, Interactive Tour & Theme Wizard תהליך ה-Onboarding של ה-WebApp מורכב משלושה רכיבים תלויים שמופעלים עבור משתמשים חדשים בלבד: Welcome Modal, סיור אינטראקטיבי מבוסס Driver.js וה-Theme Picker Wizard שמסיים את החוויה עם התאמה אישית. העמוד מרכז את ההסברים התפעוליים, מנגנוני האיפוס והנקודות החשובות למפתחים. diff --git a/docs/webapp/overview.rst b/docs/webapp/overview.rst index 56b7123b7..fd36a6b85 100644 --- a/docs/webapp/overview.rst +++ b/docs/webapp/overview.rst @@ -1,5 +1,6 @@ המיני Web App (סקירה) ====================== +:summary: מאוגוסט 2026 האייקונים אינם אמוג'ים אלא אייקונים מצוירים (SVG) בסגנון אחיד, שנשלפים מספרייט אחד. המבנה המלא, הגדלים, אופן ההוספה והמלכודות מתועדים בנפרד: language-icons. מה נותן? -------- diff --git a/docs/webapp/smooth-scrolling.rst b/docs/webapp/smooth-scrolling.rst index 19c01c590..bb870bb78 100644 --- a/docs/webapp/smooth-scrolling.rst +++ b/docs/webapp/smooth-scrolling.rst @@ -1,7 +1,6 @@ Smooth Scrolling (WebApp) — מדריך תמציתי לסוכני AI =================================================== - -מדריך זה מסביר את יכולות הגלילה החלקה שהוטמעו ב‑WebApp, כיצד להשתמש בהן באופן בטוח, ומה הדגשים לסוכני AI כדי לשמור על נגישות וביצועים. +:summary: מדריך זה מסביר את יכולות הגלילה החלקה שהוטמעו ב‑WebApp, כיצד להשתמש בהן באופן בטוח, ומה הדגשים לסוכני AI כדי לשמור על נגישות וביצועים. מה פעיל כבר ----------- diff --git a/docs/webapp/snippet-library.rst b/docs/webapp/snippet-library.rst index b96c6e77f..9fb7de6ac 100644 --- a/docs/webapp/snippet-library.rst +++ b/docs/webapp/snippet-library.rst @@ -1,11 +1,6 @@ ספריית סניפטים (Web) ====================== - -מה זה? ------- -"ספריית סניפטים" היא גלריית קטעי קוד קצרים עם הדגשת תחביר, חיפוש וסינון. -הספרייה מציגה גם סניפטים שהוגשו ע"י משתמשים (לאחר אישור אדמין), וגם סניפטים מובנים -(Curated) שמסופקים כחלק מהמערכת. +:summary: גלריית קטעי קוד קצרים עם הדגשת תחביר, מאפייני ה-UI, והפעולות שאפשר לבצע עליה. מאפייני UI ----------- diff --git a/docs/webapp/static-checklist.rst b/docs/webapp/static-checklist.rst index 61288255c..9977dda63 100644 --- a/docs/webapp/static-checklist.rst +++ b/docs/webapp/static-checklist.rst @@ -2,10 +2,7 @@ Static Performance & Security Checklist (gzip/br, Cache, SRI) ============================================================= - -מטרה ------ -להבטיח טעינה מהירה ובטוחה של נכסים סטטיים (CSS/JS/Images). +:summary: להבטיח טעינה מהירה ובטוחה של נכסים סטטיים (CSS/JS/Images). דחיסה (br/gzip) ---------------- diff --git a/docs/webapp/system-modules.rst b/docs/webapp/system-modules.rst index df0d06206..ef25c8d57 100644 --- a/docs/webapp/system-modules.rst +++ b/docs/webapp/system-modules.rst @@ -1,5 +1,6 @@ מודולים פנימיים ב-WebApp ========================= +:summary: הקבצים הבאים בתיקיית webapp/ מנהלים תשתיות שאינן מכוסות במדריכים קודמים. העמוד מסביר את ה‑API, התלויות והסיבות לכל רכיב כדי שיהיה אפשר להרחיב או לדבג במהירות. הקבצים הבאים בתיקיית ``webapp/`` מנהלים תשתיות שאינן מכוסות במדריכים קודמים. העמוד מסביר את ה‑API, התלויות והסיבות לכל רכיב כדי שיהיה אפשר להרחיב או לדבג במהירות. diff --git a/docs/webapp/theming_and_css.rst b/docs/webapp/theming_and_css.rst index 9bd7cad15..b5e9e9264 100644 --- a/docs/webapp/theming_and_css.rst +++ b/docs/webapp/theming_and_css.rst @@ -1,7 +1,6 @@ מערכת ערכות הנושא והטוקנים החדשה ================================= - -הדף מרכז את כל הידע המעשי על ארכיטקטורת הצבעים, משתני ה‑CSS והבדיקות שנדרשות לשימור חוויית הממשק בכל שמונה הערכות. זהו מקור האמת עבור כל שינוי עתידי ב‑CSS של ה‑WebApp. +:summary: ארכיטקטורת הצבעים, משתני ה-CSS והבדיקות שנדרשות לשימור חוויית הממשק בכל ערכות הנושא. מקור האמת לכל שינוי ב-CSS של ה-WebApp. .. contents:: :depth: 2 diff --git a/docs/webapp/user-interfaces.rst b/docs/webapp/user-interfaces.rst index 80cb5175e..595e5eb67 100644 --- a/docs/webapp/user-interfaces.rst +++ b/docs/webapp/user-interfaces.rst @@ -1,9 +1,6 @@ ממשקי משתמשים (Web) ===================== - -מה זה? ------- -"ממשקי משתמשים" הם אוסף מסכים ותהליכים אינטראקטיביים ב‑WebApp שמאפשרים לבצע פעולות מורכבות בנוחות: טפסים ממוקדים, אשפים רב‑שלביים, ותצוגות מצב. הפיצ'ר מיועד גם לשימוש ישיר ע"י משתמשי קצה וגם להפעלה מונחית ע"י סוכני AI. +:summary: אוסף המסכים והתהליכים האינטראקטיביים ב-WebApp, איפה כל אחד נמצא, ומה הוא עושה. היכן זה נמצא? -------------- diff --git a/docs/whats-new.rst b/docs/whats-new.rst index d28c5a91e..3385b1449 100644 --- a/docs/whats-new.rst +++ b/docs/whats-new.rst @@ -1,5 +1,6 @@ What's New ========== +:summary: יומן השינויים של הבוט וה-WebApp לפי תאריך — מה נוסף, מה השתנה ומה תוקן בכל עדכון, עם קישורים ל-Issues הרלוונטיים. 2026-01-29 ---------- diff --git a/docs/workflows/backup-flow.rst b/docs/workflows/backup-flow.rst index 8ab35bf37..1a2e45424 100644 --- a/docs/workflows/backup-flow.rst +++ b/docs/workflows/backup-flow.rst @@ -1,5 +1,6 @@ זרימת גיבוי ושחזור (Backup Flow) =================================== +:summary: זרימת הגיבוי והשחזור מקצה לקצה: סוגי הגיבויים, יצירת גיבוי מלא, שחזור, העלאה ל-Google Drive, ניהול הגיבויים הקיימים, וייבוא ZIP חיצוני. סקירה כללית ------------ diff --git a/docs/workflows/gist-flow.rst b/docs/workflows/gist-flow.rst new file mode 100644 index 000000000..9e43549f2 --- /dev/null +++ b/docs/workflows/gist-flow.rst @@ -0,0 +1,182 @@ +זרימת שיתוף ב-Gist (Gist Flow) +================================ +:summary: נקודות הכניסה לשיתוף ב-Gist, למה ה-Gist נוצר תחת חשבון ה-GitHub של המשתמש ולא של המערכת, מצבי auth_failed, וההתנהגות fail-closed בכל מסלול כשל. + +סקירה כללית +------------ + +שיתוף ב-GitHub Gist יוצר את ה-Gist **תחת החשבון האישי של המשתמש**, לא תחת חשבון המערכת. זו לא החלטה קוסמטית: Gist שנוצר בטוקן המערכת מופיע ברשימת ה-Gists של המערכת, מיוחס אליה, והמשתמש לא יכול לערוך או למחוק אותו. לכן ``GITHUB_TOKEN`` (משתנה הסביבה) אינו משמש ליצירת Gist באף מסלול — גם לא כמסלול נפילה בכשל. + +המשמעות המעשית: משתמש שלא חיבר חשבון GitHub **לא יכול** לשתף ב-Gist, ומקבל הנחיה לחבר או להשתמש ב-Pastebin. + +נקודות כניסה +------------- + +ארבעה מסלולים מגיעים לאותה פונקציה, ``integrations.resolve_gist_for_user``: + +.. list-table:: מסלולי הכניסה + :header-rows: 1 + :widths: 28 22 28 22 + + * - פונקציה + - מודול + - הקשר + - מתודת היצירה + * - ``share_single_by_id`` + - ``conversation_handlers`` + - שיתוף קובץ בודד מתוך שיחה + - ``create_gist`` + * - ``_share_to_gist`` + - ``bot_handlers`` + - כפתור ``🔗 שתף קוד`` על קובץ + - ``create_gist`` + * - ``_share_to_gist_multi`` + - ``bot_handlers`` + - שיתוף מרובה קבצים + - ``create_gist_multi`` + * - ``_export_gist`` + - ``refactor_handlers`` + - ייצוא תוצאת ריפקטורינג + - ``create_gist_multi`` + +כל ארבעתם קוראים דרך ``asyncio.to_thread``. הקריאה חוסמת — היא נוגעת ב-MongoDB וברשת — ומתוך handler אסינכרוני היא הייתה תוקעת את ה-event loop לכל המשתמשים, לא רק למי שלחץ. + +זרימת עבודה בסיסית +------------------- + +.. mermaid:: + + sequenceDiagram + participant U as User + participant H as Handler + participant R as resolve_gist_for_user + participant DB as MongoDB + participant I as GitHubGistIntegration + participant GH as GitHub API + + U->>H: 🔗 שתף קוד ← 🐙 GitHub Gist + H->>R: asyncio.to_thread(resolve_gist_for_user, user_id) + R->>DB: get_github_token(user_id) + DB->>R: טוקן מפוענח או None + + alt אין טוקן + R->>H: (None, GIST_NEEDS_GITHUB_MESSAGE) + H->>U: "כדי לשתף ב-Gist צריך לחבר GitHub" + else יש טוקן + R->>I: GitHubGistIntegration(token=token) + I->>GH: GET /user (דרך גישה ל-login) + alt הטוקן נדחה + GH->>I: 401 / 403 / 404 + I->>I: auth_failed = True + R->>H: (None, GIST_NEEDS_GITHUB_MESSAGE) + H->>U: "חבר מחדש" + else תקלה זמנית + GH->>I: 5xx / הגבלת קצב + I->>I: auth_failed = False + R->>H: (None, GIST_TEMPORARY_FAILURE_MESSAGE) + H->>U: "נסה שוב בעוד רגע" + else הצלחה + GH->>I: 200 + R->>H: (integration, None) + alt קובץ בודד + H->>I: asyncio.to_thread(create_gist, ...) + else שיתוף מרובה או ייצוא ריפקטורינג + H->>I: asyncio.to_thread(create_gist_multi, ...) + end + I->>GH: POST /gists + alt נוצר ויש url + GH->>I: Gist + I->>H: dict עם url + H->>U: הקישור ל-Gist + else None או dict בלי url + I->>H: None + H->>U: "השיתוף נכשל" + end + end + end + +אימות הטוקן — למה יש שורה שנראית מיותרת +----------------------------------------- + +בבנאי של ``GitHubGistIntegration`` יש שורה שנראית כמו קוד מת: + +.. code-block:: python + + user = self.github.get_user() + _ = user.login + self.user = user + +היא לא מיותרת, והיא **חייבת** להישאר. ``Github.get_user()`` ללא ארגומנט מחזיר ``AuthenticatedUser`` עם ``completed=False`` — אובייקט עצל שלא שלח שום בקשה. ה-``GET /user`` יוצא רק בגישה הראשונה לשדה, דרך ``_completeIfNotSet``. בלי הגישה ל-``login``, טוקן שנשלל היה "מתחבר" בהצלחה, ``is_available()`` היה מחזיר אמת, וכל סיווג הכשלים למטה לא היה רץ לעולם. הכשל היה מתגלה רק בניסיון ליצור את ה-Gist, עם הודעה שלא מצביעה על המקור. + +הערך עצמו לא נרשם ללוג: ``login`` הוא מזהה אישי. השורה הזו כבר נמחקה פעם אחת בתיקון PII, וזה הפיל את האימות — ראה `side-effect-riding-on-log-line `_. + +שלושת מצבי ``auth_failed`` +--------------------------- + +``auth_failed`` הוא ``Optional[bool]``, ולא דגל דו-ערכי. שלושת הערכים מבחינים בין שני סוגי כשל שמחייבים הודעות שונות — ומצב שלישי שבו לא נכשלנו כלל: + +.. list-table:: מצבי auth_failed + :header-rows: 1 + :widths: 15 35 50 + + * - ערך + - משמעות + - מה המשתמש רואה + * - ``None`` + - לא ניסינו, או שההתחברות הצליחה + - הזרימה ממשיכה + * - ``True`` + - הטוקן עצמו פסול + - ``GIST_NEEDS_GITHUB_MESSAGE`` — חבר מחדש + * - ``False`` + - הכשל זמני; הטוקן תקין + - ``GIST_TEMPORARY_FAILURE_MESSAGE`` — נסה שוב + +הסיווג נעשה ב-``_is_auth_failure``, והוא נשען על תת-המחלקות של PyGithub ולא על קוד הסטטוס: + +.. code-block:: python + + if isinstance(error, RateLimitExceededException): + return False # הטוקן תקין, המכסה נגמרה + if isinstance(error, (BadCredentialsException, TwoFactorException)): + return True + return getattr(error, "status", None) in {401, 403, 404} + +**למה לא לפי קוד סטטוס בלבד:** 403 הוא גם הגבלת קצב וגם הרשאה חסרה. טוקן fine-grained בלי הרשאת ``gist`` מחזיר 403 אמיתי שדורש חיבור מחדש, בעוד שמכסה שנגמרה מחזירה 403 שדורש רק המתנה. PyGithub כבר מבחין ביניהם ב-``Requester.createException``, ולכן נשענים על הסיווג שלו. לשלוח משתמש לחבר מחדש חשבון תקין, בגלל מכסה שתתאפס בעוד רבע שעה, זו הודעה שגורמת נזק. + +למה שתי הודעות ולא אחת +------------------------ + +זו ההבחנה המרכזית בזרימה הזו. "לא חיברת GitHub" ו"GitHub לא זמין כרגע" נראים דומים בקוד ומובילים לפעולה הפוכה אצל המשתמש: הראשון דורש ממנו ללכת לתפריט ולחבר חשבון, השני דורש ממנו לא לעשות כלום ולנסות שוב. הודעה אחת גנרית הייתה שולחת משתמש מחובר לחבר חשבון שכבר מחובר — ואם הוא "יתקן" את זה, הוא עלול לנתק ולחבר מחדש בלי סיבה. + +Fail-closed +------------ + +בכל מסלול כשל התוצאה זהה מבחינת המשתמש: **לא מוצג קישור, ולא מדווחת הצלחה**, ואין נפילה לטוקן המערכת. זה מכוון. ה-``except Exception`` סביב טעינת הטוקן רחב במכוון — כל כשל שכן נזרק מסתיים באי-שיתוף ולא בשיתוף תחת חשבון המערכת. + +**מה fail-closed כאן לא מבטיח:** שה-Gist לא נוצר בצד GitHub. ``create_gist`` בונה את מילון התוצאה *אחרי* שה-``POST /gists`` כבר הצליח — היא ניגשת ל-``gist.created_at.isoformat()`` ולשדות של כל קובץ. כשל בשלב הזה נתפס באותו ``except`` ומחזיר ``None``, בעוד שה-Gist כבר קיים בחשבון המשתמש. המשתמש יראה "נכשל", וניסיון חוזר ייצור Gist שני. החלון צר, אבל הוא קיים — ולכן הניסוח כאן הוא "אין קישור" ולא "אין Gist". + +ה-``logger.exception`` הוא מה שמונע בליעה שקטה: ה-traceback נרשם ללוג, ובסביבה שבה Sentry מוגדר הוא נאסף גם שם. בלי DSN, ``init_sentry`` יוצאת מוקדם ו-``LoggingIntegration`` לא מותקנת כלל — אז ההבטחה היא הלוג, לא Sentry. + +Edge Cases +---------- + +**``user_id`` ריק או אפס** + יציאה מוקדמת עם ``GIST_NEEDS_GITHUB_MESSAGE``, בלי פנייה ל-DB. + +**``create_gist`` / ``create_gist_multi`` מחזירות ``None``** + שתיהן בולעות חריגות ומחזירות ``None`` בכשל — הן לא זורקות. לכן ``try/except`` סביבן לא מספיק, ובדיקת התוצאה היא מה שמונע דיווח ✅ על שיתוף שלא קרה. זה דפוס K11. ``_export_gist`` בודק ``if not result or not result.get("url")`` — כלומר גם תוצאה שחזרה אבל בלי ``url`` נחשבת כשל, כי בלי ``url`` אין מה להציג למשתמש. + +**כשל בטעינת הטוקן מ-MongoDB** + ``get_github_token`` ב-``database/repository.py`` תופסת את החריגה בעצמה, רושמת ``db_get_github_token_error`` ומחזירה ``None``. כלומר תקלת DB אינה מגיעה כחריגה ל-``resolve_gist_for_user``, אלא נראית שם כמו "אין טוקן" — והמשתמש מקבל את הודעת החיבור ולא את הודעת התקלה הזמנית. ה-fail-closed נשמר, אבל ההבחנה בין שתי ההודעות מתבטלת במסלול הזה. + +**הטוקן מוצפן ב-DB** + ``get_github_token`` מפענחת דרך ``secret_manager.decrypt_secret``. אם הפענוח נכשל היא מחזירה את הערך המאוחסן כפי שהוא, וההתחברות ל-GitHub תיכשל עם 401 — כלומר תסווג כטוקן פסול. + +קישורים +-------- + +- :doc:`/user/share_code` +- :doc:`/api/integrations` +- :doc:`/api/conversation_handlers` +- :doc:`/security` diff --git a/docs/workflows/index.rst b/docs/workflows/index.rst index 06eec96a9..abbb90d57 100644 --- a/docs/workflows/index.rst +++ b/docs/workflows/index.rst @@ -1,10 +1,6 @@ זרימות עבודה (Workflows) ========================== - -סקירה כללית ------------- - -מסמכים אלה מתארים את הזרימות המרכזיות במערכת. +:summary: מסמכים אלה מתארים את הזרימות המרכזיות במערכת. רשימת זרימות ------------- @@ -16,6 +12,7 @@ search-flow refactor-flow backup-flow + gist-flow קישורים -------- diff --git a/docs/workflows/refactor-flow.rst b/docs/workflows/refactor-flow.rst index 93b3b9e34..2b9a2e510 100644 --- a/docs/workflows/refactor-flow.rst +++ b/docs/workflows/refactor-flow.rst @@ -1,10 +1,6 @@ זרימת רפקטורינג (Refactor Flow) ================================= - -סקירה כללית ------------- - -מנוע הרפקטורינג מאפשר שינוי מבנה קוד בצורה בטוחה עם אימות לפני ואחרי. +:summary: מנוע הרפקטורינג מאפשר שינוי מבנה קוד בצורה בטוחה עם אימות לפני ואחרי. סוגי רפקטורינג --------------- diff --git a/docs/workflows/save-flow.rst b/docs/workflows/save-flow.rst index 9a13ea1c5..fadbe5b1c 100644 --- a/docs/workflows/save-flow.rst +++ b/docs/workflows/save-flow.rst @@ -1,5 +1,6 @@ זרימת שמירת קוד (Save Flow) ============================== +:summary: מצבי השמירה, מצב האיסוף הארוך, זיהוי סודות, טיפול בכפילויות, ונרמול הקוד לפני השמירה. סקירה כללית ------------ diff --git a/docs/workflows/search-flow.rst b/docs/workflows/search-flow.rst index b9bf330d6..e7a68d497 100644 --- a/docs/workflows/search-flow.rst +++ b/docs/workflows/search-flow.rst @@ -1,5 +1,6 @@ זרימת חיפוש (Search Flow) =========================== +:summary: סוגי החיפוש בזרימת הבוט — טקסט, Regex, Fuzzy, פונקציות ותוכן — עם מבנה ה-SearchIndex, הפילטרים, הטיפול בשגיאות Regex ומיון התוצאות. החיפוש הסמנטי הוא מסלול נפרד ב-WebApp. סקירה כללית ------------ @@ -11,6 +12,17 @@ - **Content Search** - חיפוש בתוך תוכן הקבצים - **Function Search** - מציאת הגדרות פונקציות +.. warning:: + + ``SearchType.SEMANTIC`` קיים ב-``enum`` אבל **אינו ממומש בזרימה הזו**: + ל-``AdvancedSearchEngine.search`` אין ענף עבורו, והוא נופל ל-``else`` + שמריץ ``_text_search`` — כלומר חיפוש טקסט רגיל, בלי embeddings. + + החיפוש הסמנטי האמיתי הוא מסלול נפרד: הפונקציה ``semantic_search`` + ברמת המודול (חיפוש היברידי טקסט+וקטור), שנחשפת ב- + ``POST /api/search/semantic`` ב-WebApp. גם היא נופלת לחיפוש טקסט + כאשר ``SEMANTIC_SEARCH_ENABLED`` כבוי או ששירות ה-embeddings לא זמין. + סוגי חיפוש ----------- diff --git a/handlers/drive/menu.py b/handlers/drive/menu.py index 4feb96057..4e9db48eb 100644 --- a/handlers/drive/menu.py +++ b/handlers/drive/menu.py @@ -497,6 +497,7 @@ async def menu(self, update: Update, context: ContextTypes.DEFAULT_TYPE): # Connected -> show main backup selection directly per requested flow await self._render_simple_selection(update, context, header_prefix="Google Drive — מחובר\n") + # docs:drive-callback-open:start — הקטע מוטמע בתיעוד (docs/conversation-handlers.rst); אל תסיר את הסימון async def handle_callback(self, update: Update, context: ContextTypes.DEFAULT_TYPE): query = update.callback_query user_id = query.from_user.id @@ -509,6 +510,7 @@ async def handle_callback(self, update: Update, context: ContextTypes.DEFAULT_TY # Backward compatibility: map old callback to new one if data == "drive_advanced": data = "drive_sel_adv" + # docs:drive-callback-open:end if data == "drive_auth": __import__('logging').getLogger(__name__).warning(f"Drive: start auth by user {user_id}") try: diff --git a/main.py b/main.py index 903147787..837e7ec6a 100644 --- a/main.py +++ b/main.py @@ -3683,6 +3683,7 @@ async def _upload_cancel(update: Update, context: ContextTypes.DEFAULT_TYPE): pass return ConversationHandler.END + # docs:upload-conv:start — הקטע מוטמע בתיעוד (docs/conversation-handlers.rst); אל תסיר את הסימון upload_conv_handler = ConversationHandler( entry_points=[ CallbackQueryHandler(github_handler.handle_menu_callback, pattern='^upload_file$') @@ -3703,6 +3704,7 @@ async def _upload_cancel(update: Update, context: ContextTypes.DEFAULT_TYPE): CallbackQueryHandler(_upload_cancel, pattern=r'^cancel$') ] ) + # docs:upload-conv:end self.application.add_handler(upload_conv_handler) diff --git a/scripts/generate_ai_map.py b/scripts/generate_ai_map.py new file mode 100644 index 000000000..d5fc1e606 --- /dev/null +++ b/scripts/generate_ai_map.py @@ -0,0 +1,461 @@ +#!/usr/bin/env python3 +"""מחולל AI-MAP.md — מפת ניווט של אתר התיעוד, נגזרת מהקבצים עצמם. + +הבעיה שהקובץ פותר: באתר יש כ-240 עמודים, וסוכן שמחפש תשובה גורר את +כולם או מוותר. המפה נותנת שורה אחת לכל עמוד ידני — נתיב, כותרת, והתקציר +שהעמוד מצהיר עליו בראשו — כדי שהחיפוש יתחיל מקובץ אחד. + +עקרונות, לפי תוכנית עיגון התיעוד (אוגוסט 2026): + +- **נגזר, לא נכתב.** ההיררכיה נלקחת מה-toctree של Sphinx (מקור האמת), + והתקצירים מהצהרת העמוד. עריכה ידנית של הפלט תידרס בריצה הבאה. +- **דטרמיניסטי.** אותו קלט ← אותו פלט, בייט בבייט: סדר ה-toctree נשמר, + אין חותמות זמן, קידוד UTF-8 קבוע. בלי זה כל השוואה הופכת לרעש. +- **מסונן מכנית.** עמודים שהם פיגום autodoc בלבד (הוראת automodule בלי + שום תוכן משלהם) לא נכללים — התוכן שלהם נוצר רק בזמן בנייה, ומהריפו + אין בהם כלום. הם נספרים בשורת סיכום כדי שההשמטה תהיה גלויה. +- **התקציר מוצהר, לא מנוחש.** ב-``.rst`` שדה ``:summary:`` ברשימת השדות + שמיד אחרי הכותרת; ב-``.md`` המפתח ``summary`` ב-front matter. אין + הצהרה — שורת המפה מציגה כותרת בלבד, ו-``--check`` מתריע. הגרסה + הקודמת חילצה את פסקת הפרוזה הראשונה, וכדי לעשות זאת מימשה חלקים + מ-GFM ומ-RST ביד; ארבעה סבבי ריוויו מצאו שם מקרי קצה. + +בלי --out המפה מודפסת ל-stdout ושום קובץ לא נכתב; --out קובע מתי ולאן. +ה-workflow מעביר --out AI-MAP.md בשורש הריפו ולא ב-docs/, כי MyST פעיל +וכל .md בתוך docs/ נכנס לבניית Sphinx — עמוד שאינו ב-toctree מפיל את +RTD על אזהרת יתום. +""" + +from __future__ import annotations + +import re +import sys +from pathlib import Path + +import yaml + +ROOT = Path(__file__).resolve().parent.parent +DOCS = ROOT / "docs" +OUTPUT = ROOT / "AI-MAP.md" +SUMMARY_CAP = 220 + +# שורת directive של RST (.. name::) או תחילת בלוק הערה (.. בלי ::) +_DIRECTIVE_RE = re.compile(r"^\.\. ") +_UNDERLINE_RE = re.compile(r"^([=\-~^\"'#*+.`:_])\1{2,}\s*$") +_FIELD_RE = re.compile(r"^:[\w-]+:") +# שדה ההצהרה, בעמודה 0 בדיוק — שדה מוזח שייך לבלוק שמעליו +_SUMMARY_FIELD_RE = re.compile(r"^:summary:[ \t]*(.*)$") +# מה מדלגים עליו בדרך אל ההצהרה, ולמה זה כלל אחד ולא רשימת שמות. +# +# גרסה קודמת כאן מידלה את ``DocInfo`` של docutils — הטרנספורם שמקדם +# רשימת שדות ל-```` ומתעלם בדרך מ-``nodes.PreBibliographic``. +# אימות מול הצרכן הראה שהטרנספורם הזה כלל אינו רץ כאן: Sphinx מכבה +# ``doctitle_xform`` (``sphinx/environment/__init__.py``, שורה 66: +# ``'doctitle_xform': False``), הכותרת נשארת בתוך ``
``, +# ``DocInfo`` לא מוצא רשימת שדות כילד ראשון של המסמך — ואין קידום. בבנייה +# מלאה של האתר יש **אפס** בלוקי ``docinfo``, ו-``:summary:`` מרונדר כמו +# שהוא: ``
`` במקום שבו הוא כתוב. +# +# מהמודל המת ההוא נולדה שאלה שאין לה תשובה יציבה: "אילו directives +# שקופים?". שלושה סבבי ריוויו רצופים נפלו עליה — פעם ``.. note::``, פעם +# ``.. py:function::``, פעם ``.. raw::``, פעם ``.. default-role::``. כל +# תשובה הייתה רשימת שמות שמישהו ניחש, וכל directive חדש בסביבה הפיל +# אותה שוב. +# +# הכלל כאן מוותר על השאלה. אין קידום ל-docinfo, ולכן אין הבדל בין +# "שקוף" ל"מרנדר": בשני המקרים השדה מרונדר בעמוד, והוא ההצהרה של הכותב. +# מדלגים על **כל** explicit markup — הערה, יעד, directive, על גופו המוזח +# — וההצהרה היא רשימת השדות הראשונה שנפגשת. תוכן שאינו explicit markup +# ואינו שדה (פרוזה, רשימה, טבלה) עוצר את החיפוש, כי ממנו והלאה כבר לא +# מדובר בראש העמוד. +# +# ``Body.patterns['explicit_markup']`` ב-``docutils/parsers/rst/states.py`` +# הוא ``\.\.( +|$)`` — רווחים בלבד, לא טאב. +_EXPLICIT_MARKUP_RE = re.compile(r"^\.\.( +|$)") +_TOCTREE_ENTRY_RE = re.compile(r"^\s{3,}(\S.*)$") + +_AUTODOC_RE = re.compile(r"^\.\. auto(module|class|function)::") + + +def _read(path: Path) -> list[str]: + return path.read_text(encoding="utf-8").split("\n") + + +def _resolve(base_dir: Path, entry: str) -> Path | None: + """ערך toctree ← קובץ קיים (rst או md), או None לקישור חיצוני/חסר.""" + if entry.startswith(("http://", "https://")): + return None + # תמיכה בצורת "כותרת <נתיב>" + m = re.match(r".*<(.+)>\s*$", entry) + if m: + entry = m.group(1) + for suffix in (".rst", ".md", ""): + p = (base_dir / f"{entry}{suffix}").resolve() + if p.is_file(): + return p + return None + + +def _toctree_blocks(lines: list[str]): + """מחזיר (caption, [ערכים]) לכל בלוק toctree, בסדר הופעתם.""" + i = 0 + while i < len(lines): + if lines[i].strip() == ".. toctree::": + caption = "" + entries = [] + i += 1 + while i < len(lines): + line = lines[i] + stripped = line.strip() + if stripped.startswith(":caption:"): + caption = stripped.split(":caption:", 1)[1].strip().rstrip(":") + elif stripped.startswith(":"): + pass # אופציה אחרת (maxdepth וכו') + elif not stripped: + # שורה ריקה בתוך הבלוק מותרת רק בין האופציות לערכים + if entries: + break + elif _TOCTREE_ENTRY_RE.match(line): + entries.append(stripped) + else: + break + i += 1 + yield caption, entries + else: + i += 1 + + +def _body_start(lines: list[str]) -> int: + """האינדקס שאחרי ה-front matter, או 0 אם אין. + + לפי ``markdown_it``/MyST, front matter הוא בלוק שנפתח ב-``---`` בשורה + הראשונה ממש ונסגר ב-``---`` או ``...``. + """ + if not lines or lines[0].strip() != "---": + return 0 + for i in range(1, len(lines)): + if lines[i].strip() in ("---", "..."): + return i + 1 + return 0 # לא נסגר — MyST גם לא היה מזהה אותו כ-front matter + + +def _title(lines: list[str], path: Path) -> str: + if path.suffix == ".md": + # מדלגים על front matter לפני חיפוש הכותרת: ה-``---`` הסוגר שלו + # הוא קו-תחתון חוקי לפי ``_UNDERLINE_RE``, ולכן שורת ``summary:`` + # שמעליו נקראה ככותרת setext והכותרת של העמוד יצאה "summary: ...". + for idx, ln in enumerate(lines[_body_start(lines):], start=_body_start(lines)): + if ln.startswith("# "): + return ln[2:].strip() + if ln.strip() and idx + 1 < len(lines) and _UNDERLINE_RE.match(lines[idx + 1]): + return ln.strip() # כותרת setext: טקסט ומתחתיו ==== + return path.stem + for idx in range(len(lines) - 1): + text, under = lines[idx].strip(), lines[idx + 1] + is_heading = text and not _DIRECTIVE_RE.match(lines[idx]) and _UNDERLINE_RE.match(under) + if is_heading and len(under.strip()) >= len(text) - 2: + return text + return path.stem + + +def _declared_summary(lines: list[str], path: Path) -> str: + """התקציר שהעמוד מצהיר עליו בראשו, או מחרוזת ריקה אם אין. + + שני תחבירים, כל אחד הסטנדרטי בפורמט שלו — ולא שלישי: + + * ``.rst`` — שדה ``:summary:`` מתחת לכותרת. ב-Sphinx אין קידום + ל-```` (ראו ההסבר ליד :data:`_EXPLICIT_MARKUP_RE`), והשדה + מרונדר בדיוק במקומו: ``
`` מתחת ל-H1. + זה מה שרואים בעמוד, וזה מה שנכנס למפה. + * ``.md`` — ``summary`` ב-front matter. נקרא ב-``yaml.safe_load``, + בדיוק כמו ש-MyST קורא אותו (``myst_parser/mdit_to_docutils/base.py``: + ``data = yaml.safe_load(token.content)``). + + למה הצהרה ולא חילוץ מהגוף: הגרסה הקודמת ניסתה לזהות את פסקת הפרוזה + הראשונה, וכדי לעשות זאת נאלצה לממש חלקים מ-GFM ומ-RST ביד — טבלאות, + גדרות, תחילות בלוק. ארבעה סבבי ריוויו רצופים מצאו שם מקרי קצה, כולל + תקציר שיצא הטבלה עצמה ותקציר שיצא ריק. מי שכתב את העמוד יודע מה + התקציר; אין צורך לנחש. + """ + raw = _front_matter_summary(lines) if path.suffix == ".md" else _rst_field_summary(lines) + return _cap(raw) + + +def _cap(text: str) -> str: + """חיתוך לאורך שורת מפה. שורה ארוכה מדי מבטלת את התועלת של מפה. + + ההצהרה עצמה נשארת מלאה בעמוד; רק שורת המפה נחתכת. פונקציה נפרדת כדי + שגם ``tests/test_doc_summary_style.py`` יוכל להחיל את אותו חיתוך + כשהוא משווה את מה שהוא בודק מול מה שכתוב ב-``AI-MAP.md``. + """ + if len(text) <= SUMMARY_CAP: + return text + return text[: SUMMARY_CAP - 1].rsplit(" ", 1)[0] + "…" + + +def _front_matter_summary(lines: list[str]) -> str: + """``summary`` מתוך front matter של MyST, אם יש.""" + end = _body_start(lines) - 1 + if end < 1: + return "" # אין front matter, או שהוא לא נסגר + try: + data = yaml.safe_load("\n".join(lines[1:end])) + except yaml.YAMLError: + return "" + if not isinstance(data, dict): + return "" + value = data.get("summary") + return " ".join(str(value).split()) if value else "" + + +def _consume_indented_body(lines: list[str], i: int) -> int: + """מדלג על הגוף המוזח של explicit markup שהתחיל בשורה הקודמת. + + זה בדיוק המקום שבו כבר היה באג פעם אחת: קידום של שורה אחת נעצר על + הגוף המוזח, הכותרת לא נמצאה, והתקציר יצא ריק. + + למה רק כאן ולא גם ב-:func:`_is_autodoc_scaffold`: שם הלולאה מדלגת + ממילא על כל שורה מוזחת, בשומר ``raw[:1].isspace()`` שבראשה. קריאה + לפרימיטיב הזה משם הייתה נכונה אבל חסרת השפעה — מוטציה שביטלה אותה + לא הפילה אף בדיקה — וקוד שאי אפשר להפיל אי אפשר גם לשמור עליו. + """ + n = len(lines) + while i < n and (not lines[i].strip() or lines[i][:1].isspace()): + i += 1 + return i + + +def _skip_explicit_markup(lines: list[str], i: int) -> int: + """מדלג על שורות ריקות ועל כל explicit markup — כולל הגוף המוזח. + + הגוף המוזח הוא העיקר: directive או הערה רב-שורות נפרסים על כמה + שורות, וקידום של שורה אחת בלבד נעצר על הגוף המוזח — ואז הכותרת לא + נמצאת והתקציר יוצא ריק. + """ + n = len(lines) + while i < n: + if not lines[i].strip(): + i += 1 + continue + if not _EXPLICIT_MARKUP_RE.match(lines[i]): + return i + i = _consume_indented_body(lines, i + 1) + return i + + +def _rst_field_summary(lines: list[str]) -> str: + """שדה ``:summary:`` מרשימת השדות הראשונה שאחרי כותרת המסמך. + + ההצהרה היא מה שרואים בראש העמוד. לכן מדלגים על explicit markup — + לפני הכותרת ואחריה — ולוקחים את רשימת השדות הראשונה שנפגשת. פרוזה, + רשימה או טבלה עוצרות: ``:summary:`` שמופיע אחריהן או בתוך סעיף כבר + אינו הצהרה בראש העמוד, וחיפוש בכל הקובץ היה מציג אותו ככזה במפה. + """ + i, n = 0, len(lines) + i = _skip_explicit_markup(lines, i) + # הכותרת עצמה: טקסט + קו, או קו + טקסט + קו + if i < n and _UNDERLINE_RE.match(lines[i]): + i += 1 # overline + if i + 1 < n and lines[i].strip() and _UNDERLINE_RE.match(lines[i + 1]): + i += 2 + else: + return "" # אין כותרת מסמך — אין מיקום להצהרה + # גם **אחרי** הכותרת מדלגים: יעד, הערה או directive בין הכותרת לשדה + # אינם מזיזים את ההצהרה מראש העמוד, והקוד כאן דילג פעם רק על שורות + # ריקות — כך שהם הסתירו תקציר תקין לגמרי. + i = _skip_explicit_markup(lines, i) + summary = "" + while i < n: + line = lines[i] + if not line.strip(): + break # שורה ריקה סוגרת את רשימת השדות + if not _FIELD_RE.match(line): + break # תוכן רגיל — רשימת השדות נגמרה + m = _SUMMARY_FIELD_RE.match(line) + parts = [m.group(1)] if m else [] + i += 1 + while i < n and lines[i].strip() and lines[i][:1].isspace(): + if m: + parts.append(lines[i].strip()) + i += 1 + if m: + summary = " ".join(" ".join(parts).split()) + break + return summary + + +def _is_autodoc_scaffold(lines: list[str], path: Path) -> bool: + """עמוד שכולו הוראת autodoc — כותרת, directives, וכלום מעבר. + + הבדיקה מבנית ולא תוכנית: קודם היא שאלה "יש autodoc ואין פסקת פרוזה", + ולכן גררה את כל מנגנון חילוץ הפרוזה. עכשיו היא שואלת אם נשארה ולו + שורת תוכן אחת בעמודה 0 שאינה כותרת, קו, שדה או directive. אומת: + שתי הנוסחאות מסווגות את אותם 92 עמודים בדיוק. + """ + if not any(_AUTODOC_RE.match(ln) for ln in lines): + return False + if _declared_summary(lines, path): + # הצהרת תקציר היא תוכן שמישהו כתב, וזה בדיוק מה שהמסנן מחפש. + # בלי הכלל הזה עמוד שכל הפרוזה שלו הייתה כפילות של ההצהרה + # והוסרה — כמו docs/modules/index.rst — נשר מהמפה בשקט. + return False + i, n = 0, len(lines) + while i < n: + raw = lines[i] + stripped = raw.strip() + if not stripped or raw[:1].isspace(): + i += 1 # שורה ריקה או גוף מוזח של directive + continue + if _DIRECTIVE_RE.match(raw) or stripped == "..": + # כאן מדלגים על **כל** explicit markup (כולל ``automodule``), + # ולא רק על הצורות השקופות — זו שאלה אחרת: האם נשאר תוכן + # שנכתב ביד. הגוף המוזח נצרך ממילא בשומר שבראש הלולאה. + i += 1 + continue + if _UNDERLINE_RE.match(raw): + i += 1 # קו של כותרת + continue + if i + 1 < n and _UNDERLINE_RE.match(lines[i + 1]): + i += 2 # כותרת + קו + continue + if _FIELD_RE.match(stripped): + i += 1 # שדה הצהרה, למשל :summary: + continue + return False + return True + + +#: מתמלא בכל הרצה של :func:`build_map` — העמודים הידניים שאין להם הצהרת +#: תקציר. ``--check`` מתריע עליהם ולא מפיל: עמוד בלי תקציר עדיין מופיע +#: במפה עם הכותרת שלו, וזו הידרדרות הדרגתית ולא שבירה. +undeclared: list[str] = [] + + +def build_map() -> str: + undeclared.clear() + index = DOCS / "index.rst" + visited: set[Path] = set() + out: list[str] = [] + scaffold_count = 0 + + out.append("# מפת התיעוד לסוכני AI") + out.append("") + out.append("") + out.append("") + out.append( + "שורה לכל עמוד ידני באתר התיעוד: נתיב, כותרת, והתקציר שהעמוד " + "מצהיר עליו בראשו (`:summary:` ב-rst, `summary` ב-front matter). " + "עמוד בלי הצהרה מופיע עם הכותרת בלבד. ההיררכיה נגזרת מה-toctree. " + "עמודי פיגום של autodoc מסוננים — התוכן שלהם נוצר רק בזמן בנייה; " + "לחתימות קראו את הקוד עצמו." + ) + out.append("") + + def walk(path: Path, depth: int) -> None: + nonlocal scaffold_count + if path in visited: + return + visited.add(path) + lines = _read(path) + for caption, entries in _toctree_blocks(lines): + children = [] + for entry in entries: + child = _resolve(path.parent, entry) + if child is None or child in visited: + continue + children.append(child) + if not children: + continue + if caption and depth == 0: + out.append(f"## {caption}") + out.append("") + for child in children: + # ערך שמופיע פעמיים באותו בלוק: שניהם עוברים את הסינון של + # בניית children (אף אחד עוד לא ב-visited), והשני היה נכתב + # שוב. walk מעדכן את visited רק אחרי שהלולאה כאן כבר רצה. + if child in visited: + continue + clines = _read(child) + rel = child.relative_to(ROOT).as_posix() + if _is_autodoc_scaffold(clines, child): + # מדלגים על שורת הפיגום עצמו, אבל יורדים לילדיו: + # עמודי אינדקס של autodoc (api/handlers.rst וכד') + # מחזיקים toctree לעמודים שחלקם כן ידניים. + # לא מוסיפים ל-visited כאן — walk פותח בבדיקת visited + # והוספה מוקדמת הייתה הופכת את הירידה ל-no-op. + scaffold_count += 1 + # באותו עומק, לא depth+1: שורת הפיגום לא נכתבה, + # והילדים תופסים את מקומו — אחרת ההזחה קופצת רמה. + walk(child, depth) + continue + title = _title(clines, child) + summary = _declared_summary(clines, child) + if not summary: + undeclared.append(rel) + if summary.rstrip("…") and summary.rstrip("…") in title: + summary = "" + indent = " " * depth + line = f"{indent}- `{rel}` — **{title}**" + if summary: + line += f": {summary}" + out.append(line) + walk(child, depth + 1) + if depth == 0: + out.append("") + + walk(index, 0) + out.append("---") + out.append("") + out.append(f"עמודי פיגום autodoc שסוננו: {scaffold_count}. עמודים שנסרקו: {len(visited)}.") + out.append("") + return "\n".join(out) + + +def main() -> int: + import argparse + + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument( + "--out", type=Path, default=None, + help="נתיב לכתיבת המפה. בלי הדגל שום קובץ לא נכתב (המפה מודפסת " + "ל-stdout) — לפי מדיניות הריפו סקריפט לא כותב ב-root אלא " + "בהוראה מפורשת. ה-workflow מעביר --out AI-MAP.md בכוונה.", + ) + parser.add_argument( + "--check", type=Path, nargs="?", const=OUTPUT, default=None, + metavar="PATH", + help="לא כותב; קוד יציאה 1 אם הקובץ (ברירת מחדל: AI-MAP.md בשורש) " + "אינו תואם את מה שהיה נוצר.", + ) + args = parser.parse_args() + if args.check is not None and args.out is not None: + # קבלה שקטה של שניהם הייתה מתעלמת מהכתיבה: הקורא ביקש קובץ + # וקיבל רק השוואה, בלי שום רמז שהקובץ לא נוצר. + parser.error("אי אפשר לשלב את --check עם --out — בחרו אחד") + content = build_map() + if args.check is not None: + existing = args.check.read_text(encoding="utf-8") if args.check.exists() else None + if undeclared: + print(f"התרעה: {len(undeclared)} עמודים ידניים בלי הצהרת תקציר " + f"(:summary: ב-rst, summary ב-front matter):") + for rel in undeclared: + print(f" - {rel}") + if existing == content: + print(f"{args.check.name}: עדכני") + return 0 + print(f"{args.check.name}: אינו תואם את התיעוד הנוכחי") + return 1 + if args.out is None: + sys.stdout.write(content) + return 0 + existing = args.out.read_text(encoding="utf-8") if args.out.exists() else None + if existing == content: + print(f"{args.out.name}: ללא שינוי") + return 0 + args.out.write_text(content, encoding="utf-8") + print(f"{args.out.name}: נכתב ({len(content.splitlines())} שורות)") + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/tests/test_ai_map_freshness.py b/tests/test_ai_map_freshness.py new file mode 100644 index 000000000..869ba5037 --- /dev/null +++ b/tests/test_ai_map_freshness.py @@ -0,0 +1,93 @@ +"""אוכף ש-``AI-MAP.md`` המקומט תואם את התיעוד שבריפו. + +המפה היא תוצר נגזר: ``scripts/generate_ai_map.py`` בונה אותה מה-toctree +של Sphinx ומהפסקה הראשונה של כל עמוד. תוצר נגזר שמתעדכן בנפרד מהמקור +שלו נשאר מאחור בשקט — סוכן שקורא אותו מקבל מפה של מצב קודם ואין לו שום +דרך לדעת. + +למה בדיקה ולא אוטומציה שכותבת: ``main`` מוגן, וכל ניסיון לתת לאוטומציה +לכתוב אליו נתקל באותו קיר בצורה אחרת (git push, PR fallback, PAT, +Contents API). הבדיקה הזו מבטלת את הצורך — מי שערך את התיעוד מרענן את +המפה באותו PR, וה-CI מסרב למיזוג בלי זה. אין טוקן, אין הרשאת כתיבה, +אין מרוץ מול עדכון מקביל. + +היקף: הבדיקה רצה גם על ``pull_request`` וגם על ``push`` ל-main +(``.github/workflows/ci.yml`` מפעילה את ``unit-tests`` על שניהם, בלי +מסנן ``paths``), כך שגם עריכה ישירה של ``docs/`` מממשק הווב — שעוקפת +PR לגמרי — מסמנת את הקומיט ב-X אדום במקום להשאיר מפה ישנה בשקט. +""" + +import difflib +import subprocess +import sys +from pathlib import Path + + +ROOT = Path(__file__).resolve().parent.parent +GENERATOR = ROOT / "scripts" / "generate_ai_map.py" +MAP = ROOT / "AI-MAP.md" + +# הפקודה שמרעננת. מופיעה גם בהודעת הכשל — מי שנתקל בה צריך לדעת מה +# להריץ בלי לחפש, כי בדרך כלל הוא לא זה שכתב את הבדיקה. +REFRESH_CMD = "python3 scripts/generate_ai_map.py --out AI-MAP.md" + + +def _run(*args: str) -> subprocess.CompletedProcess: + """מריץ את המחולל כתהליך נפרד, בדיוק כמו הצרכן. + + לא ``import build_map``: הבדיקה אמורה לאמת את מה שאדם או CI מריצים + בפועל, כולל פענוח הדגלים וקוד היציאה. ייבוא ישיר היה עוקף את ה-CLI + ומשאיר את המסלול האמיתי לא בדוק. + """ + return subprocess.run( + [sys.executable, str(GENERATOR), *args], + cwd=ROOT, + capture_output=True, + text=True, + encoding="utf-8", + ) + + +def test_generator_exists() -> None: + """בלי המחולל אין למפה מקור אמת, ושאר הבדיקות כאן חסרות משמעות.""" + assert GENERATOR.is_file(), f"המחולל חסר: {GENERATOR.relative_to(ROOT)}" + + +def test_map_is_committed() -> None: + """המפה חייבת להיות בריפו — הצרכן שלה קורא את עץ הקבצים, לא רשת.""" + assert MAP.is_file(), ( + f"AI-MAP.md חסר בשורש הריפו. ליצירה: {REFRESH_CMD}" + ) + + +def test_map_matches_the_current_docs() -> None: + """המפה המקומטת זהה בייט-בבייט למה שהמחולל יוצר מהתיעוד הנוכחי.""" + check = _run("--check", "AI-MAP.md") + if check.returncode == 0: + return + + # רק במסלול הכשל: מייצרים את המפה הטרייה ל-stdout (בלי --out, כדי + # לא לכתוב כלום מתוך בדיקה) ומראים את ההפרש. בלי זה הודעת הכשל היא + # "לא תואם" בלבד, ומי שקורא אותה לא יודע מה זז. + fresh = _run() + assert fresh.returncode == 0, ( + "המחולל עצמו נכשל, ולכן אי אפשר להשוות:\n" + f"{fresh.stderr.strip() or fresh.stdout.strip()}" + ) + + current = MAP.read_text(encoding="utf-8") if MAP.exists() else "" + diff = "\n".join( + list( + difflib.unified_diff( + current.splitlines(), + fresh.stdout.splitlines(), + fromfile="AI-MAP.md (מקומט)", + tofile="AI-MAP.md (מהתיעוד הנוכחי)", + lineterm="", + ) + )[:60] + ) + raise AssertionError( + "AI-MAP.md אינו תואם את התיעוד. שינית עמוד תיעוד בלי לרענן את " + f"המפה — הרץ וקמט באותו PR:\n\n {REFRESH_CMD}\n\n{diff}" + ) diff --git a/tests/test_ai_map_generator.py b/tests/test_ai_map_generator.py new file mode 100644 index 000000000..bdf2cafca --- /dev/null +++ b/tests/test_ai_map_generator.py @@ -0,0 +1,360 @@ +"""בדיקות למחולל מפת התיעוד (scripts/generate_ai_map.py). + +מה נבדק כאן — ומה בכוונה לא: הבדיקות מוודאות שהמחולל עצמו רץ, +דטרמיניסטי, ומכסה עמודים אמיתיים. הן **לא** משוות את הפלט ל-AI-MAP.md +שבריפו; ההשוואה הזו היא בדיקה נפרדת, tests/test_ai_map_freshness.py, +כדי שכשל בה יקרא "המפה לא רועננה" ולא "המחולל שבור". + +הערה על התיאור הקודם כאן: הוא טען שהשוואה כזו הייתה מפילה כל PR שנוגע +בתיעוד, ולכן הרענון הופקד ב-GitHub Action שמקמט את המפה בעצמו. אותו +Action נמחק. main מוגן, וכל ניסיון לתת לאוטומציה לכתוב אליו נתקל באותו +קיר בצורה אחרת. הכשל האדום הוא לא מציקות — הוא בדיוק הסימן שצריך +לרענן, והרענון הוא פקודה אחת באותו PR. +""" + +import importlib.util +import sys +from pathlib import Path + +ROOT = Path(__file__).resolve().parent.parent + + +def _load_generator(): + spec = importlib.util.spec_from_file_location( + "generate_ai_map", ROOT / "scripts" / "generate_ai_map.py" + ) + mod = importlib.util.module_from_spec(spec) + sys.modules["generate_ai_map"] = mod + spec.loader.exec_module(mod) + return mod + + +def test_output_is_deterministic(): + """אותו קלט ← אותו פלט, בייט בבייט. בלי זה כל השוואה היא רעש.""" + gen = _load_generator() + assert gen.build_map() == gen.build_map() + + +def test_map_covers_known_manual_pages(): + """עמודים ידניים מרכזיים מופיעים; ההיררכיה באמת נגזרת מה-toctree.""" + content = _load_generator().build_map() + for expected in ( + "docs/workflows/save-flow.rst", + "docs/architecture.rst", + "docs/quickstart-ai.rst", + ): + assert expected in content, f"עמוד ידני חסר במפה: {expected}" + + +def test_autodoc_scaffolds_are_filtered(): + """עמוד שהוא automodule בלבד לא נכנס — הוא ריק כשקוראים מהריפו.""" + content = _load_generator().build_map() + assert "docs/api/bot_handlers.rst" not in content + assert "עמודי פיגום autodoc שסוננו" in content, ( + "שורת הסיכום נעלמה — ההשמטה חייבת להישאר גלויה" + ) + + +def test_no_timestamps_in_generator_authored_lines(): + """חותמת זמן שהמחולל מוסיף הופכת כל ריצה ל-diff. אסור שתהיה. + + נבדקות רק השורות שהמחולל מחבר בעצמו (כותרת, הערת ה"נוצר אוטומטית", + שורת הסיכום) — לא תקצירים שנשלפו מהעמודים, כי תאריך לגיטימי בפסקה + ראשונה של דף היה הופך את הבדיקה למחסום מציק על עריכת תיעוד. + """ + import re + + content = _load_generator().build_map() + authored = [ + ln for ln in content.splitlines() + if not ln.lstrip().startswith("-") # שורות ערכים מגיעות מהעמודים + ] + stamp = re.compile(r"\b20\d{2}-\d{2}-\d{2}\b|\d{2}:\d{2}:\d{2}") + hits = [ln for ln in authored if stamp.search(ln)] + assert not hits, f"חותמת זמן בשורות של המחולל: {hits}" + + +def _run_cli(*args, cwd): + """מריץ את המחולל כתהליך משנה. ``cwd`` חובה ותמיד תיקייה זמנית — + למחולל נתיבים מוחלטים, ולפי הנחיות הריפו טסט לא רץ מתוך שורש הפרויקט.""" + import subprocess + import sys as _sys + + return subprocess.run( + [_sys.executable, str(ROOT / "scripts" / "generate_ai_map.py"), *args], + capture_output=True, text=True, timeout=120, cwd=cwd, + ) + + +def test_cli_default_prints_and_writes_nothing(tmp_path): + """בלי --out: המפה ב-stdout ואף קובץ לא נכתב — מדיניות אי-כתיבה ב-root.""" + before = {f: f.stat().st_mtime_ns for f in ROOT.glob("*.md")} + proc = _run_cli(cwd=tmp_path) + assert proc.returncode == 0 + assert proc.stdout.startswith("# מפת התיעוד לסוכני AI") + after = {f: f.stat().st_mtime_ns for f in ROOT.glob("*.md")} + assert before == after, "הרצה בלי --out נגעה בקובץ בשורש" + + +def test_cli_out_writes_to_given_path(tmp_path): + out = tmp_path / "map.md" + proc = _run_cli("--out", str(out), cwd=tmp_path) + assert proc.returncode == 0 + assert out.exists() and "docs/workflows/save-flow.rst" in out.read_text(encoding="utf-8") + + +def test_cli_check_exit_codes(tmp_path): + """--check מחזיר 0 על קובץ תואם ו-1 על קובץ שסטה — בלי לכתוב כלום.""" + fresh = tmp_path / "fresh.md" + assert _run_cli("--out", str(fresh), cwd=tmp_path).returncode == 0 + assert _run_cli("--check", str(fresh), cwd=tmp_path).returncode == 0 + + stale = tmp_path / "stale.md" + stale.write_text("מפה מיושנת", encoding="utf-8") + proc = _run_cli("--check", str(stale), cwd=tmp_path) + assert proc.returncode == 1 + assert stale.read_text(encoding="utf-8") == "מפה מיושנת", "--check אסור שיכתוב" + + +def test_declared_summary_reads_an_rst_field(): + """שדה ``:summary:`` מתחת לכותרת נקרא, כולל שורות המשך מוזחות. + + המיקום הוא מה ש-``docutils`` מקדם ל-````: field list שבא + ראשון אחרי כותרת המסמך (``transforms/frontmatter.py``, ``DocInfo``). + """ + g = _load_generator() + page = ["כותרת העמוד", "===========", ":summary: התקציר המוצהר של העמוד.", "", "גוף."] + assert g._declared_summary(page, Path("x.rst")) == "התקציר המוצהר של העמוד." + + wrapped = ["כותרת העמוד", "===========", + ":summary: שורה ראשונה של התקציר", " והמשך מוזח שלה.", "", "גוף."] + assert g._declared_summary(wrapped, Path("x.rst")) == "שורה ראשונה של התקציר והמשך מוזח שלה." + + +def test_declared_summary_ignores_an_indented_field(): + """``:summary:`` מוזח אינו הצהרה — הוא תוכן של בלוק אחר. + + עמודה 0 בדיוק היא מה ש-``docutils`` מפרש כשדה ברמת המסמך; בלי הכלל + הזה שורה בתוך ``.. note::`` או בתוך בלוק קוד הייתה נחשבת תקציר. + """ + g = _load_generator() + page = ["כותרת", "=====", "", ".. note::", " :summary: לא הצהרה.", "", "גוף."] + assert g._declared_summary(page, Path("x.rst")) == "" + + +def test_declared_summary_reads_markdown_front_matter(): + """``summary`` ב-front matter נקרא ב-``yaml.safe_load``, כמו ב-MyST. + + ``myst_parser/mdit_to_docutils/base.py``: ``data = yaml.safe_load(...)``. + הערך כאן מכיל נקודתיים בכוונה — הוא חייב לעבור round-trip דרך YAML. + """ + g = _load_generator() + page = ["---", "summary: 'מטרה: להסביר משהו.'", "---", "", "# כותרת", "", "גוף."] + assert g._declared_summary(page, Path("x.md")) == "מטרה: להסביר משהו." + + +def test_declared_summary_is_empty_without_a_declaration(): + """עמוד בלי הצהרה מחזיר ריק — ואז המפה מציגה כותרת בלבד.""" + g = _load_generator() + assert g._declared_summary(["כותרת", "=====", "", "גוף."], Path("x.rst")) == "" + assert g._declared_summary(["# כותרת", "", "גוף."], Path("x.md")) == "" + assert g._declared_summary(["---", "author: פלוני", "---", "", "# כותרת"], Path("x.md")) == "" + + +def test_declared_summary_is_capped(): + """הצהרה ארוכה נחתכת בשורת המפה, ונשארת מלאה בעמוד. + + בלי החיתוך שורת מפה אחת יכולה להיות ארוכה מכל השאר יחד, וזה מבטל + את התועלת של מפה. אומת: החיתוך הוא מה שהופך את הזריעה לזהה + בייט-בייט למפה שנוצרה מחילוץ. + """ + g = _load_generator() + long = "מילה " * 200 + page = ["כותרת", "=====", f":summary: {long}", "", "גוף."] + got = g._declared_summary(page, Path("x.rst")) + assert len(got) <= g.SUMMARY_CAP, len(got) + assert got.endswith("…") + + +def test_front_matter_does_not_become_the_title(): + """ה-``---`` הסוגר של front matter אינו קו-תחתון של כותרת setext. + + רגרסיה שנתפסה במבחן הקבלה של הזריעה: ``_UNDERLINE_RE`` מתאים גם + ל-``---``, ולכן שורת ``summary:`` שמעליו נקראה ככותרת והכותרת של + העמוד יצאה ``summary: '...'``. + """ + g = _load_generator() + page = ["---", "summary: תקציר כלשהו.", "---", "", "# הכותרת האמיתית", "", "גוף."] + assert g._title(page, Path("x.md")) == "הכותרת האמיתית" + + +def test_check_warns_about_undeclared_pages_without_failing(tmp_path): + """``--check`` מתריע על עמוד ידני בלי הצהרה, ומחזיר 0. + + ההידרדרות הדרגתית היא כל הרעיון: עמוד בלי תקציר עדיין מופיע במפה + עם הכותרת שלו, ולכן אין סיבה להפיל עליו את ה-CI. + """ + # מפה טרייה ב-tmp_path, ולא AI-MAP.md שבריפו: הצמדה למפה המקומטת + # הייתה מפילה את הסוויטה הזו על "המפה לא רועננה" — כשל שכבר יש לו + # בדיקה ייעודית (test_ai_map_freshness) עם הודעה שמסבירה מה לעשות. + # כאן נבדק רק מה שהבדיקה מתיימרת לבדוק: --check מתריע ולא מפיל. + fresh = tmp_path / "fresh-map.md" + written = _run_cli("--out", str(fresh), cwd=tmp_path) + assert written.returncode == 0, written.stdout + written.stderr + + proc = _run_cli("--check", str(fresh), cwd=tmp_path) + assert proc.returncode == 0, proc.stdout + proc.stderr + assert "עדכני" in proc.stdout, proc.stdout + + g = _load_generator() + g.build_map() + if g.undeclared: + assert "התרעה:" in proc.stdout, proc.stdout + assert g.undeclared[0] in proc.stdout, proc.stdout + + +def test_summary_field_must_sit_at_the_top_of_the_page(): + """``:summary:`` אחרי פרוזה או בתוך סעיף אינו התקציר של המסמך. + + ההצהרה היא מה שרואים בראש העמוד. שדה שמופיע אחרי פסקה או בתוך סעיף + מרונדר במקומו, עמוק בעמוד, והצגתו כתקציר במפה מייצגת משהו שהקורא + לא רואה שם. + """ + g = _load_generator() + + late = ["כותרת", "=====", "", "פסקה רגילה שפותחת את העמוד.", "", + "סעיף", "-----", "", ":summary: לא התקציר של המסמך.", "", "עוד."] + assert g._declared_summary(late, Path("x.rst")) == "" + + after_blank = ["כותרת", "=====", "", "פסקה.", "", ":summary: גם לא.", ""] + assert g._declared_summary(after_blank, Path("x.rst")) == "" + + # והמיקום התקין ממשיך לעבוד, גם עם יעד לפני הכותרת ועם שדה נוסף + ok = [".. _label:", "", "כותרת", "=====", ":orphan:", + ":summary: זה כן התקציר.", "", "גוף."] + assert g._declared_summary(ok, Path("x.rst")) == "זה כן התקציר." + + +def test_a_declared_summary_means_the_page_is_not_a_scaffold(): + """עמוד עם הצהרת תקציר אינו פיגום autodoc, גם בלי פרוזה בגוף. + + רגרסיה: כשהוסרו פסקאות פתיחה שהיו כפילות של ההצהרה, ``docs/modules/index.rst`` + נשאר עם כותרות והוראות ``automodule`` בלבד — ולכן סווג כפיגום ונשר מהמפה + בשקט. הצהרה היא תוכן שמישהו כתב, וזה בדיוק מה שהמסנן אמור לחפש. + """ + g = _load_generator() + scaffold = ["מודולים", "========", "", "חלק", "----", "", + ".. automodule:: x", " :members:"] + assert g._is_autodoc_scaffold(scaffold, Path("x.rst")) is True + + declared = ["מודולים", "========", ":summary: תיעוד המודולים הראשיים.", "", + "חלק", "----", "", ".. automodule:: x", " :members:"] + assert g._is_autodoc_scaffold(declared, Path("x.rst")) is False + + +def test_multiline_directive_before_the_title_is_consumed(): + """directive רב-שורות לפני הכותרת נצרך כולו, כולל הגוף המוזח. + + רגרסיה: לולאת הדילוג קידמה שורה אחת בלבד ונעצרה על הגוף המוזח של + ``.. meta::``. מאותו רגע הכותרת לא נמצאה, ``_rst_field_summary`` + החזיר "", והעמוד הופיע במפה בלי תקציר — למרות שהוא מצהיר עליו. + """ + g = _load_generator() + page = [ + ".. meta::", + " :description: תיאור כלשהו", + " :keywords: א, ב", + "", + "כותרת העמוד", + "===========", + ":summary: התקציר המוצהר.", + "", + "גוף.", + ] + assert g._declared_summary(page, Path("x.rst")) == "התקציר המוצהר." + + +def test_markup_between_title_and_field_is_skipped(): + """יעד או הערה בין הכותרת לשדה אינם מסתירים את התקציר. + + הקוד דילג עליהם רק לפני הכותרת. אף עמוד בריפו אינו במצב הזה כרגע — + הבדיקה מונעת את הפער, לא מתקנת עמוד קיים. + """ + g = _load_generator() + target = ["כותרת", "=====", "", ".. _some-label:", "", ":summary: התקציר.", "", "גוף."] + assert g._declared_summary(target, Path("x.rst")) == "התקציר." + + comment = ["כותרת", "=====", "", ".. הערה פנימית", "", ":summary: התקציר.", "", "גוף."] + assert g._declared_summary(comment, Path("x.rst")) == "התקציר." + + +def test_every_explicit_markup_form_is_skipped_before_the_field_list(): + """כל explicit markup מדולג — בלי רשימת שמות ובלי שאלת "מי שקוף". + + זו הבדיקה שמחליפה שלוש קודמות, שכל אחת מהן שאלה על directive אחר + (``note``, ``py:function``, ``raw``, ``default-role``) אם הוא "שקוף". + השאלה נבעה ממודל ``DocInfo`` שאינו רץ ב-Sphinx: אין קידום ל-docinfo, + השדה מרונדר במקומו בכל מקרה, והוא ההצהרה של הכותב. לכן אין הבדל בין + הצורות, ורשימת שמות מנוחשת אינה נדרשת. + + ``py:function`` נשאר ברשימה כמקרה בוחן: שם directive עם ``:`` פנימי + הוא ``Inliner.simplename`` חוקי (``docutils/parsers/rst/states.py``, + שורה 673), וניסוח קודם סיווג אותו לא נכון. + """ + g = _load_generator() + + forms = ( + ".. _label:", + ".. __: https://example.com", + ".. הערה חופשית", + "..", + ".. הערה עם :: בתוכה", + ".. meta::", + ".. raw:: html", + ".. note:: שים לב", + ".. py:function:: foo(bar)", + ".. js:class:: X", + ".. default-role:: literal", + ".. role:: hl(literal)", + ".. index:: מונח", + ".. toctree::", + ) + for form in forms: + page = ["כותרת", "=====", "", form, " גוף מוזח", "", + ":summary: התקציר.", "", "גוף."] + assert g._declared_summary(page, Path("x.rst")) == "התקציר.", form + + +def test_prose_stops_the_search_for_the_declaration(): + """פרוזה עוצרת — משם והלאה זה כבר לא ראש העמוד. + + זה הגבול שמחליף את טקסונומיית הנראוּת: לא "אילו directives שקופים", + אלא "עד היכן נמשך ראש העמוד". הבדיקה נופלת אם הדילוג יורחב לכל שורה + ולא רק ל-explicit markup. + """ + g = _load_generator() + + for blocker in ("פסקת פתיחה.", "- פריט ברשימה", "| טור | טור |", "===="): + page = ["כותרת", "=====", "", blocker, "", ":summary: לא הצהרה.", ""] + assert g._declared_summary(page, Path("x.rst")) == "", blocker + + +def test_scaffold_detection_handles_a_multiline_directive_first(): + """עמוד פיגום שנפתח ב-directive רב-שורות עדיין מזוהה כפיגום.""" + g = _load_generator() + page = [".. meta::", " :description: תיאור", "", "מודולים", "========", "", + ".. automodule:: x", " :members:"] + assert g._is_autodoc_scaffold(page, Path("x.rst")) is True + + +def test_a_multiline_comment_before_the_title_does_not_hide_the_summary(): + """הגוף המוזח של הערה רב-שורות נצרך, ולכן הכותרת שאחריה נמצאת. + + זו הבדיקה שמגנה על ``_consume_indented_body``: מוטציה שמחליפה אותו + ב-``i += 1`` מפילה אותה, כי הסריקה נעצרת על שורת הגוף המוזחת, + הכותרת לא נמצאת, ו-``_rst_field_summary`` מחזיר מחרוזת ריקה. + """ + g = _load_generator() + page = [".. הערה רב-שורות", " המשך ההערה כאן", "", "כותרת", "=====", "", + ":summary: התקציר.", "", "גוף."] + assert g._declared_summary(page, Path("x.rst")) == "התקציר." diff --git a/tests/test_doc_summary_style.py b/tests/test_doc_summary_style.py new file mode 100644 index 000000000..b21a35911 --- /dev/null +++ b/tests/test_doc_summary_style.py @@ -0,0 +1,184 @@ +"""אוכף שהצהרות התקציר אינן מכילות ספירות או הבטחות יכולת. + +הרקע: שלושה סבבי ריוויו רצופים נפלו על אותו דבר — לא על פירסור, אלא על +**טענות שנכתבו בלי לאמת מול הקוד**. תקציר אמר "שבעה מסלולי API" כשהיו +תשעה; תקציר אחר אמר "דוגמאות מוכנות להרצה" כשהקוד בעמוד מכיל ``...`` +ופונקציה שאינה מוגדרת; שלישי הציג ``SearchType.SEMANTIC`` כנתמך, בעוד +``AdvancedSearchEngine.search`` נופל עבורו ל-``_text_search``. + +ספירה מתיישנת בשקט, והבטחת יכולת דורשת קריאה בקוד. תקציר אמור לתאר מה +יש בעמוד — לא כמה, ולא מה עובד. הבדיקה הזו הופכת שיפוט חוזר לכלל מכני. + +מה הבדיקה הזו **אינה** תופסת, ובכוונה — כדי שלא תיקרא כאישור גורף: + +* ספירה במילים שאינן ברשימה: "אחד", "אחת", "כמה", "מספר", "עשרות". הן + נפוצות מדי בפרוזה תקינה ("כל אחד", "פעם אחת", "מספר גרסה") מכדי לסנן + אותן בלי להפיל תקצירים נכונים. +* ספירה בספרות שאינה מלווה במילה עברית: "3 endpoints". +* טענה עובדתית שאינה ספירה ואינה הבטחת הרצה — "נתמך", "אוטומטי", + "בזמן אמת". אלה נשארים לריוויו אנושי. + +הבדיקה היא רשת לצורה שכבר נפלה כאן שלוש פעמים, לא הוכחה שהתקציר נכון. +""" + +import importlib.util +import re +import sys +from pathlib import Path + + +ROOT = Path(__file__).resolve().parent.parent +DOCS = ROOT / "docs" + +# מילות ספירה, כמילה שלמה — כולל צורת נסמך ("שלושת ה-Endpoints") +_COUNT_WORDS = ( + "שניים", "שתיים", "שני", "שתי", + "שלושה", "שלוש", "שלושת", "ארבעה", "ארבע", "ארבעת", + "חמישה", "חמש", "חמשת", "שישה", "שש", "ששת", + "שבעה", "שבע", "שבעת", "שמונה", "שמונת", + "תשעה", "תשע", "תשעת", "עשרה", "עשר", "עשרת", + "עשרים", "שלושים", "ארבעים", "חמישים", + "שישים", "שבעים", "שמונים", "תשעים", "מאה", "אלף", + "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", + "eleven", "twelve", "dozen", +) +_COUNT_RE = re.compile(r"(? dict[str, str]: + """ההצהרות כפי ש**המחולל** קורא אותן, לא לפי פרסר שני משלנו. + + הגרסה הראשונה כאן סרקה את הקובץ כולו אחרי שורה שמתחילה ב- + ``:summary: `` — עם רווח אחד בדיוק, ובכל מקום בעמוד. זה עבד, אבל זה + היה פרסר שני: כל שינוי במחולל היה מסיט את הלינט מהמפה בלי שאיש ישים + לב, ואז הבדיקה הייתה מאשרת תקציר שהמפה בכלל לא מציגה. עכשיו יש מקור + אחד — ``_rst_field_summary`` ו-``_front_matter_summary``. + + בלי ה-cap של :func:`_declared_summary`: הלינט צריך לראות את ההצהרה + המלאה, גם מעבר ל-220 התווים שנכנסים לשורת המפה. + """ + g = _load_generator() + out = {} + for path in sorted(list(docs_root.rglob("*.rst")) + list(docs_root.rglob("*.md"))): + lines = path.read_text(encoding="utf-8").split("\n") + summary = ( + g._front_matter_summary(lines) + if path.suffix == ".md" + else g._rst_field_summary(lines) + ) + if summary: + out[path.relative_to(docs_root.parent).as_posix()] = summary + return out + + +def test_there_are_summaries_to_check(): + """שומר אי-ריקנות: בלעדיו הבדיקות למטה עוברות על אוסף ריק.""" + assert len(_declared_summaries()) > 100, len(_declared_summaries()) + + +def test_the_lint_checks_the_values_that_are_in_the_committed_map(): + """מה שנבדק כאן הוא בדיוק הטקסט שכתוב ב-AI-MAP.md שבריפו. + + הגרסה הראשונה של הבדיקה הזו הייתה טאוטולוגיה: היא ייצרה מפה טרייה + ב-``build_map()`` והשוותה אותה ל-``_declared_summary()`` — אותה + פונקציה שהמפה עצמה קוראת לה. שני האגפים תמיד הסכימו, ואילו הערכים + שהלינט באמת בודק לא נבדקו כלל. אם ``_declared_summaries()`` הייתה + סוטה בשקט לתקציר אחר לאותם עמודים, הבדיקה הייתה עוברת. + + התיקון: הצד השני הוא הקובץ המקומט, לא פלט של אותו קוד; והערך + שמושווה הוא ``lint[rel]`` — מה שהבדיקות למטה באמת סורקות. החיתוך + ל-220 תווים נלקח מ-``_cap`` של המחולל ולא משוכפל כאן. + """ + g = _load_generator() + lint = _declared_summaries() + line_re = re.compile(r"^\s*- `([^`]+)` — \*\*.*?\*\*: (.+)$") + + committed = (ROOT / "AI-MAP.md").read_text(encoding="utf-8") + in_map = {} + for line in committed.split("\n"): + if m := line_re.match(line): + in_map[m.group(1)] = m.group(2) + + assert len(in_map) > 100, f"רק {len(in_map)} שורות עם תקציר ב-AI-MAP.md" + for rel, mapped in in_map.items(): + assert rel in lint, f"{rel}: מופיע במפה עם תקציר, והלינט לא רואה אותו" + assert g._cap(lint[rel]) == mapped, ( + f"{rel}: מה שהלינט בודק אינו מה שכתוב במפה\n" + f" לינט: {g._cap(lint[rel])!r}\n" + f" מפה : {mapped!r}" + ) + + +def test_the_reader_is_the_maps_reader_and_not_a_second_parser(tmp_path): + """שני עמודים שמפרידים בין הקריאה הנכונה לסריקת-קובץ נאיבית. + + הגרסה הראשונה כאן סרקה את כל הקובץ אחרי שורה שמתחילה ב- + ``:summary: ``. על שני העמודים שלמטה היא נותנת תשובה אחרת מהמפה: + + * ``late.rst`` — ``:summary:`` באמצע הגוף. סריקת-קובץ הייתה אוספת + אותו; המפה לא מציגה אותו, כי הוא אינו רשימת השדות שמתחת לכותרת. + * ``wrapped.rst`` — הצהרה שנמשכת לשורה שנייה. סריקת-קובץ הייתה + עוצרת בשורה הראשונה ובודקת חצי תקציר. + + זו הבדיקה שנופלת אם מישהו יחזיר לכאן פרסר שני. + """ + docs = tmp_path / "docs" + docs.mkdir() + (docs / "late.rst").write_text( + "כותרת\n=====\n\nפסקה בגוף.\n\n:summary: לא הצהרה.\n", encoding="utf-8" + ) + (docs / "wrapped.rst").write_text( + "כותרת\n=====\n:summary: שורה ראשונה\n והמשכה.\n\nגוף.\n", encoding="utf-8" + ) + + got = _declared_summaries(docs) + + assert "docs/late.rst" not in got, got.get("docs/late.rst") + assert got["docs/wrapped.rst"] == "שורה ראשונה והמשכה." + + +def test_no_counts_in_summaries(): + """אין ספירה בתקציר — לא במילים ולא בספרות. ספירה מתיישנת בשקט.""" + offenders = [] + for rel, summ in _declared_summaries().items(): + for rx in (_COUNT_RE, _DIGIT_COUNT_RE): + if m := rx.search(summ): + offenders.append(f"{rel}: {m.group(0)!r} ← {summ[:70]}") + assert not offenders, ( + "ספירה בתקציר. תארו מה יש בעמוד, לא כמה:\n " + "\n ".join(offenders) + ) + + +def test_no_runnability_claims_in_summaries(): + """אין הבטחה שקוד בעמוד ניתן להרצה — זו טענה שדורשת אימות.""" + offenders = [ + f"{rel}: {summ[:70]}" + for rel, summ in _declared_summaries().items() + if _CLAIM_RE.search(summ) + ] + assert not offenders, ( + "הבטחת הרצה בתקציר, בלי אימות:\n " + "\n ".join(offenders) + ) diff --git a/tests/test_docs_literalinclude_anchors.py b/tests/test_docs_literalinclude_anchors.py new file mode 100644 index 000000000..159a1322d --- /dev/null +++ b/tests/test_docs_literalinclude_anchors.py @@ -0,0 +1,137 @@ +"""אוכף מיעון עמיד של הטמעות קוד בתיעוד. + +הבאג שהבדיקות כאן מונעות: בלוקי ``literalinclude`` שמוענו לפי מספרי +שורות (``:lines:``) המשיכו להציג את הטווח הישן אחרי שהקוד זז — שמונה +מתוך עשרה בלוקים הציגו קוד לא קשור, אחד מהם במרחק 2,900 שורות מהיעד +המוצהר בכיתוב. זה דפוס ``line-number-coupling`` (amir-bug-patterns). + +שני כללים נאכפים: + +1. אין ``:lines:`` תחת ``literalinclude`` — במקומו ``:pyobject:`` לפונקציה + שלמה, או ``:start-after:``/``:end-before:`` עם הערות סימון לקטע. +2. כל סימון שהתיעוד מפנה אליו קיים בקובץ המקור **פעם אחת בדיוק** — + marker חסר מפיל את הבנייה ברעש (אזהרת docutils תחת ``-W``), אבל + marker כפול היה מרנדר את הקטע מהמופע הראשון בלי שום אזהרה. + +מה לא מכוסה כאן, בכוונה: הפניות שורה בפרוזה ("ראו ``main.py:739``"). +אלה נשארות בטריגר של ``line-number-coupling`` לקריאה אנושית. +""" + +import re +from pathlib import Path + +import pytest + + +ROOT = Path(__file__).resolve().parent.parent +DOCS = ROOT / "docs" + +# בלוק literalinclude שלם: שורת הפתיחה + כל שורות האופציות המוזחות אחריה +# ``[ \t]*`` ולא ``\s*``: עם MULTILINE, ``\s*`` בולע את שורת הריק שלפני +# הבלוק, ה-indent נלכד כ-"\n", וההפניה-לאחור דורשת שכל שורת אופציה תתחיל +# בירידת שורה — כלומר opts יוצא ריק תמיד והבדיקה עוברת על כלום. +# ובאופציות ``[ \t]+`` ולא שלושה רווחים בדיוק: RST מקבל כל הזחה עקבית, +# ובלוק עם ארבעה רווחים היה חומק מהבדיקה כולה. +# ``(?:\n|$)`` ולא ``\n``: בלוק שהאופציה האחרונה שלו היא שורת הקובץ +# האחרונה, בלי newline סופי, היה חומק מהסריקה כולה. +_BLOCK_RE = re.compile( + r"^(?P[ \t]*)\.\. literalinclude:: (?P\S+)(?:\n|$)" + r"(?P(?:(?P=indent)[ \t]+:.*(?:\n|$))*)", + re.MULTILINE, +) + + +def _blocks(root=None): + for rst in sorted((root or DOCS).rglob("*.rst")): + if "_build" in rst.parts: + continue + text = rst.read_text(encoding="utf-8") + for m in _BLOCK_RE.finditer(text): + yield rst, m.group("target"), m.group("opts") + + +def test_no_line_number_addressing(): + """אף בלוק לא ממוען לפי מספרי שורות.""" + offenders = [ + f"{rst.relative_to(ROOT)} ← {target}" + for rst, target, opts in _blocks() + if ":lines:" in opts + ] + assert not offenders, ( + "בלוקים ממוענים לפי מספרי שורות — הקוד יזוז והתיעוד יציג קוד שגוי " + "בלי אזהרה. השתמשו ב-:pyobject: לפונקציה שלמה, או בהערות סימון " + "docs:<שם>:start/end עם :start-after:/:end-before: לקטע. " + "ראו docs/doc-authoring.rst.\n" + "\n".join(offenders) + ) + + +def test_nonstandard_option_indent_is_still_caught(tmp_path): + """בלוק שהאופציות שלו מוזחות בארבעה רווחים לא חומק מהסריקה. + + רגרסיה: הגרסה הראשונה של ה-regex דרשה שלושה רווחים בדיוק, ולכן + ``:lines:`` בהזחה אחרת עבר את test_no_line_number_addressing בשקט. + """ + (tmp_path / "page.rst").write_text( + "כותרת\n======\n\n" + ".. literalinclude:: ../x.py\n" + " :language: python\n" + " :lines: 1-5\n", + encoding="utf-8", + ) + found = [(t, o) for _, t, o in _blocks(root=tmp_path)] + assert found and ":lines:" in found[0][1], ( + "בלוק בהזחת 4 רווחים לא זוהה — ה-regex התכווץ בחזרה" + ) + + +def test_block_at_eof_without_trailing_newline_is_caught(tmp_path): + """בלוק שנגמר בסוף הקובץ בלי newline לא חומק מהסריקה.""" + (tmp_path / "page.rst").write_text( + "כותרת\n======\n\n" + ".. literalinclude:: ../x.py\n" + " :lines: 1-5", # אין newline סופי בכוונה + encoding="utf-8", + ) + found = [(t, o) for _, t, o in _blocks(root=tmp_path)] + assert found and ":lines:" in found[0][1], ( + "בלוק ללא newline סופי לא זוהה" + ) + + +def _referenced_markers(): + """כל (קובץ מקור, marker) שהתיעוד מפנה אליו.""" + refs = [] + for rst, target, opts in _blocks(): + src = (rst.parent / target).resolve() + for line in opts.splitlines(): + m = re.match(r"\s*:(start-after|end-before): (.+)", line) + if m: + refs.append((rst, src, m.group(2).strip())) + return refs + + +def test_documentation_uses_anchored_sections_somewhere(): + """אם כל ה-markers ייעלמו מהתיעוד יחד עם הכלל — שהבדיקה לא תעבור על ריק.""" + assert _referenced_markers(), ( + "אין אף בלוק ממוען-סימון בתיעוד; אם זו כוונה, עדכנו גם בדיקה זו" + ) + + +@pytest.mark.parametrize( + "rst, src, marker", + [(r, s, m) for r, s, m in _referenced_markers()], + ids=[m for _, _, m in _referenced_markers()], +) +def test_every_referenced_marker_exists_exactly_once(rst, src, marker): + """ה-marker קיים בקובץ המקור, ופעם אחת בדיוק. + + חסר — הבנייה נופלת ברעש ממילא, אבל הבדיקה תופסת את זה בלי לבנות. + כפול — Sphinx היה חותך מהמופע הראשון בלי אזהרה, וזה שקט ומסוכן. + """ + assert src.exists(), f"{rst.name} מפנה לקובץ שאינו קיים: {src}" + count = src.read_text(encoding="utf-8").count(marker) + assert count == 1, ( + f"הסימון {marker!r} מופיע {count} פעמים ב-{src.name} — נדרש בדיוק " + f"אחד. חסר: הבנייה תיפול תחת -W. כפול: הבלוק ירונדר מהמופע הראשון " + f"בשקט." + )