
git blameמראה מי, מתי ומה שונה. whyso מראה למה שונה.
הבעיה
כשרוצים להבין למה שורת קוד נכתבה כך, אפשר לעשות רק דבר אחד: לבדוק git blame ולקרוא את הודעת ה-commit.
$ git blame internal/handler/page.go
a3f1b2c (parkjunwoo 2026-03-08) func CreatePage(c *gin.Context) {
מי, מתי ומה שונה — מופיע. למה שונה — לא מופיע.
אולי נכתוב את הסיבה בהודעת ה-commit? המציאות נראית כך:
fix: update handler
refactor: clean up
wip
לכתוב הודעות commit טובות זה עניין של משמעת. גם אם הצוות גיבש קונבנציה, קשה לדמיין מישהו שמתקן באג בשלוש בלילה וחושב: “עכשיו אכתוב בהקפדה את ההקשר והנימוקים להודעת ה-commit”.
אבל בעידן הקידוד עם AI — המצב שונה. סיבת השינוי כבר מתועדת.
נתוני הסשן של Claude Code
Claude Code שומר את כל השיחות כקבצי JSONL תחת ~/.claude/projects/. כל רשומה מכילה הודעות משתמש, תגובות AI, קריאות tool_use (Write, Edit, Bash) ושרשרת parentUuid שמקשרת ביניהן.
משתמש: "התחל לממש את פקודת whyso validate"
→ AI: Write internal/crosscheck/crosscheck.go
→ AI: Edit internal/crosscheck/crosscheck.go
→ AI: "יצירת חבילת crosscheck ראשונית — אימות התאמת operationId בין SSaC ל-OpenAPI"
למה הקובץ נוצר ולמה שונה — נשאר בתוך השיחה עצמה. עשיר יותר מהודעת commit, ולא צריך לכתוב אותו במכוון. אם התנהלה שיחה — הוא נרשם אוטומטית.
whyso מנתח נתונים אלה ומחלץ היסטוריית שינויים לפי קבצים.
רואים את חיי הקובץ
file: internal/crosscheck/crosscheck.go
created: 2026-03-08T14:23:01Z
history:
- timestamp: 2026-03-08T14:23:01Z
session: 09351222-d7be-41fe-994f-87c2d7067e5d
user_request: "התחל לממש את פקודת whyso validate"
answer: "יצירת חבילת crosscheck ראשונית — אימות התאמת operationId בין SSaC ל-OpenAPI"
tool: Write
- timestamp: 2026-03-09T10:15:33Z
session: 4e9b4e5e-3a50-43f2-be6e-e5db228ecc3b
user_request: "הוסף אימות שעמודת x-sort קיימת ב-DDL"
answer: "הוספת אימות צלב של עמודות x-sort/x-filter מול DDL"
tool: Edit
- timestamp: 2026-03-10T09:41:22Z
session: b2e43b4f-cb21-4286-975d-1eb9de8a16c0
user_request: "הוסף גם אימות צלב של מפרט Func"
answer: "הוספת אימות צלב של מספר ארגומנטים וסוגי ארגומנטים בין @call לבין מפרט Func"
tool: Edit
למה נוצר, באיזה בקשה ואיך התפתח — כל חיי הקובץ גלויים.
למה זה נחוץ
הפער בסקירת הקוד
ברגע שמסקרים PR ושואלים “למה נעשה שינוי זה?”, אם הסיבה לא בהודעת ה-commit — צריך לשאול את הכותב. אם הכותב לא זוכר — צריך לקרוא את הקוד מחדש ולנסות להסיק.
בסביבת קידוד עם AI, התשובה לשאלה הזו נמצאת בנתוני הסשן. whyso מוציא אותה החוצה.
Onboarding
הדרך המהירה ביותר לחבר חדש בצוות להבין את בסיס הקוד היא לדעת “למה הקוד נראה כך”. git log הוא רשימה כרונולוגית של שינויים, ותיעוד הוא תמונת מצב של המצב הנוכחי. היסטוריית הקבצים של whyso מראה את מה שביניהם — שרשרת הכוונות.
תיעוד עצמי
גם כשמפתחים לבד, מגיע רגע שלא זוכרים למה כתבנו דבר מסוים לפני שלושה חודשים. whyso משחזר את השיחה שהתנהלה בין ה-AI שלנו לבין אני-מהעבר. ההקשר שלא נכתב בהודעת ה-commit — נמצא שם.
היחס ל-git blame
whyso לא מחליף את git blame. הוא משלים אותו.
| git blame | whyso | |
|---|---|---|
| מי | O | — |
| מתי | O | O |
| מה שונה | O (ברמת שורה) | O (ברמת tool_use) |
| למה שונה | △ (הודעת commit) | O (בקשת משתמש + הסבר AI) |
| מקור הנתונים | היסטוריית git | סשן Claude Code |
אם git blame הוא ה"תיעוד הרשמי" המבוסס על commits, אז whyso הוא “יומן העבודה” המבוסס על שיחות. ההקשר שלא נכלל בתיעוד הרשמי — נשאר ביומן העבודה.
המבנה שבו AI קורא את התיעוד שלו עצמו
המקרה השימושי המעניין ביותר של whyso הוא שלא בן-אדם קורא אותו — אלא ה-AI עצמו.
Claude Code שוכח הכל בסוף כל סשן. כשפותחים את אותו פרויקט בסשן הבא, למה כתבתי כך אתמול, אילו אפשרויות נבחנו ונדחו, באיזה הקשר ביקש המשתמש — הכל נעלם. רק מנסים להסיק מתוך הקוד.
דמיינו שמוסיפים שורה אחת ל-CLAUDE.md:
לפני שינוי קובץ, הרץ בהכרח `whyso history <file>`. אם יש היסטוריה — קרא אותה לפני השינוי.
מה שורה אחת זו משנה:
יודעים אילו שינויים אסור לבטל
קראנו קובץ לפני שינוי וקוד מסוים נראה מוזר. לפי המצב הנוכחי בלבד נרצה לתקן, כי נראה כמו טעות. אבל אם היסטוריית whyso אומרת “המשתמש ביקש מפורשות מבנה זה, והסיבה אינה ביצועים אלא קריאות” — לא נגע בו.
לא מציעים מחדש אפשרויות שנדחו
בסשן הקודם התנהלה שיחה “ננסה גישה A?” → “לא, נלך עם B”. ה-AI בסשן החדש לא יודע זאת. ושוב מציע A. מטריד מאוד מנקודת המשתמש. עם whyso — יודעים כבר אילו כיוונים נבחנו ונדחו.
מחברים הקשר בין עבודות ממושכות
“תמשיך מהריפקטורינג של אתמול” — כרגע צריך להסיק מ-diff. עם היסטוריית whyso — קוראים מיד את בקשות המשתמש מסשן אתמול ואת ההיגיון של ה-AI. עבודה המשכית מבוססת עובדות, לא על הסקה.
התיעוד מצטבר בין סשנים
כשהמבנה הזה קיים, היסטוריית whyso מצטברת עם כל סשן. הסיבה לשינוי בסשן הנוכחי מועברת ל-AI של הסשן הבא. בעיית חוסר הזיכרון בין סשנים נפתרת ברמת הקובץ — ללא מערכת זיכרון נפרדת.
מה שמתועד ב-whyso הוא מה שה-AI עשה. אבל ה-AI לא זוכר זאת. התיעוד שיצר הוא הנחוץ לו ביותר. זה הנקודה הייחודית של שילוב whyso עם כלי קידוד AI.
לאנשים, whyso הוא “כלי שמשאיר אוטומטית הודעות commit טובות”. לאי, whyso הוא זיכרון שחוצה סשנים.
שימוש
התקנה
go install github.com/park-jun-woo/whyso/cmd/whyso@latest
הצגת היסטוריית קובץ
# קובץ יחיד
whyso history README.md
# כל הספרייה
whyso history internal/ --all
# פלט במראה מבנה הקבצים
whyso history . --all --output .file-histories/
# פורמט JSON
whyso history README.md --format json
רשימת סשנים
whyso sessions
איך זה עובד
מעקב אחורה בשרשרת parentUuid
כל רשומה ב-JSONL מקושרת על-ידי uuid ו-parentUuid. מה-tool_use שבו ה-AI שינה קובץ, עולים אחורה בשרשרת parentUuid ומגיעים לבקשה המקורית של המשתמש שגרמה לשינוי.
user message (uuid: A) ← "הוסף אימות שעמודת x-sort קיימת ב-DDL"
→ assistant tool_use (parentUuid: A)
→ tool_result (parentUuid: B)
→ assistant Edit (parentUuid: C) ← סיבת השינוי = A
מכיוון שמופיעות הודעות מסוג tool_result בין לבין, מחלצים רק את אלה עם type == "user" שבהן content הוא מחרוזת — וכך מוצאים את בקשת המשתמש האמיתית.
החלטות עיצוב
עוקבים רק אחר Write/Edit. tool_use של Write ו-Edit ב-Claude Code כוללים מפורשות את נתיב הקובץ ותוכן השינוי. פעולות קבצים של פקודות Bash (כמו rm, mv, cp) מזוהות באמצעות heuristics, אך Write/Edit הם יעד המעקב העיקרי. מכיוון ש-Claude Code תוכנן להשתמש ב-Write/Edit לשינוי קבצים, שני כלים אלה לבדם לוכדים את רוב השינויים.
כולל גם sub-agents. כש-Claude Code מעבד משימות מורכבות, הוא לפעמים יוצר sub-agents. סשני ה-sub-agent נשמרים תחת ספריית סשן ההורה. whyso מנתח גם סשני sub-agent ובונה היסטוריה מלאה.
עדכונים מצטברים. כשמפיקים פלט לספרייה עם --output, סשנים שכבר נותחו מדולגים. גם אם יש מאות סשנים — לא מנתחים את הכל מחדש בכל פעם.
נתונים
תוצאות מעקב תהליך הפיתוח של whyso עצמו באמצעות whyso:
| פריט | ערך |
|---|---|
| מספר סשנים | 17 |
| קריאות Write | 660 |
| קריאות Edit | 1,415 |
| פעולות קבצים ב-Bash | 206 |
| קבצים ייחודיים שהשתנו | 480 |
מ-17 סשנים חולצה היסטוריית שינויים של 480 קבצים. לכל קובץ — תיעוד של “למה נוצר ולמה שונה”.
מגבלות
- ייעודי ל-Claude Code. כלי קידוד AI אחרים שומרים נתוני סשן בפורמטים שונים. כרגע נתמך רק פורמט JSONL של Claude Code.
- עוקב רק אחר קבצי טקסט. tool_use של Write/Edit מיועד לקבצי טקסט. שינויים בתמונות וקבצים בינאריים אינם נעקבים.
- נתוני הסשן חייבים להיות מקומיים. קבצי הסשן חייבים להיות ב-
~/.claude/projects/. אם נמחקו או שהעבודה בוצעה ממחשב אחר — אותם רשומות לא קיימות.
סיכום
בעידן שבו כותבים קוד עם AI, סיבת השינוי כבר לא חייבת להיות תלויה רק בהודעת ה-commit. השיחה עצמה היא תיעוד, וממנה ניתן לחלץ אוטומטית היסטוריית שינויים לפי קבצים.
אם git blame מראה “מי, מתי ומה שונה”, אז whyso מראה “למה שונה”.