דמו / פורטפוליו בעברית וב־RTL: בונה תוכנית אימון שבועית וממיר טקסט חופשי לכרטיסייה שאפשר להריץ במצב אימון. זה לא מוצר SaaS חי, אין מנויים ואין שרת בענן בדמו הציבורי.
למי נבנה: מאמנים אישיים עצמאיים בישראל שרוצים תוכנית מותאמת (מטרה, רמה, ציוד, ימים) בלי אקסל. זה גם כלי תרגול למתאמן בודד.
דמו חי על GitHub Pages · בנה אימון · ספריית הסרטונים · ספריית תרגילים · יומן ביצוע · הצעה למאמנים · דף אחד להדפסה · ניהול מאגר · טקסט לכרטיסייה · מצב אימון
הדמו סטטי. פענוח AI ב־backend/main.py רץ רק אם מרימים localhost:8001 עם מפתח; ב־Pages הוא לא פעיל.
- מנוע אימון מפרומט (
index.html+js/prompt-parser.js+js/session-builder.js): מטרה קצרה בעברית לצד שדות מפורשים לזמן, ציוד וכמות חניכים. פרסר מבוסס-כללים בדפדפן (בלי רשת ובלי מפתח) מחלץ גם נתונים שנכתבו בטקסט, בונה אימון מהמאגר ומחלק קבוצה לתחנות. אם אין מספיק סרטונים — נאמר במפורש ומוצע הקרוב ביותר. בלי הבטחות תוצאה. - קליטת אימון קיים (
js/ingest.js): מדביקים טקסט («3 סבבים: 40 שניות פלאנק…») — מפורק לתרגילים ומותאם לסרטון במאגר, כולל שגיאות כתיב («סמיכה»=«שמיכה»). תרגיל בלי סרטון נשאר טקסט ונכנס לרשימת «סרטונים שכדאי לצלם». פירוק סרטון ארוך הוא סימון ידני של התחלה/סוף — אין זיהוי ראייה אוטומטי. - מנתח אימון (
js/analyzer.js): תרגיל בודד (שרירים, דפוס תנועה, סוג עומס, קושי) ואימון שלם (פילוח נפח, איזון דחיפה-משיכה, זמן/עצימות, גירוי, דגלי איכות). - ליבה משותפת (
js/core.js+js/catalog.json+videos/drive-catalog.json): סכימתphases,esc, אחסון,wa.me, מנוע התוכנית, וקטלוג מאוחד עם שדהsource(מקומי / דרייב / יוטיוב / קישור). כשהקטלוג טעון המנוע מעדיף קליפים אמיתיים על מאגר גנרי. חיפוש, תגיות (ילדים / זוגות / ספורט), חלופות, ולינק לקליפ בודד (#CLIP.) — בלי שם קובץ בכתובת. בדיקות:node --test(בלי תלויות) על המנוע, הקטלוג, הפרסר, המנתח, הספרייה, קוד הסיום ל־wa.me, וסכימתphases. - ספריית סרטונים (
library.html): 70 רשומות הותאמו ל־68 קובצי OneDrive אמיתיים ונארזו כווידאו H.264 ציבורי דרך GitHub Releases. שמונה רשומות ללא קובץ מסומנות כלא זמינות ואינן נבחרות לאימון. בלי רשת או במקרה שגיאה מוצגים פרטי התרגיל במקום נגן שבור. שמות קבצים לא מוצגים. - ניהול מאגר (
manage.html): הדבקת קישור דרייב / מזהה / יוטיוב → הצעת שריר/ציוד/רמה → שמירה ב־localStorage וייצוא JSON. קישור חיצוני נשמר כקישור שנפתח בחוץ — לא חיבור למאמנים ולא חיפוש ביוטיוב. - בונה שבועי (
weekly.html): מטרה משנה סטים/חזרות/מנוחה (כוח 4×4–6 / 120 שנ׳, היפרטרופיה 3×8–12 / 60 שנ׳, סיבולת 3×12–15 / 45 שנ׳). ציוד כולל גומיות/קונוסים/כדור (מה שיש בספרייה), וקהל ילדים/ספורט. תרגיל עם קליפ מסומן; אפשר להחליף לחלופה מאותה ספרייה. התחל אימון פותח את מצב האימון עם אותה סכימתphases. אימונים שנשמרו מספריית התרגילים מופיעים בראש הדף; «הצג בתוכנית השבועית» (או כתובת#reel-plan) מציב כל אימון שמור כיום בתוכנית, עם אותם כפתורי התחלה, תצוגת מתאמן, שיתוף והדפסה. - ספריית תרגילים מרילים (
exercises.html+data/exercises.json+js/reel-library.js): איחוד רשימת הרילים והמיפוי — 79 רשומות. חיפוש וסינון לפי קבוצת שריר בעברית, כרטיס עם קישור לריל, ובניית אימון (סטים וחזרות לכל תרגיל) שנשמר ב־localStorage ומוצג בבונה השבועי. הפירוט מגיע ממיפוי צפייה אוטומטי ו־verifiedהואfalseעד בדיקה מול הסרטון. «לא מצוין» מוצג כ«לא ממוין». שני רילים שאין להם מיפוי נשארים «לא ממוין». סרטוני Google Drive מ־data/drive_videos.jsonמצטרפים לאותה ספרייה ולאותו בונה. איך מוסיפים רשומה: למטה. - טקסט לכרטיסייה (
frontend/): טקסט חופשי → כרטיסייה. אם השרת המקומי נכשל, רץ פענוח כללים בדפדפן (בלי AI). אין Marketplace ואין חשבון. - מצב אימון: טיימר אחד לכל שלב, דילוג על סט בודד, חזרה שמורידה מונים. נגן: קובץ מקומי כ־
<video>, דרייב/יוטיוב כ־iframe, ובלי רשת — טקסט התרגיל. החלף מציע חלופה מאותה קבוצת שרירים. לינק#CLIP.פותח תרגיל בודד מהספרייה. - פתח כמתאמן: אותו לינק־hash בלי קוד גישה — כדי שאפשר לנסות את הזרימה בדמו. שתף אימון ללקוח עדיין דורש מסלול מאמן.
- לינק מתאמן: התוכנית ב־hash של הכתובת, בלי התחברות. בסיום — סיכום ל־
wa.meוקודTH1לייבוא. - יומן ביצוע (
journal.html): ייבוא הקוד מהוואטסאפ, רשת 28 יום, בלי לקוחות מזויפים. הצע שבוע הבא משנה סטים לפי קושי/דילוגים. תזכורת בוואטסאפ למי שבלי ביצוע מיובא. זה כלי מקומי, לא CRM שנמכר. - הצעה למאמנים (
offer.html): מסלול תוכן בלבד ב־₪59 למושב מאמן — שיתוף אימון ללקוח ודף ממותג. אין סליקה באתר; קוד גישה אחרי תשלום מחוץ לאתר. בלי קוד, כפתור «שתף אימון ללקוח» חסום. בקשת קוד: טופס Google «משוב על האפליקציות» של הבעלים, עם TrainerHub ממולא מראש (מאז 28.9) — הערך האחדCONTACTב־js/contact.js. אם מרוקנים אותו, הדף חוזר לטופס issue בעברית (ציבורי). - דף אחד להדפסה (
pitch.html) וייצוא אימון ל־PDF (workout-print.html, הדפסה מהדפדפן). גרסת תרגול נושאת סימן מים; מיתוג המאמן רק אחרי קוד. - חוברת קורס המאמנים (
booklet.html+js/booklet.js+content/booklet/): תוכן חוברות קורס המאמנים של עמותת אחריי (ספטמבר 2026) כנתונים מובנים — עקרונות האימון, 90 תרגילי חימום/מתיחות/גמישות, משחקי תופסת וכדור, שיטות לשטח מוגבל (טבטה, פירמידה, אני-אתה…), 5 אימוני פתיחה שנפתחים ישירות במצב אימון, מחשבון בוחן כושר לפי טבלאות החוברת (לא נשמר), דגשי בטיחות בחורף, חוקת כדור זוהר, ותבנית ריקה של תיק קבוצה (סקר שטח, טבלת סיכונים, תגובה לאירועים). כל פריט נושא קרדיט לקובץ המקור; בלי שמות או פרטים אישיים. - סריקת שטח (
js/site-profile.js+js/site-plan.js+js/site-scan.js+worker/site-scan/): פרופיל שטח (רוחב, משטח, מדרגות/ספסל/קיר/שיפוע, סכנות, צל) שממנו נבנה אימון מהחוברת — שיטה לשטח מוגבל כשצר, תרגילי מדרגות/ספסל/קיר כשזוהו, משחקי תופסת רק כששטח רחב, חלוקה לגלים/תחנות לפי גודל הקבוצה ושורת אזהרה לכל סכנה, עם שורת הסבר בעברית לכל בחירה. הזיהוי מהתמונות הוא רשות: בלי AI הכול עובד מהצ'קליסט הידני «מה יש בשטח?», וכל כשל (אין פרוקסי, אין מפתח, תשובה שבורה) מחזיר את המאמן לאותו צ'קליסט עם שורה בעברית. ה־AI, כשהוא מחובר, רץ מאחוריworker/site-scan/(Cloudflare Worker, תוכנית חינם) אוbackend/main.pyבפיתוח מקומי — מפתח Gemini לא נמצא במאגר ולא בדפדפן, והתמונות לא נשמרות. הפריסה והמפתח הם צעד של הבעלים: worker/site-scan/README.md. המסך עצמו הואsite-scan.html(כפתור «📷 סרוק את השטח» בדף הבית ובחוברת). - מצב פילוט (
js/pilot.js):?pilot=acharai(או קוד גישה) מפעיל פילוט לעמותת אחריי — יכולות המאמן בלי תשלום, מיתוג «עמותת אחריי» בשיתוף ובהדפסה, והעדפת התרגילים שהחוברת מלמדת כשהמנוע בוחר מהקטלוג (THPilot.builderOpts(catalog)כפרמטר שלישי ל־buildSession). משוב בסוף אימון (אימון, שטח, דירוג, מה עבד ומה לשפר) נשמר במכשיר ויוצא כ־JSON או כהודעת וואטסאפ שהמאמן שולח בעצמו — בלי טלפונים, מיילים ופרטי מתאמנים. הכול ב־localStorage, בלי שרת. מאמן שכבר יש לו מיתוג משלו שומר אותו. אין סליקה ואין וואטסאפ־שרת. קובצי הווידאו אינם נשמרים בהיסטוריית Git: גרסאות H.264 המותאמות לדפדפן מתפרסמות כנכסי release, והקטלוג שומר כתובות יציבות בלבד (ראו videos/README.md).backend/אופציונלי ולא רץ ב־Pages. אין GitHub Actions. מחקר המחיר: MONETIZATION.md. מסמכי האקתון/תמחור ישנים ב־docs/archive/.
המאגר הוא data/exercises.json. מוסיפים אובייקט אחד לסוף המערך exercises. אחר כך מריצים את הבדיקה.
קבוצות שריר מותרות, בדיוק כך: ליבה, חזה, גב, רגליים/ישבן, גוף מלא/HIIT, מוביליטי, אחר, לא ממוין. תווית מעורבת מהמיפוי (למשל «חזה ושכיבות סמיכה / גוף מלא») נכנסת ל־muscle_group הראשונה ול־secondary_group אם יש קבוצה קבועה נוספת. תיאור שאינו קבוצה (תזונה, ילדים, זריזות) נשמר ב־muscle_detail.
verified ברירת המחדל היא false. הפירוט הנוכחי הגיע ממיפוי צפייה אוטומטי ולא נבדק מול הסרטון. אחרי בדיקה מול הווידאו מותר להפוך רשומה ל־true, ובתנאי שיש לה שם ו־source_title.
איור לכרטיס: שמים קובץ ב־assets/posters/<reel_id>.png או .jpg (ה־shortcode, בלי הקידומת ig-). אם הקובץ חסר, הכרטיס והבונה מציגים מציין מקום בצבע קבוצת השריר. שדה poster דורס את הנתיב הזה כשהוא מלא. poster_uncertain: true מסמן איור שההתאמה לריל לא ודאית — הכרטיס מציג «איור לא ודאי».
equipment_tags היא רשימת תגיות מהרשימה הסטנדרטית (משקל גוף, מזרן, ספסל, קיר…). קבוצת השראה היא טיפים שאינם תרגיל (תזונה, שינה, מוטיבציה, לימפה) והם לא נכנסים לבונה. סריקת סביבה (scan.html + js/scan-match.js) בוחרת תרגילים שכל הציוד שלהם זוהה, או משקל גוף, ובונה ימים קבועים. מודל ראייה אופציונלי: TH_VISION_ENDPOINT ב־POST /api/environment-scan. בלי מפתח הדפדפן מזהה עם COCO-SSD או לפי צ'יפים.
מחרוזת סטים/חזרות שמכילה לא מצוין נשמרת כ־sets_reps: "לא ממוין", עם sets: null ו־reps: "". בלי source_title הרשומה נשארת לא ממוינת: name_he הוא ריל לא ממוין, בלי סטים, ציוד או שלבים. כך נשארו שני הרילים שאינם במיפוי (DdHOFvtKk9z, DdI_86lNFfY). המיפוי הוסיף את DeO8oVyADue (פוסט) ואת DdS9ue-knAM.
| שדה | סוג | הערה |
|---|---|---|
id |
string | ig- ועוד ה־shortcode של הריל. ייחודי. |
name_he |
string | שם בעברית, או ריל לא ממוין. |
muscle_group |
string | אחת הקבוצות למעלה. |
secondary_group |
string | קבוצות קבועות נוספות, מופרדות ב־·, או ריק. |
muscle_detail |
string | תיאור חופשי מהתווית (תזונה, ילדים…), או ריק. |
sets |
number או null | מספר שלם חיובי, או null אם לא ידוע. |
reps |
string | חזרות כפי שנמסרו (20). ריק אם לא ידוע. |
sets_reps |
string | תווית תצוגה. לא ממוין כשהמקור הוא לא מצוין. |
equipment |
string | ציוד מהמיפוי. ריק אם אין מקור. |
steps_he |
string[] | שלבי ביצוע בעברית. תרגיל מאומת: 3–5 שלבים קצרים למתאמן מתחיל. |
safety_he |
string | אופציונלי. דגש בטיחות אחד; חובה כש-verified הוא true. |
difficulty |
number או null | אופציונלי. 1 קל, 2 בינוני, 3 מתקדם; חובה כש-verified הוא true. |
alternatives |
string[] | אופציונלי. עד 2 מזהים מהספרייה מאותה muscle_group. |
source_url |
string | https://www.instagram.com/reel/<shortcode>/ או /p/<shortcode>/. |
creator |
string | שם משתמש בלי @. |
poster |
string | נתיב יחסי אופציונלי. ריק משאיר את ברירת המחדל assets/posters/<reel_id>.png (או .jpg). לא כתובת חיצונית. |
poster_uncertain |
boolean | true רק כשהאיור הותאם לריל בלי ודאות. ברירת מחדל false. |
verified |
boolean | false עד בדיקה מול הסרטון. |
source_title |
string | השם המלא מהמיפוי, או ריק. |
source_muscle_group |
string | original_group מהמיפוי, או ריק. |
source_muscle_label |
string | תווית השריר הגולמית מהמיפוי, או ריק. |
source_sets_reps |
string | הסטים/חזרות כפי שנכתבו במיפוי, או ריק. |
source_notes |
string | הערת מקור, או ריק. |
דוגמה לרשומה מהמיפוי, עדיין לא מאומתת:
{
"id": "ig-DfDEp8PRL3f",
"name_he": "4 תרגילים על ספסל: ברך שמאל/ימין, פוש-אפ מוגבה, נגיעת כתף",
"muscle_group": "ליבה",
"secondary_group": "",
"muscle_detail": "",
"sets": 3,
"reps": "20",
"sets_reps": "3x20 → 5x20 REPS",
"equipment": "ספסל שטוח צהוב-שחור ROGUE, רצפת גומי",
"steps_he": ["ברך שמאל/ימין", "פוש-אפ מוגבה", "נגיעת כתף"],
"source_url": "https://www.instagram.com/reel/DfDEp8PRL3f/",
"creator": "coachgiress38",
"poster": "",
"verified": false,
"source_title": "Bench Core Blast - 4 תרגילים על ספסל: ברך שמאל/ימין, פוש-אפ מוגבה, נגיעת כתף",
"source_muscle_group": "בטן ו-Core",
"source_muscle_label": "בטן ו-Core / ליבה",
"source_sets_reps": "3x20 → 5x20 REPS",
"source_notes": "מיפוי Meta AI, לא אומת מול הסרטון"
}דוגמה לרשומה בלי מיפוי:
{
"id": "ig-DdHOFvtKk9z",
"name_he": "ריל לא ממוין",
"muscle_group": "לא ממוין",
"secondary_group": "",
"muscle_detail": "",
"sets": null,
"reps": "",
"sets_reps": "לא ממוין",
"equipment": "",
"steps_he": [],
"source_url": "https://www.instagram.com/reel/DdHOFvtKk9z/",
"creator": "mjoepersonaltrainer",
"poster": "",
"verified": false,
"source_title": "",
"source_muscle_group": "",
"source_muscle_label": "",
"source_sets_reps": "",
"source_notes": ""
}בדיקה אחרי ההוספה:
node scripts/validate-exercises.js
python scripts/validate_exercises.py
npm testשני הסקריפטים בודקים את אותה סכימה (js/reel-library.js ו־scripts/validate_exercises.py). קובץ שלא עומד בה יוצא בקוד 1 ומדפיס את השדות השבורים. אותו ריצה בודקת גם ש־data/drive_videos.json הוא מערך תקין.
הספרייה טוענת את data/drive_videos.json בנוסף ל־79 הרילים. הקובץ הוא מערך, וכיום יש בו 93 סרטונים. מערך ריק עדיין תקין. אין המצאה של סטים, חזרות, ציוד או שלבים: הכרטיס מציג את שם הקובץ ואת הקבוצה הממופה.
כל פריט:
| שדה | סוג | הערה |
|---|---|---|
fileId |
string | מזהה הקובץ ב־Drive. נכנס לכתובת https://drive.google.com/file/d/<fileId>/preview. |
name |
string | שם הסרטון כפי שהוא ב־Drive. זה השם בכרטיס. |
folder |
string | נתיב תיקייה, למשל כושר/חזה. המיפוי משתמש בשם האחרון (חזה). |
muscleGroup |
string | בקובץ המסונכרן זה שם תיקיית Drive, לא קבוצת האפליקציה. אפשר להשאיר ריק. |
[
{ "fileId": "1a2b3c4d5e6f7g8h", "name": "פלאנק.mp4", "folder": "כושר/חזה", "muscleGroup": "חזה" }
]תיקייה מוכרת ממופה לקבוצה שכבר קיימת בספרייה. לא קשור ו־לבדיקה לא נכנסים לכרטיסים ולא לבונה.
| תיקיית Drive | קבוצה בספרייה |
|---|---|
| בטן | ליבה |
| גב | גב |
| רגליים | רגליים/ישבן |
| חזה | חזה |
| כתפיים | אחר |
| ידיים | אחר |
| גוף מלא HIIT | גוף מלא/HIIT |
| קרדיו | גוף מלא/HIIT |
| חימום | מוביליטי |
| מתיחות וגמישות | מוביליטי |
| זמן תגובה וקואורדינציה | אחר |
| זמן תגובה וקאורדינצייה | אחר |
| לא קשור | דילוג |
| לבדיקה | דילוג |
כרטיס Drive מציג את השם, את קבוצת השריר, נגן iframe עם loading="lazy" לכתובת ה־preview, וקישור «פתיחה ב-Drive» (/view). אין סטים, חזרות או שלבים עד שהרשומה מועשרת. «הוסף לאימון» מכניס אותו לבונה כמו תרגיל ריל, והסטים והחזרות נרשמים שם.
פסק דין ל־CRM: PARK. ליתד תוכן (ספרייה + בונה + שיתוף, בלי CRM): נתיב כסף צר במחיר מוצע ₪59 — לא אומת בראיונות. פירוט ב־RESEARCH.md ו־MONETIZATION.md.
- השוק הישראלי כבר מלא. AutoFit, Coach, Boostapp, Tazman ו־BaseCRM מוכרים למאמנים עברית + וואטסאפ + ניהול לקוחות, במחיר ₪0–450.
- ה־ICP שנבחר כבר מטרה שלהם. מאמן/ת עצמאי/ת בישראל עם 15–40 מתאמנים משלמים שעדיין רץ על וואטסאפ + אקסל — לא רשת ולא סטודיו עם עשרה מדריכים.
- הצעד הבא הוא 10 ראיונות, לא קוד. שיחות קצרות מקבוצת מאמני הכושר של ישראל (כ־25.7K חברים): אם מחר מפסיקים את הוואטסאפ — לאיזה כלי עוברים, וכמה מוכנים לשלם? שאלות, כללי עצירה והמשך וטבלה למילוי: docs/WTP_INTERVIEW_LOG.md.
הועלה מהמחשב של אבירן — יולי 2026. תיקוני הדמו והמיצוב — אוגוסט 2026.