1 שלב הבסיס

Headless Mode and CLI Automation — מצב ללא ממשק ואוטומציה בשורת הפקודה

עד עכשיו ניהלתם שיחה עם Claude Code — שאלתם, קיבלתם תשובה, אישרתם. בפרק הזה אתם עוברים מ-"שיחה" ל-"שירות": Claude מקבל פקודה, מריץ, מחזיר תוצאה — בלי שום ממשק, בלי אישורים, בלי בן אדם בלופ. זו השכבה שעליה נבנים כל ה-pipelines, cron jobs, ו-CI/CD workflows שנלמד בקורס הזה.

מה יהיה לכם בסוף הפרק הזה
יעדי למידה
דרישות קדם
הפרויקט שלכם

בקורס CC Power User למדתם לעבוד עם Claude Code כ-Power User — הגדרתם Hooks, יצרתם Agents ו-Skills, חיברתם MCP servers, ובניתם סביבת עבודה מתקדמת עם CLAUDE.md ו-Worktrees. בפרק הזה אתם עוברים מ-"שימוש אינטראקטיבי מתקדם" ל-"אוטומציה ללא ממשק" — תלמדו להריץ את Claude Code בלי שום בן אדם בלופ, לשלב אותו בסקריפטים, ולבנות תהליכים אוטומטיים שרצים לבד. בפרק הבא תיקחו את הכלים האלה ותטמיעו אותם ב-GitHub Actions — כדי ש-Claude יעשה code review, security audit, ויצירת release notes על כל PR באופן אוטומטי.

מילון מונחים — Headless ו-CLI Automation
מונח (English) תרגום הגדרה
Headless Mode מצב ללא ממשק הרצת Claude Code ללא ממשק אינטראקטיבי — שולחים פקודה, מקבלים תוצאה, התהליך נסגר
-p Flag (Print Mode) דגל הדפסה הדגל שמפעיל מצב Headless: claude -p "prompt" — שולח prompt, מדפיס תוצאה, יוצא
--bare Flag דגל חשוף מצב מהיר שמדלג על Hooks, LSP, Plugins ו-Skills — מיועד ל-CI/CD ואוטומציה מהירה
Exit Code קוד יציאה מספר שמחזירה תוכנית כשהיא מסיימת: 0 = הצלחה, כל דבר אחר = שגיאה. הבסיס ל-error handling בסקריפטים
stdout / stderr פלט רגיל / פלט שגיאות שני ערוצי הפלט של כל תוכנית בלינוקס — stdout לתוצאות, stderr להודעות שגיאה ו-debug
Pipeline צינור עיבוד שרשרת פקודות שכל אחת מקבלת את הפלט של הקודמת כקלט — cmd1 | cmd2 | cmd3
Batch Processing עיבוד אצווה הרצת אותה פעולה על קבוצת קבצים או נתונים — במקום אחד-אחד, הכל יחד
Cron Job משימה מתוזמנת פקודה שרצה באופן אוטומטי בזמנים קבועים — כל יום, כל שעה, כל שבוע. מנוהלת ע״י crontab
JSON Output Format פלט בפורמט JSON פלט מובנה עם שדות מוגדרים (result, cost, tokens_used) — קל לפירוק ועיבוד בקוד
Idempotency אידמפוטנטיות תכונה של פעולה שמייצרת את אותה תוצאה גם אם מריצים אותה פעמיים — קריטי לאוטומציה אמינה
apiKeyHelper סקריפט עזר למפתח סקריפט שמחזיר API key טרי בכל קריאה — לסביבות Enterprise עם key rotation
מתחיל 10 דקות מושג חינם

מ-Interactive ל-Headless — שינוי הפרדיגמה

בשלושת הקורסים הקודמים עבדתם עם Claude Code בצורה אינטראקטיבית: פתחתם טרמינל, כתבתם prompt, קראתם את התשובה, אישרתם פעולות, שאלתם שאלות המשך. זו שיחה — יש בן אדם בלופ כל הזמן. זה נהדר ללמידה, לתכנון, ולעבודה יצירתית. אבל זה לא מתאים כשצריך שהתהליך ירוץ לבד.

Headless mode (מצב ללא ממשק, נקרא גם CLI mode או Print mode) מסיר את הבן אדם מהמשוואה לחלוטין. Claude מקבל פקודה, מריץ, מייצר פלט, ויוצא. אין back-and-forth, אין אישורים, אין ממשק. זה ההבדל בין לדבר עם עובד לבין לתת לו מעטפה עם הוראות ולקבל את התוצאה מוכנה על השולחן.

למה זה כל כך חשוב? כי כל מה שתלמדו בקורס הזה — CI/CD pipelines, GitHub Actions, SDK-based agents, automated testing, scheduled monitoring — הכל מבוסס על היכולת של Claude Code לרוץ בלי בן אדם. בלי Headless mode, אין אוטומציה.

Interactive → Semi-automated → Headless → Pipeline

ספקטרום האוטומציה: Interactive = בן אדם עושה הכל. Semi-automated = בן אדם מאשר. Headless = בלי בן אדם. Pipeline = שרשרת של שלבי Headless שרצים אוטומטית. בפרק הזה אתם מטפסים מ-Headless ל-Pipeline.

המעבר המנטלי — מ-"משתמש" ל-"אדריכל"

השינוי הכי חשוב הוא לא טכני — הוא מנטלי. כש-Claude Code רץ אינטראקטיבית, אתם משתמשים שמנהלים שיחה. כש-Claude Code רץ Headless, אתם אדריכלים שמעצבים מערכות אוטומטיות. בואו נראה מה זה אומר בפועל:

מצב אינטראקטיבי מצב Headless
אתם מנסחים prompts בזמן אמת, משפרים תוך כדי אתם כותבים prompts מוכנים מראש, מדויקים, שלא משאירים מקום לפרשנות
אם Claude לא הבין — אתם מבהירים בשיחה אם Claude לא הבין — הסקריפט נכשל ואתם צריכים error handling
אתם רואים את הפלט ומחליטים מה לעשות הסקריפט מפרסר את הפלט אוטומטית ומחליט בלעדיכם
עלות = מה ששילמתם על הסשן הזה עלות = (עלות להרצה) x (מספר הרצות ביום) x 30 — צריך תקציב מתוכנן
שגיאה = Claude מבקש הבהרה שגיאה = הסקריפט קורס, cron job נכשל, אף אחד לא יודע עד שבודקים לוגים

דוגמאות מייצגות — מהעולם האמיתי

תרחיש 1: חברת SaaS ישראלית בהרצליה — 8 מפתחים. לפני Headless mode, כל מפתח היה צריך לזכור להריץ code review ידנית לפני PR. חלק שכחו. עכשיו, כל PR מפעיל אוטומטית claude -p "review this diff" --bare דרך GitHub Actions. התוצאה: 100% כיסוי review, אפס שכחות, עלות של כ-15 ש״ח ביום.

תרחיש 2: מפתח freelancer שעובד על 6 פרויקטים. כל בוקר ב-08:00, cron job רץ על כל 6 הפרויקטים ומייצר "morning briefing" — סיכום שינויים מאתמול, TODO items פתוחים, בעיות אבטחה חדשות. המפתח פותח את הבוקר עם תמונת מצב ברורה בלי לפתוח Claude אפילו פעם אחת.

תרחיש 3: צוות DevOps שמנהל 20 שרתים. כל שעה, watchdog script רץ עם claude -p ומנתח את מטריקות השרתים. אם משהו חריג — Slack alert. בחודש הראשון, המערכת תפסה דליפת זיכרון שהייתה גורמת ל-downtime תוך 12 שעות.

טעות נפוצה: לאוטמט הכל

הפיתוי הוא לאוטמט כל משימה. אבל Headless mode מתאים רק למשימות שעומדות ב-3 תנאים: (1) חוזרות — רצות לפחות פעם בשבוע, (2) מוגדרות היטב — אפשר לכתוב prompt מדויק שתמיד רלוונטי, (3) ניתנות לבדיקה — אפשר לוודא שהפלט תקין אוטומטית. דוגמה: code review אוטומטי — עומד ב-3 התנאים. תכנון ארכיטקטורה — לא, כי כל מקרה שונה ודורש שיקול דעת אנושי. Refactoring — תלוי: שינוי שמות משתנים — כן. עיצוב מחדש של API — לא.

עשו עכשיו 1 דקה

פתחו טרמינל והריצו: claude -p "what is 2+2?". שימו לב: אין ממשק אינטראקטיבי, אין "thinking", אין אישורים. Claude עונה ויוצא מיד. ברכות — הרצתם את ה-Headless הראשון שלכם.

עשו עכשיו 3 דקות

רשמו 5 משימות שאתם עושים כל שבוע עם Claude Code אינטראקטיבית. עכשיו סמנו V ליד כל משימה שעומדת ב-3 התנאים (חוזרת, מוגדרת, ניתנת לבדיקה). אלה המועמדות הראשונות לאוטומציה Headless.

מתחיל 15 דקות הקמה חינם

הדגל -p — הכניסה לעולם ה-Headless

הדגל -p (קיצור של print) הוא הכלי הבסיסי ביותר ל-Headless mode. המכניקה פשוטה: הוא שולח prompt ל-Claude, מקבל תשובה ב-stdout (ערוץ הפלט הרגיל של כל תוכנית), ומחזיר exit code (קוד יציאה שמציין הצלחה או כישלון). זה הכל. אין back-and-forth, אין שיחה, אין ממשק.

ה-prompt שאתם שולחים יכול להיות כל דבר שהייתם כותבים אינטראקטיבית — אבל ההבדל הוא שיש לכם רק הזדמנות אחת. אין "אופס, התכוונתי למשהו אחר". לכן prompts ל-Headless צריכים להיות מדויקים יותר, עם הגבלות ברורות ופורמט פלט מוגדר.

שימוש בסיסי

# שימוש בסיסי — שלח prompt, קבל תשובה
claude -p "analyze this codebase and list all TODO comments"

# לכוד את התוצאה במשתנה
RESULT=$(claude -p "summarize README.md")
echo "$RESULT"

# שמור לקובץ
claude -p "generate a .gitignore for a Node.js project" > .gitignore

# הוסף לקובץ קיים (append)
claude -p "generate 5 test cases for the login function" >> tests.md

# שילוב עם conditional logic
claude -p "run tests and report" && echo "Success" || echo "Issues found"

שימו לב למבנה: claude -p "הפרומפט שלכם". כמה נקודות חשובות:

דגלים שמשתלבים עם -p

הדגל -p לא עומד לבד — יש לו "חברים" שמרחיבים את הפונקציונליות:

דגל מה הוא עושה דוגמה מתי להשתמש
-m בוחר מודל (Sonnet, Opus, Haiku) claude -p "quick check" -m sonnet כשרוצים לחסוך בעלויות או להאיץ
-n שם לסשן — מופיע בהיסטוריה claude -p "audit" -n "nightly-audit" ב-cron jobs כדי לזהות הרצות בהיסטוריה
--append-system-prompt מוסיף הוראות מערכת בלי לשנות CLAUDE.md claude -p "review" --append-system-prompt "respond in Hebrew only" כשצריך התנהגות ספציפית להרצה מסוימת
--output-format json מחזיר JSON עם metadata (result, cost, tokens) claude -p "count bugs" --output-format json כשצריך לפרסר את התוצאה בקוד
--bare מדלג על Hooks, LSP, Plugins — מהיר יותר claude -p "fast check" --bare ב-CI/CD ובסקריפטים שרצים הרבה פעמים
-w רץ ב-Git Worktree נפרד claude -p "implement feature" -w my-feature כשרוצים שהשינויים יהיו ב-branch נפרד

Exit Codes — השפה של האוטומציה

בעולם ה-CLI, exit codes (קודי יציאה) הם הדרך שבה תוכניות מדווחות על הצלחה או כישלון. כל תוכנית שמסיימת מחזירה מספר — וזה מה שסקריפטים משתמשים בו כדי לקבל החלטות. Claude Code מחזיר:

למה זה חשוב? כי בסקריפטים אתם משתמשים ב-exit codes כדי לקבל החלטות אוטומטיות:

# אם Claude מצליח — המשך. אם נכשל — עצור והתריע
claude -p "run all tests and report results" --bare && echo "All good" || {
    echo "[ERROR] Claude failed — check API key and connectivity" >&2
    exit 1
}

# בדיקת exit code מפורשת
claude -p "validate config.json" --bare
if [ $? -ne 0 ]; then
    echo "Validation failed!"
    # שלח email, webhook, Slack message...
fi
טיפ חשוב: תמיד בדקו אינטראקטיבית קודם

לפני שאתם שמים prompt בסקריפט Headless — הריצו אותו אינטראקטיבית. פתחו claude רגיל, הקלידו את אותו prompt בדיוק, ובדקו שהתוצאה הגיונית. אם הוא לא עובד טוב בשיחה רגילה, הוא ודאי לא יעבוד ב-Headless. ההבדל הוא שבאינטראקטיבי אתם יכולים להבהיר — ב-Headless, אין הזדמנות שנייה.

עשו עכשיו 3 דקות

הריצו את הפקודה הבאה וכתבו את הפלט לקובץ: claude -p "list all files in this directory with their sizes, formatted as a markdown table" > file-report.md. עכשיו פתחו את file-report.md ובדקו — האם הפלט נקי? האם הוא markdown תקין? האם אין בו "noise" (שיחה, הקדמות, חתימות)? זו הבדיקה הבסיסית שעושים לפני ששמים prompt באוטומציה.

עשו עכשיו 2 דקות

הריצו: claude -p "say hello" -n "test-session". עכשיו בדקו את ההיסטוריה: claude --history. מצאו את הסשן בשם "test-session". ככה אתם מזהים הרצות Headless בתוך ההיסטוריה.

בינוני 10 דקות כלי חינם

הדגל --bare — מהירות מקסימלית ל-CI/CD

הדגל --bare הוכנס בגרסה 2.1.81 (מרץ 2026) ועוצב במיוחד לאוטומציה. הוא חייב לשמש יחד עם -p — אי אפשר להשתמש בו במצב אינטראקטיבי:

claude -p "your prompt here" --bare

מה הרעיון? כשאתם מריצים claude -p רגיל, Claude Code עובר תהליך initialization שלם: טוען Hooks, מפעיל Language Server, מסנכרן Plugins, סורק Skills directories, קורא/כותב Auto-Memory. כל אלה חשובים במצב אינטראקטיבי — אבל בסקריפט שרץ 100 פעמים ביום, כל אלה הם overhead מיותר.

מה --bare מדלג עליו ומה לא

רכיב בלי --bare עם --bare חיסכון זמן
Hook execution כל ה-Hooks רצים (PreToolUse, PostToolUse, SessionStart...) מדלג ~1-3 שניות
LSP (Language Server Protocol) מופעל — code intelligence, autocomplete מדלג ~1-2 שניות
Plugin sync סנכרון מלא של כל ה-plugins המותקנים מדלג ~0.5-1 שנייה
Skill directory scanning סריקת .claude/commands/ ו-.claude/agents/ מדלג ~0.5 שנייה
Auto-memory קורא/כותב MEMORY.md — לומד מהסשן מדלג
CLAUDE.md נטען עדיין נטען!

שימו לב לנקודה הקריטית: CLAUDE.md עדיין נטען גם במצב --bare. הוראות הפרויקט שלכם חלות גם באוטומציה. זה חשוב — אם הגדרתם ב-CLAUDE.md כללים כמו "always use TypeScript", "never modify the /prod directory", או "use Israeli date format" — הכללים האלה בתוקף גם ב---bare. זה by design: Anthropic רוצים שהסטנדרטים של הפרויקט שלכם ישמרו גם באוטומציה.

אימות: --bare דורש ANTHROPIC_API_KEY

הגבלה חשובה: במצב --bare, אימות OAuth/Keychain לא זמין. חייבים להשתמש באחת מהאפשרויות:

זה הגיוני — ב-CI/CD ובסקריפטים אוטומטיים, אין מי שיאשר OAuth login אינטראקטיבי.

מתי להשתמש ב---bare ומתי לא

לא כל הרצה Headless צריכה --bare. יש מקרים שבהם אתם רוצים שה-Hooks ירוצו:

טעות נפוצה: לחשוב ש---bare חוסך tokens

הדגל --bare חוסך זמן (wall-clock time), לא tokens. ה-prompt שלכם עדיין נשלח ל-API ומעובד באותה צורה — אתם משלמים אותו דבר. החיסכון הוא ב-2-5 שניות של initialization overhead. זה נשמע מעט, אבל מסתכם: 100 הרצות CI ביום x 3 שניות = 5 דקות ביום. 300 ימי עבודה = 25 שעות בשנה של המתנה מיותרת.

עשו עכשיו 2 דקות

מדדו את ההפרש: הריצו time claude -p "say hello" ואז time claude -p "say hello" --bare. רשמו את הזמנים. ההפרש הוא ה-overhead שחוסכים בכל הרצה.

בינוני 15 דקות כלי חינם

JSON Output — פלט מובנה לאוטומציה

כברירת מחדל, -p מחזיר טקסט חופשי — כמו שהייתם קוראים בשיחה אינטראקטיבית. אבל לאוטומציה אתם צריכים פלט מובנה (structured) שקוד יכול לפרסר (לפרק). טקסט חופשי הוא שביר — Claude יכול לשנות קצת את הפורמט ולשבור לכם את כל ה-parsing. JSON, לעומת זאת, הוא פורמט מובנה עם שדות מוגדרים.

כאן נכנס הדגל --output-format json:

claude -p "list all bugs in this file" --output-format json

הפלט הוא אובייקט JSON עם metadata שימושי:

{
  "result": "הטקסט של התשובה של Claude — התוכן שהייתם מקבלים בלי --output-format json",
  "tokens_used": 1247,
  "cost": 0.0037,
  "model": "claude-opus-4-6",
  "duration": 4.2
}

שימו לב: שדה result מכיל את התוכן. cost מכיל את העלות בדולרים. tokens_used מספר ה-tokens. duration זמן ההרצה בשניות. המידע הזה הוא זהב לניטור ומעקב עלויות.

פירוק JSON ב-Shell עם jq

jq הוא כלי שורת הפקודה הסטנדרטי לעיבוד JSON. אם הוא לא מותקן אצלכם: sudo apt install jq (Linux) או brew install jq (macOS).

# חלצו רק את התוצאה (הטקסט)
claude -p "summarize this code" --output-format json | jq -r '.result'

# חלצו את העלות
COST=$(claude -p "analyze main.py" --output-format json | jq '.cost')
echo "This run cost: \$$COST"

# תנאי על בסיס העלות — עצרו אם ההרצה יקרה מדי
claude -p "deep analysis" --output-format json | jq -e '.cost < 0.10' > /dev/null && echo "Within budget" || echo "OVER BUDGET!"

# חלצו את מספר ה-tokens
claude -p "review code" --output-format json | jq '.tokens_used'

פירוק JSON ב-Python

import subprocess
import json

result = subprocess.run(
    ["claude", "-p", "list all TODO comments in the project", "--output-format", "json"],
    capture_output=True, text=True, timeout=120
)

if result.returncode != 0:
    print(f"Error: {result.stderr}")
else:
    data = json.loads(result.stdout)
    print(f"Result: {data['result']}")
    print(f"Cost: ${data['cost']:.4f}")
    print(f"Tokens: {data['tokens_used']}")
    print(f"Duration: {data['duration']:.1f}s")

פירוק JSON ב-TypeScript / Node.js

import { execFile } from 'child_process';
import { promisify } from 'util';

const execFileAsync = promisify(execFile);

async function runClaude(prompt: string) {
  const { stdout } = await execFileAsync('claude', [
    '-p', prompt, '--output-format', 'json'
  ], { timeout: 120000 });

  const data = JSON.parse(stdout);
  console.log(`Result: ${data.result}`);
  console.log(`Cost: $${data.cost.toFixed(4)}`);
  return data;
}

runClaude('list TODOs in the project');

שתי שכבות JSON — הטריק החזק

טריק חשוב: גם בתוך ה-prompt, אפשר לבקש מ-Claude להחזיר JSON מובנה. ככה מקבלים שתי שכבות של מבנה — ה-wrapper JSON של --output-format json (עם cost, tokens, duration), ובתוכו JSON מובנה שאתם הגדרתם:

# שתי שכבות: wrapper JSON + תוכן JSON
claude -p "scan all .py files for security issues. Return ONLY a JSON array of objects with keys: file, line, severity, message. No explanation, just the JSON array." --output-format json | jq -r '.result' | jq '.'

# דוגמה לפלט הפנימי (שדה result):
# [
#   {"file": "auth.py", "line": 42, "severity": "critical", "message": "SQL injection risk"},
#   {"file": "api.py", "line": 87, "severity": "warning", "message": "Missing input validation"}
# ]
כשמשרשרים קריאות Claude — תמיד JSON

אם הפלט של קריאה אחת הולך להיות הקלט של קריאה אחרת (chaining), תמיד תבקשו JSON. פירסוק טקסט חופשי עם regex הוא שביר: Claude יכול להוסיף שורה ריקה, לשנות סדר, להוסיף מילות חיבור — ולשבור לכם את כל ה-regex. JSON הוא פורמט קפדני עם מבנה צפוי.

עשו עכשיו 3 דקות

הריצו: claude -p "list the 3 most common programming languages. Return ONLY a JSON array of objects with keys: name, year_created, main_use. No explanation." --output-format json | jq -r '.result'. בדקו: האם הפלט הוא JSON תקין? נסו להעביר אותו דרך jq '.' לוולידציה. אם jq נותן שגיאה — ה-prompt צריך שיפור (הוסיפו "respond ONLY with JSON, no markdown code fences").

בינוני 20 דקות תרגול חינם

Shell Scripting עם Claude Code

Claude Code משתלב בצורה טבעית בסקריפטים של bash/zsh. חשבו עליו כמו על כל כלי CLI אחר — הוא מקבל קלט (prompt + piped data), נותן פלט (stdout), ומחזיר exit code. אפשר לשרשר אותו עם כלים אחרים בדיוק כמו grep, awk, או curl.

עם הזמן זיהינו 4 דפוסים בסיסיים שמכסים כמעט כל תרחיש של שילוב Claude Code בסקריפטים. בואו נלמד כל אחד:

דפוס 1: The Validator (המאמת)

Claude בודק משהו ומחזיר verdict — pass/fail, YES/NO, OK/PROBLEM. זה הדפוס הבסיסי ביותר:

#!/bin/bash
set -euo pipefail

# בדיקת אבטחה על PR diff — אם יש בעיה, חסום את ה-deploy
DIFF=$(git diff HEAD~1)
REVIEW=$(echo "$DIFF" | claude -p "review this code diff for security vulnerabilities. If you find CRITICAL issues, start your first line with the word CRITICAL. If everything is safe, start with OK. Then explain." --bare)

FIRST_WORD=$(echo "$REVIEW" | head -1 | cut -d' ' -f1)
if [ "$FIRST_WORD" = "CRITICAL" ]; then
    echo "SECURITY ALERT: Blocking deployment!"
    echo "$REVIEW"
    exit 1
else
    echo "Security check passed."
fi

דפוס 2: The Generator (המייצר) — Claude מייצר תוכן חדש שנשמר לקובץ:

#!/bin/bash
set -euo pipefail
source ~/.claude-env.sh

# יצירת migration SQL
claude -p "generate a PostgreSQL migration SQL for adding a 'status' column (VARCHAR(20), DEFAULT 'active', NOT NULL) to the users table. Output ONLY valid SQL, no explanation, no markdown fences." --bare > migrations/002_add_status.sql

echo "Migration created: migrations/002_add_status.sql"
echo "Content:"
cat migrations/002_add_status.sql

דפוס 3: The Analyzer (המנתח) — Claude מנתח נתונים קיימים ומפיק תובנות:

#!/bin/bash
set -euo pipefail

# סיכום שינויים ל-release notes — בעברית
git log --oneline HEAD~10..HEAD | claude -p "summarize these git commits into release notes. Group by: Features (תכונות חדשות), Bug Fixes (תיקוני באגים), Improvements (שיפורים). Write in Hebrew. Use markdown format." --bare > RELEASE_NOTES.md

echo "Release notes generated!"

דפוס 4: The Decision Maker (מקבל ההחלטות) — Claude מחזיר YES/NO פשוט לתנאי בסקריפט:

#!/bin/bash
set -euo pipefail

# האם הקוד מוכן ל-deploy?
VERDICT=$(claude -p "review the test results in test-output.log. Answer ONLY the single word 'YES' or 'NO': is this safe to deploy to production?" --bare | tr -d '[:space:]')

if [ "$VERDICT" = "YES" ]; then
    echo "AI approved deployment. Proceeding..."
    ./deploy.sh
else
    echo "AI blocked deployment. Manual review required."
    exit 1
fi

Piping Data INTO Claude — הזרמת נתונים

אחד הדברים החזקים ביותר: אפשר להזרים נתונים ל-Claude דרך pipe. ככה Claude מקבל נתונים אמיתיים מהמערכת שלכם ומנתח אותם:

# ניתוח לוגים — מצא דפוסי שגיאות
cat error.log | claude -p "analyze these error logs. Group by error type, count occurrences of each, and suggest the fix for the most common error. Hebrew." --bare

# סיכום קובץ קוד
cat src/main.ts | claude -p "explain what this code does in 3 sentences. Hebrew." --bare

# ניתוח תלויות
npm ls --depth=0 2>&1 | claude -p "identify any deprecated or potentially vulnerable packages in this dependency list" --bare

# ניתוח docker containers
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | claude -p "are all containers healthy? Report any issues." --bare

שלד הסקריפט — The Script Skeleton

כל סקריפט שמשתמש ב-Claude Code ב-Headless צריך לעקוב אחרי מבנה מסודר. זה ה-skeleton שתעתיקו ותתאימו:

#!/bin/bash
set -euo pipefail  # מצב קפדני: עצור על שגיאות, משתנים לא מוגדרים, pipe failures

# ========== 1. SETUP ==========
source ~/.claude-env.sh  # טען API key ומשתני סביבה
TIMEOUT=120              # timeout בשניות
OUTPUT_DIR="./reports"
DATE=$(date +%Y%m%d-%H%M)
mkdir -p "$OUTPUT_DIR"

# ========== 2. RUN CLAUDE ==========
RESULT=$(timeout $TIMEOUT claude -p "your prompt here" --bare --output-format json 2>"$OUTPUT_DIR/stderr-$DATE.log")
EXIT_CODE=$?

# ========== 3. CHECK EXIT CODE ==========
if [ $EXIT_CODE -ne 0 ]; then
    echo "[ERROR] Claude failed with exit code $EXIT_CODE" >&2
    echo "[ERROR] stderr: $(cat "$OUTPUT_DIR/stderr-$DATE.log")" >&2
    exit 1
fi

# ========== 4. PARSE OUTPUT ==========
CONTENT=$(echo "$RESULT" | jq -r '.result')
COST=$(echo "$RESULT" | jq '.cost')

# ========== 5. ACT ON RESULT ==========
echo "$CONTENT" > "$OUTPUT_DIR/report-$DATE.md"
echo "[INFO] Report generated: $OUTPUT_DIR/report-$DATE.md"
echo "[INFO] Cost: \$$COST"
מסגרת החלטה: איזה דפוס סקריפט לבחור?
המצב שלכם הדפוס דוגמה
צריך לבדוק תנאי (pass/fail, safe/unsafe) Validator security scan, lint check, compliance verification
צריך ליצור קובץ חדש מאפס Generator SQL migrations, config files, documentation, test files, .gitignore
צריך לעבד נתונים קיימים ולהפיק תובנות Analyzer log analysis, release notes, weekly summaries, code review
צריך תשובה בינארית (כן/לא) לתנאי בסקריפט Decision Maker deploy gating, approval flows, quality thresholds
טעות נפוצה: שכחת error handling

Claude Code הוא שירות חיצוני שתלוי ברשת, ב-API, וב-rate limits. בלי error handling, הסקריפט שלכם ייתקע (timeout), יפיק תוצאות שגויות בשקט (empty output), או יקרוס ללא הודעה. שלושה דברים חובה: (1) timeout על כל קריאה, (2) בדיקת exit code, (3) redirect של stderr ללוג.

עשו עכשיו 5 דקות

צרו קובץ claude-validator.sh והעתיקו לתוכו את דפוס ה-Validator. שנו את ה-prompt כך שיבדוק קובץ README.md שלכם על שלמות (האם יש תיאור פרויקט, הוראות התקנה, דוגמאות). הריצו bash claude-validator.sh ובדקו שהפלט הגיוני. אם אין לכם README.md — בחרו קובץ אחר.

בינוני 15 דקות תרגול בתשלום

Batch Processing — עיבוד קבצים במקביל

Batch Processing (עיבוד אצווה) הוא הרצת אותה פעולה על קבוצה שלמה של קבצים. במקום להריץ Claude על כל קובץ ידנית — אתם כותבים סקריפט שעובר על כולם, אחד אחרי השני או כמה במקביל.

עיבוד סדרתי — קובץ אחרי קובץ

הגישה הפשוטה ביותר — for loop:

#!/bin/bash
source ~/.claude-env.sh

# הוספת docstrings לכל קבצי Python בתיקייה
for f in src/*.py; do
    echo "[INFO] Processing: $f"
    claude -p "add comprehensive docstrings to every function and class in this file. Keep all existing code unchanged. Return ONLY the modified file content, nothing else." --bare < "$f" > "${f}.new"

    # וולידציה בסיסית: הקובץ החדש לא ריק
    if [ -s "${f}.new" ]; then
        mv "${f}.new" "$f"
        echo "[DONE] $f — updated successfully"
    else
        rm -f "${f}.new"
        echo "[WARN] $f — empty output, skipped"
    fi
done

עיבוד מקבילי עם xargs

מהיר יותר — מריצים כמה קבצים בו-זמנית:

# 4 קבצים במקביל
find . -name "*.py" -type f | xargs -P 4 -I {} bash -c '
    echo "[INFO] Processing: {}"
    claude -p "add type hints to all function signatures in this file. Return ONLY the file content." --bare -m sonnet < "{}" > "{}.typed"
    if [ -s "{}.typed" ]; then
        mv "{}.typed" "{}"
        echo "[DONE] {}"
    else
        rm -f "{}.typed"
        echo "[WARN] {} — skipped"
    fi
'

/batch — הכלי המובנה של Claude Code

Claude Code מגיע עם skill מובנית בשם /batch שעושה batch processing ברמה אחרת לגמרי. במקום לולאה פשוטה, /batch:

מתי להשתמש ב-/batch לעומת לולאה ידנית?

תרחיש הכלי הנכון למה
הוספת docstrings ל-50 קבצים לולאה ידנית (for / xargs) כל קובץ עצמאי — אין תלויות, לא צריך תיאום
Refactoring של API שמשפיע על 20 קבצים /batch שינויים תלויים זה בזה — צריך עקביות בין קבצים
סריקת אבטחה לולאה ידנית כל קובץ נבדק בנפרד, אין תלויות
מיגרציה מ-JavaScript ל-TypeScript /batch Types צריכים להיות עקביים בין קבצים

ניהול עלויות — ה-Dry Run Pattern

עיבוד אצווה יכול לעלות כסף ברצינות. 50 קבצים x $0.05 לקובץ = $2.50 (כ-9 ש״ח). 500 קבצים = $25 (כ-90 ש״ח). הנה הדרך הנכונה:

#!/bin/bash
source ~/.claude-env.sh

# שלב 1: DRY RUN — עבדו על 3 קבצים, בדקו איכות + עלות
echo "=== DRY RUN: 3 files ==="
TOTAL_COST=0
for f in $(find src/ -name "*.ts" -type f | head -3); do
    RESULT=$(claude -p "add JSDoc to all exports" --bare --output-format json -m sonnet < "$f")
    COST=$(echo "$RESULT" | jq '.cost // 0')
    TOTAL_COST=$(echo "$TOTAL_COST + $COST" | bc)
    echo "  $f — cost: \$$COST"
done

FILE_COUNT=$(find src/ -name "*.ts" -type f | wc -l)
ESTIMATED=$(echo "$TOTAL_COST / 3 * $FILE_COUNT" | bc -l | head -c 6)
echo "Estimated total cost for $FILE_COUNT files: \$$ESTIMATED"
echo "Proceed? (y/n)"
read -r ANSWER
[ "$ANSWER" = "y" ] || exit 0

# שלב 2: FULL RUN — רק אחרי אישור
echo "=== FULL RUN ==="
# ... (הלולאה המלאה)
טעות נפוצה: Batch מקבילי ללא הגבלת Rate

אם תשלחו 100 קריאות מקביליות ל-API, תגיעו ל-rate limit תוך שניות והרצות יתחילו להיכשל. הכלל: מקסימום 4-5 קריאות מקביליות עם xargs -P 4. וגם — תמיד עשו dry run על 3 קבצים לפני ההרצה המלאה.

חיסכון: Sonnet ו-Haiku ל-Batch

לפעולות Batch שגרתיות (docstrings, type hints, formatting review), Sonnet עולה פי 5 פחות מ-Opus, ו-Haiku פי 60 פחות. למשימות שגרתיות — האיכות מספיקה. שמרו את Opus למשימות שדורשות שיקול דעת: claude -p "add docstrings" -m sonnet --bare.

עשו עכשיו 4 דקות

בחרו תיקייה עם לפחות 3 קבצי קוד. כתבו one-liner: for f in src/*.py; do echo "=== $f ==="; claude -p "summarize this file in one sentence. Hebrew." --bare -m sonnet < "$f"; done (שנו סיומת לפי השפה שלכם). הריצו ובדקו את הסיכומים.

מתחיל 10 דקות הקמה חינם

Environment Variables והגדרות

ב-Headless mode, משתני סביבה (Environment Variables) הם הדרך העיקרית להגדיר את ההתנהגות של Claude Code. אין ממשק גרפי, אין /config אינטראקטיבי — הכל דרך ENV vars. זה ההבדל בין "יישום שולחני" ל-"כלי שרת".

משתני הסביבה הקריטיים

משתנה מה הוא עושה ברירת מחדל דוגמה
ANTHROPIC_API_KEY מפתח ה-API — חובה לכל הרצה Headless ו---bare אין sk-ant-api03-...
CLAUDE_MODEL מודל ברירת מחדל (במקום -m בכל קריאה) opus 4.6 (Max) claude-sonnet-4-6
MAX_THINKING_TOKENS עומק החשיבה. נמוך = מהיר/זול, גבוה = יסודי עשרות אלפים 4096 (מהיר) או 32768 (עמוק)
CLAUDE_CODE_USE_BEDROCK ניתוב דרך AWS Bedrock false 1
CLAUDE_CODE_USE_VERTEX ניתוב דרך Google Vertex AI false 1
CLAUDE_CODE_USE_FOUNDRY ניתוב דרך Anthropic Foundry false 1

הירארכיית ההגדרות

ENV vars → settings.json (project) → settings.json (global) → defaults

משתני סביבה הם בעדיפות הגבוהה ביותר. אם settings.json מגדיר מודל מסוים, CLAUDE_MODEL=sonnet בסביבה יעקוף אותו. זה נוח — מאפשר לשנות התנהגות ב-CI בלי לגעת ב-settings.json.

קובץ .claude-env.sh — המפתח לסדר

במקום לייצא משתנים בכל סקריפט מחדש, צרו קובץ מרכזי:

#!/bin/bash
# ~/.claude-env.sh — DO NOT COMMIT TO GIT!
# הוסיפו ל-.gitignore!

export ANTHROPIC_API_KEY="sk-ant-api03-your-key-here"
export CLAUDE_MODEL="claude-sonnet-4-6"
export MAX_THINKING_TOKENS="8192"

# הגדרות ספציפיות לפרויקט (אופציונלי)
export CLAUDE_PROJECT="my-saas-app"
export CLAUDE_OUTPUT_DIR="./claude-reports"

ואז בכל סקריפט — שורה אחת:

#!/bin/bash
source ~/.claude-env.sh
# ... מכאן כל הסקריפט ...

apiKeyHelper — לסביבות Enterprise

בחברות גדולות שמחליפות מפתחות API (key rotation), אפשר להגדיר סקריפט שמחזיר מפתח טרי בכל קריאה:

// .claude/settings.json
{
  "apiKeyHelper": "/usr/local/bin/get-claude-key.sh"
}

// get-claude-key.sh — מחזיר מפתח מ-AWS SSM:
#!/bin/bash
aws ssm get-parameter --name "/claude/api-key" --with-decryption \
    --query "Parameter.Value" --output text

Claude Code קורא ל-apiKeyHelper לפני כל הרצה ומקבל מפתח עדכני. ככה אין צורך לעדכן ידנית כשהמפתח מתחלף.

טעות נפוצה: API keys ב-Git

זו כנראה הטעות הכי יקרה שמפתחים עושים. לעולם אל תעשו commit של מפתח API לריפו. מפתח Anthropic שנחשף יכול לעלות אלפי שקלים ביום אם מישהו מנצל אותו. הכללים: (1) קובץ .claude-env.sh חייב להיות ב-.gitignore, (2) ב-CI/CD השתמשו ב-GitHub Secrets או Vault, (3) אם בטעות עשיתם commit — revoke מיד ב-console.anthropic.com וצרו מפתח חדש.

עשו עכשיו 3 דקות

צרו את ~/.claude-env.sh עם ה-API key שלכם ו-CLAUDE_MODEL. הריצו: source ~/.claude-env.sh && claude -p "what model are you?" --bare. בדקו שהמודל תואם למה שהגדרתם. עכשיו ודאו ש-.claude-env.sh לא נמצא בשום repo: grep -r "claude-env" ~/.gitignore 2>/dev/null || echo "WARNING: not in .gitignore!".

בינוני 15 דקות הקמה בתשלום

Cron Jobs ותהליכים מתוזמנים

כל מה שלמדנו עד עכשיו — -p, --bare, JSON output, סקריפטים — מקבל ערך אמיתי כשהוא רץ אוטומטית, על לוח זמנים. במקום שתזכרו להריץ סריקת אבטחה כל בוקר — cron job עושה את זה בשבילכם. בכל יום, בכל שעה, בכל שבוע — אתם קובעים.

Cron — הבסיס

cron הוא scheduler מובנה בלינוקס. תחביר: minute hour day month weekday command.

# ערכו את ה-crontab
crontab -e

# סריקת אבטחה יומית ב-08:00
0 8 * * * source /home/user/.claude-env.sh && cd /home/user/myproject && claude -p "scan codebase for new security vulnerabilities" --bare > /home/user/myproject/reports/security-$(date +\%Y\%m\%d).md 2>&1

# סיכום שבועי כל יום ראשון ב-09:00
0 9 * * 0 source /home/user/.claude-env.sh && cd /home/user/myproject && git log --oneline --since="7 days ago" | claude -p "create a weekly dev summary from these commits. Hebrew." --bare > /home/user/myproject/reports/weekly-$(date +\%Y\%m\%d).md 2>&1

# בדיקת TODO items כל יום שלישי ב-10:00
0 10 * * 2 source /home/user/.claude-env.sh && cd /home/user/myproject && claude -p "find all TODO, FIXME, HACK comments in the codebase. Prioritize by urgency." --bare > /home/user/myproject/reports/todos-$(date +\%Y\%m\%d).md 2>&1

systemd Timer — האלטרנטיבה המתקדמת

systemd timers מספקים יתרונות משמעותיים על cron: לוגים מובנים (journalctl), restart policies, תלויות בין שירותים, monitoring מובנה, ותמיכה ב-persistent (אם המחשב היה כבוי בזמן שהמשימה הייתה אמורה לרוץ — היא תרוץ כשהוא יידלק).

# /etc/systemd/system/claude-audit.service
[Unit]
Description=Claude Code Nightly Audit
After=network-online.target

[Service]
Type=oneshot
User=deploy
WorkingDirectory=/home/deploy/project
EnvironmentFile=/home/deploy/.claude-env.sh
ExecStart=/usr/local/bin/claude -p "run comprehensive code quality audit. Check: security, performance, test coverage, documentation completeness. Output markdown." --bare
StandardOutput=append:/var/log/claude-audit.log
StandardError=append:/var/log/claude-audit-error.log
TimeoutStartSec=300

# /etc/systemd/system/claude-audit.timer
[Unit]
Description=Run Claude audit daily at 2am

[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true

[Install]
WantedBy=timers.target
# הפעלה ובדיקה
sudo systemctl daemon-reload
sudo systemctl enable --now claude-audit.timer
systemctl list-timers | grep claude
journalctl -u claude-audit.service --since today

דפוס ה-Watchdog — Claude כשומר מערכת

אחד הדפוסים השימושיים ביותר: Claude Code כ-"שומר" שבודק את בריאות המערכת ומתריע רק כשיש בעיה:

#!/bin/bash
# watchdog.sh — רץ כל שעה
source ~/.claude-env.sh

# אסוף מטריקות מהשרת
DISK=$(df -h / | tail -1)
DOCKER=$(docker ps --format "{{.Names}}: {{.Status}}" 2>/dev/null || echo "Docker not available")
LOAD=$(uptime)
MEMORY=$(free -m | head -2)

# שלח ל-Claude לניתוח — שימו לב: Sonnet, לא Opus (חסכון!)
ANALYSIS=$(cat <<EOF | claude -p "analyze these server metrics. If EVERYTHING is fine, respond with just the single word 'OK'. If something is concerning (disk > 85%, memory > 90%, container down, high load), explain the issue and urgency level." --bare -m sonnet
Disk: $DISK
Docker: $DOCKER
Load: $LOAD
Memory: $MEMORY
EOF
)

# התריע רק אם יש בעיה
if [ "$ANALYSIS" != "OK" ]; then
    echo "[ALERT] $(date): $ANALYSIS" >> /var/log/watchdog-alerts.log
    # Slack webhook (החליפו ב-URL שלכם)
    curl -s -X POST "https://hooks.slack.com/services/YOUR/WEBHOOK/URL" \
        -H "Content-Type: application/json" \
        -d "{\"text\": \"Server Alert:\\n$ANALYSIS\"}"
else
    echo "[OK] $(date): All systems normal" >> /var/log/watchdog.log
fi

Idempotency — תכונה קריטית לתזמון

Idempotency (אידמפוטנטיות) פירושה שהרצה של אותו תהליך פעמיים מייצרת את אותה תוצאה. למה זה קריטי ל-cron jobs?

מסגרת החלטה: Cron vs systemd Timer vs GitHub Actions Schedule
אם... השתמשו ב... למה
משימה פשוטה, שרת בודד, לא צריך לוגים מובנים Cron פשוט, כולם מכירים, עובד מהקופסה
צריך לוגים, retry, monitoring, persistent timers systemd Timer journalctl מובנה, restart on failure, dependency management
משימה קשורה לריפו (code audit, weekly summary) GitHub Actions scheduled workflow אינטגרציה טבעית, סוד ב-GitHub Secrets — נלמד בפרק הבא
משימה חד-פעמית שחוזרת בתוך סשן פתוח /loop לא צריך cron — /loop 5m check deploy status רץ בתוך הסשן
עשו עכשיו 5 דקות

צרו סקריפט daily-summary.sh שמריץ: source ~/.claude-env.sh && cd /path/to/project && git log --oneline --since="1 day ago" | claude -p "summarize today's changes. Hebrew." --bare -m sonnet > reports/daily-$(date +%Y%m%d).md. בדקו ידנית שעובד. עכשיו הוסיפו ל-crontab: (crontab -l 2>/dev/null; echo "0 18 * * 1-5 /path/to/daily-summary.sh") | crontab - — ירוץ כל יום עבודה ב-18:00.

מתקדם 10 דקות כלי בתשלום

Git Worktrees במצב Headless

בקורס הקודם למדתם להשתמש ב-Git Worktrees — עותקים נפרדים של הפרויקט שחולקים את אותו repository, כל אחד ב-branch אחר. עכשיו נשלב worktrees עם Headless mode — וזה פותח אפשרויות חדשות לגמרי.

הדגל -w (worktree) עובד יחד עם -p:

# יצירת worktree + הרצת prompt headless
claude -p "implement user authentication with JWT tokens" -w feature-auth --bare

# מה קורה בפועל:
# 1. נוצר git worktree חדש ב-.claude/worktrees/feature-auth/
# 2. נפתח branch חדש בשם feature-auth
# 3. Claude מריץ את ה-prompt בתוך ה-worktree — הקבצים שם נפרדים
# 4. השינויים נמצאים ב-branch feature-auth — לא ב-main שלכם

Pattern: מקביליות מלאה — כמה features במקביל

הכוח האמיתי: הרצת כמה worktree sessions במקביל. כל אחד עובד על feature אחר, ב-branch נפרד, בלי שום התנגשות:

#!/bin/bash
source ~/.claude-env.sh

# רשימת features לפיתוח
FEATURES=("add-search-api" "fix-pagination-bug" "update-readme" "add-dark-mode-toggle")

# הרצה מקבילית — כל feature ב-background
for feature in "${FEATURES[@]}"; do
    echo "[INFO] Starting: $feature"
    claude -p "implement $feature based on the spec in docs/specs/$feature.md. Run tests after changes." \
        -w "$feature" --bare &
done

# חכה שכל ההרצות יסיימו
wait
echo "[DONE] All features implemented in separate branches"

# בדוק את התוצאות — מה כל branch מכיל
for feature in "${FEATURES[@]}"; do
    echo "=== $feature ==="
    git -C ".claude/worktrees/$feature" log --oneline -3
    git -C ".claude/worktrees/$feature" diff --stat HEAD~1 2>/dev/null || echo "  (no changes)"
done

Worktrees ב-CI/CD — הדפוס הנפוץ

הדפוס הנפוץ ביותר ל-worktrees ב-Headless הוא ב-CI/CD pipelines שבהם כמה משימות צריכות לרוץ על אותו repo במקביל בלי להפריע אחת לשנייה. לדוגמה: pipeline שמריץ code review, security scan, ו-test generation במקביל — כל אחד ב-worktree נפרד:

#!/bin/bash
source ~/.claude-env.sh

# שלושה agents במקביל, כל אחד ב-worktree נפרד
claude -p "review code for bugs and style issues" -w review-agent --bare &
claude -p "scan for security vulnerabilities" -w security-agent --bare &
claude -p "generate unit tests for uncovered functions" -w test-agent --bare &

# חכה לכולם
wait

# איחוד תוצאות
echo "=== Code Review ===" > combined-report.md
git -C .claude/worktrees/review-agent show HEAD:review.md >> combined-report.md 2>/dev/null
echo -e "\n=== Security Scan ===" >> combined-report.md
git -C .claude/worktrees/security-agent show HEAD:security.md >> combined-report.md 2>/dev/null
echo -e "\n=== Test Generation ===" >> combined-report.md
git -C .claude/worktrees/test-agent show HEAD:tests.md >> combined-report.md 2>/dev/null

היתרון: כל agent עובד בסביבה מבודדת לחלוטין. אם agent אחד עושה שינויים בקבצים — זה לא משפיע על האחרים. בלי worktrees, הרצה מקבילית הייתה גורמת להתנגשויות בקבצים.

Sparse Checkout — למונוריפוס גדולים

אם יש לכם monorepo עם מאות אלפי קבצים, כל worktree לא צריך את כולם. ההגדרה worktree.sparsePaths מאפשרת checkout חלקי — רק הקבצים הרלוונטיים:

// .claude/settings.json
{
  "worktree": {
    "sparsePaths": ["packages/api/", "shared/types/", "package.json", "tsconfig.json"]
  }
}

ניקוי Worktrees

Worktrees תופסים מקום בדיסק. אחרי שסיימתם — נקו:

# ראו worktrees קיימים
git worktree list

# מחקו worktree ספציפי
git worktree remove .claude/worktrees/feature-auth

# ניקוי אוטומטי של worktrees שה-branch שלהם נמחק
git worktree prune
Worktrees + --bare = מקביליות מקסימלית

שלבו -w עם --bare: claude -p "..." -w feat --bare. ככה מדלגים על initialization overhead בכל worktree. אם 4 worktrees רצים במקביל, חוסכים ~12-20 שניות סה״כ.

עשו עכשיו 3 דקות

הריצו: claude -p "create a simple hello world function in index.js" -w test-worktree --bare. אחרי שסיים, בדקו: git worktree list. עכשיו נקו: git worktree remove .claude/worktrees/test-worktree 2>/dev/null; git worktree prune.

בינוני 15 דקות כלי חינם

Debugging של הרצות Headless

כשהרצה Headless מייצרת פלט לא צפוי — או לא מייצרת פלט בכלל — אתם צריכים כלי debugging. בלי ממשק אינטראקטיבי זה קצת יותר מאתגר, אבל יש שיטה מסודרת.

The Headless Debug Ladder — 6 שלבי Debugging

תמיד תעבדו מהבדיקה הפשוטה ביותר למורכבת ביותר. כל שלב מצמצם את מרחב החיפוש:

6 שלבי Debug Ladder
  1. בדקו Exit Code: claude -p "..." --bare; echo "Exit: $?"
    אם לא 0 — יש בעיה בסיסית (API key, network, rate limit). אם 0 — Claude רץ בהצלחה אבל הפלט לא מה שציפיתם
  2. בדקו stderr: claude -p "..." --bare 2>debug.log; cat debug.log
    הודעות שגיאה מפורטות הולכות ל-stderr — זה המקום הראשון למצוא מה השתבש
  3. הריצו עם --verbose: claude -p "..." --verbose 2>verbose.log
    מוסיף לוגים מפורטים: אילו כלים Claude קרא, כמה זמן כל שלב לקח, אילו החלטות נלקחו
  4. בדקו אותו prompt אינטראקטיבית: פתחו claude רגיל, הקלידו את אותו prompt — מה קורה? האם Claude מבקש הבהרה? האם התוצאה שונה?
  5. בדקו CLAUDE.md: האם הוראות ב-CLAUDE.md סותרות את ה-prompt? האם הקובץ נמצא בנתיב שבו אתם מריצים? (cron jobs רצים מ-HOME, לא מתיקיית הפרויקט)
  6. בדקו API key ו-rate limits: האם המפתח תקין? האם הגעתם ל-rate limit? בדקו: echo $ANTHROPIC_API_KEY | head -c 20 ובדקו ב-console.anthropic.com את השימוש

כשלים נפוצים ב-Headless — הטבלה

תסמין סיבה אפשרית פתרון
פלט ריק לגמרי API key חסר, לא תקין, או שפג תוקפו בדקו echo $ANTHROPIC_API_KEY, חדשו ב-console.anthropic.com
תשובה לא רלוונטית Prompt עמום או חסר הקשר הוסיפו הקשר, הגבלות, דוגמה לפלט רצוי
Exit code 1 ללא stderr שגיאת רשת או rate limit בדקו חיבור, המתינו 60 שניות, נסו שוב
Claude "שוכח" הוראות מ-CLAUDE.md ה-cwd (ספריית העבודה) לא מצביע על הפרויקט הוסיפו cd /path/to/project בסקריפט לפני הקריאה
Timeout — ההרצה לא מסתיימת Prompt מורכב מדי, מודל איטי, או context ענק שנו ל-Sonnet (-m sonnet), קצרו prompt, הורידו MAX_THINKING_TOKENS
תוצאות שונות בכל הרצה Claude הוא non-deterministic — תוצאות משתנות הוסיפו שכבת validation שבודקת את הפורמט, לא את התוכן המדויק

תרחיש Debug מהעולם האמיתי — "למה ה-Cron Job שלי מחזיר שטויות?"

בואו נעבור על תרחיש debugging אמיתי שכל מתחיל נתקל בו. הסיפור: הגדרתם cron job שרץ כל בוקר ומייצר סיכום שינויים. במחשב שלכם הסקריפט עובד מצוין — אבל מ-cron, הפלט ריק או לא רלוונטי.

שלב 1 — בדיקת Exit Code: מוסיפים לוג ל-cron entry:

0 8 * * * /home/user/summary.sh >> /tmp/cron-debug.log 2>&1; echo "EXIT: $?" >> /tmp/cron-debug.log

פותחים את /tmp/cron-debug.log — ורואים EXIT: 0. Claude רץ בהצלחה, אבל הפלט לא מה שציפיתם.

שלב 2 — בדיקת stderr: בודקים את השורות לפני ה-exit code. מגלים: warning: not a git repository.

שלב 3 — הבנת הבעיה: Cron jobs רצים מ-HOME כברירת מחדל, לא מתיקיית הפרויקט! הסקריפט שלכם לא עושה cd לפרויקט. Claude רץ מ-HOME, לא מוצא git repo, ומחזיר תשובה גנרית.

התיקון:

#!/bin/bash
source ~/.claude-env.sh
cd /home/user/myproject || exit 1   # <-- השורה שהייתה חסרה!
git log --oneline --since="1 day ago" | claude -p "summarize these changes. Hebrew." --bare

הלקח: תמיד הוסיפו cd /path/to/project || exit 1 בתחילת כל סקריפט שרץ מ-cron. זו טעות קלאסית שהולכת ונפתרת רק אחרי שקוראים את ה-logs.

הכלי /debug — Post-Mortem אינטראקטיבי

אם הרצה Headless נכשלה ואתם לא מבינים למה — פתחו סשן אינטראקטיבי והריצו את ה-skill המובנית /debug:

# אחרי הרצה headless שנכשלה:
claude
> /debug
# Claude ינתח את ה-debug logs של הסשן הקודם ויסביר מה השתבש

מה /debug עושה מאחורי הקלעים? הוא קורא את קבצי ה-debug log של הסשן האחרון (נמצאים ב-~/.claude/debug/), מנתח את רצף הכלים שהופעלו, מזהה היכן התהליך "נתקע" או "סטה", ומציג הסבר ברור עם הצעת תיקון. חשבו עליו כ-"post-mortem אוטומטי" — במקום שתקראו מאות שורות של logs, Claude עושה את זה בשבילכם.

Pattern: Prompt Test Suite

לפני ששמים prompt באוטומציה שרצה כל יום, בנו "test suite" שמוודא שהפלט תקין:

#!/bin/bash
# test-prompts.sh — הריצו לפני כל deployment של אוטומציה חדשה
source ~/.claude-env.sh
PASS=0; FAIL=0

# Test 1: פלט לא ריק
RESULT=$(claude -p "say hello" --bare 2>/dev/null)
[ -n "$RESULT" ] && { PASS=$((PASS+1)); echo "PASS: Non-empty output"; } || { FAIL=$((FAIL+1)); echo "FAIL: Empty output"; }

# Test 2: JSON output parseable
RESULT=$(claude -p "return the JSON object {\"status\": \"ok\"}" --output-format json 2>/dev/null)
echo "$RESULT" | jq '.' > /dev/null 2>&1 && { PASS=$((PASS+1)); echo "PASS: JSON parseable"; } || { FAIL=$((FAIL+1)); echo "FAIL: Invalid JSON"; }

# Test 3: Exit code 0
claude -p "echo test" --bare > /dev/null 2>&1 && { PASS=$((PASS+1)); echo "PASS: Exit code 0"; } || { FAIL=$((FAIL+1)); echo "FAIL: Non-zero exit"; }

# Test 4: --bare mode works
claude -p "hello" --bare > /dev/null 2>&1 && { PASS=$((PASS+1)); echo "PASS: --bare mode"; } || { FAIL=$((FAIL+1)); echo "FAIL: --bare mode"; }

echo ""
echo "Results: $PASS passed, $FAIL failed out of $((PASS + FAIL))"
[ $FAIL -eq 0 ] && echo "All tests passed!" || echo "Some tests failed — check before deploying."
עשו עכשיו 2 דקות

הריצו: claude -p "say hello" --bare 2>stderr.log; echo "Exit: $?"; cat stderr.log. עכשיו הריצו עם API key לא תקין: ANTHROPIC_API_KEY="invalid" claude -p "say hello" --bare 2>stderr-fail.log; echo "Exit: $?"; cat stderr-fail.log. השוו — ככה תבינו את ההבדל בין הרצה מוצלחת לכושלת.

עשו עכשיו 3 דקות

העתיקו את ה-Prompt Test Suite מלמעלה לקובץ test-prompts.sh והריצו אותו. כל 4 הטסטים צריכים לעבור. אם טסט נכשל — השתמשו ב-Debug Ladder כדי לזהות את הבעיה.

שגרת עבודה — Headless שוטף
תדירות משימה פירוט
יומי בדקו לוגים של הרצות Headless ודאו שה-cron jobs רצו בהצלחה, ש-exit codes הם 0, ושהעלויות בטווח הצפוי. בדקו stderr logs לשגיאות שקטות
יומי עיינו בפלט הסיכום היומי אם הגדרתם daily summary — קראו אותו. 2 דקות קריאה שחוסכות 20 דקות עבודה ידנית
שבועי בדקו עלויות מצטברות סכמו costs מהרצות Headless. השתמשו ב---output-format json | jq '.cost' כדי לעקוב. ודאו שאתם בתקציב
שבועי שפרו prompts לפי תוצאות אם פלט של prompt מסוים לא עקבי — שפרו: הוסיפו הגבלות, דוגמאות, או שנו מודל
שבועי נקו worktrees ישנים git worktree listgit worktree prune. מחקו worktrees שסיימתם
חודשי סקירת ארכיטקטורת האוטומציה האם יש cron jobs לא רלוונטיים? משימות חדשות שכדאי לאוטמט? עלויות שאפשר לחסוך?
חודשי עדכון גרסת Claude Code + test suite עדכנו (npm update -g @anthropic-ai/claude-code), הריצו test-prompts.sh, ודאו שהכל עובד
בינוני 75 דקות תרגול בתשלום

תרגילים מעשיים

תרגיל 1: סקריפט Code Review אוטומטי 20 דקות

בנו סקריפט שמריץ code review אוטומטי על כל קובץ שהשתנה:

  1. צרו קובץ auto-review.sh עם set -euo pipefail ו-source ~/.claude-env.sh
  2. השתמשו ב-git diff --name-only HEAD~1 כדי לקבל רשימת קבצים שהשתנו
  3. לכל קובץ, הריצו claude -p עם prompt שבודק: (א) באגים אפשריים, (ב) בעיות אבטחה, (ג) הצעות שיפור
  4. שמרו את הביקורת לקובץ review-YYYYMMDD.md בתיקיית reports
  5. הוסיפו error handling: timeout (120 שניות), בדיקת exit code, log של stderr
  6. הוסיפו מעקב עלויות עם --output-format json | jq '.cost' — סכמו עלות כוללת

תוצאה צפויה: סקריפט שמריץ bash auto-review.sh ומפיק קובץ review מפורט + שורת סיכום עם עלות כוללת.

תרגיל 2: Batch Documentation Generator 25 דקות

בנו מערכת שמייצרת תיעוד אוטומטי לכל הקבצים בפרויקט:

  1. צרו קובץ batch-docs.sh עם setup מלא (env, error handling)
  2. מצאו את כל קבצי הקוד: find . -name "*.ts" -o -name "*.py" -o -name "*.js" | grep -v node_modules
  3. עשו dry run על 3 קבצים: בדקו איכות + עלות. הציגו עלות משוערת לכל הקבצים
  4. לכל קובץ, הריצו Claude (עם -m sonnet) שמייצר: תיאור, רשימת פונקציות, דוגמאות שימוש
  5. השתמשו ב-xargs -P 3 לעיבוד מקבילי (3 קבצים בו-זמנית)
  6. שמרו תיעוד בתיקיית docs/auto/ וצרו INDEX.md עם לינקים

תוצאה צפויה: תיקיית docs/auto/ עם תיעוד לכל קובץ + INDEX.md + דוח עלויות.

תרגיל 3: Watchdog עם התראות ולוגים 30 דקות

בנו מערכת ניטור שרצה כל שעה ומתריעה על חריגות:

  1. צרו watchdog.sh עם setup מלא
  2. אספו מטריקות: df -h, uptime, free -m, docker ps (אם רלוונטי)
  3. שלחו ל-Claude עם prompt: "analyze and report ONLY if concerning. If fine, just 'OK'"
  4. אם יש בעיה — כתבו alert לקובץ log. בונוס: שלחו ל-Slack webhook
  5. הוסיפו לוגים: כל הרצה נרשמת עם timestamp, גם OK וגם alerts
  6. הגדירו cron: 0 * * * * /path/to/watchdog.sh (כל שעה)
  7. הוסיפו --dry-run mode: bash watchdog.sh --dry-run שמדפיס מטריקות בלי Claude

תוצאה צפויה: watchdog.sh שרץ כל שעה, שקט כשהכל בסדר, מתריע כשיש בעיה.

אם אתם עושים רק דבר אחד מהפרק הזה

צרו את הקובץ ~/.claude-env.sh עם ה-API key שלכם, ואז כתבו סקריפט של 5 שורות שמריץ claude -p על משהו שימושי בפרויקט שלכם — סיכום שינויים, סריקת באגים, או יצירת תיעוד. הריצו אותו פעם אחת וודאו שהפלט הגיוני. אם יש לכם סקריפט אחד עובד שמשתמש ב-Claude Code Headless — יש לכם את הבסיס לכל האוטומציות שנלמד בקורס הזה.

בדקו את עצמכם — 5 שאלות (4/5 = עובר)
  1. למה Headless mode דורש prompts מדויקים יותר מאשר מצב אינטראקטיבי? (רמז: חשבו על מה קורה כש-Claude לא מבין — מה ההבדל בין שני המצבים?)
  2. מה ההבדל בין -p ל---bare, ולמה לא תמיד משתמשים ב---bare? (רמז: מה --bare מדלג עליו? באילו מצבים אתם דווקא רוצים שה-Hooks ירוצו?)
  3. למה idempotency קריטית במיוחד ל-cron jobs שמשתמשים ב-Claude Code? (רמז: Claude הוא non-deterministic — מה המשמעות של הרצה כפולה?)
  4. מתי תשתמשו ב-/batch ומתי בלולאת for — ומה הסיכון של כל גישה? (רמז: חשבו על תלויות בין קבצים — מתי שינוי בקובץ אחד חייב להיות עקבי עם אחר?)
  5. מה 3 השלבים הראשונים ב-Debug Ladder ולמה הסדר חשוב? (רמז: כל שלב מצמצם את מרחב החיפוש — exit code → stderr → verbose)
סיכום הפרק

בפרק הזה עברתם את המעבר המנטלי הכי חשוב בקורס: מ-"משתמש שמנהל שיחה" ל-"אדריכל שמעצב מערכות אוטומטיות". גיליתם שהדגל -p הוא השער לעולם ה-Headless, שבו Claude Code הופך מ-chatbot לרכיב CLI שמקבל קלט, מייצר פלט, ויוצא — בדיוק כמו grep, curl, או כל כלי שורת פקודה אחר. למדתם את ארבעת דפוסי הסקריפטים — Validator, Generator, Analyzer, Decision Maker — שמכסים כמעט כל תרחיש של שילוב Claude בתהליכים אוטומטיים. בניתם תשתית מסודרת של Environment Variables, batch processing עם ניהול עלויות, ו-cron jobs עם monitoring. התובנה המרכזית שמחברת הכל: Claude Code ב-Headless הוא לא "chatbot שרץ ברקע" — הוא רכיב בארכיטקטורה, עם כניסות מוגדרות, יציאות מוגדרות, error handling, ותקציב. מי שמתייחס אליו ככה בונה אוטומציות אמינות. מי שמתייחס אליו כמו לשיחה — מתאכזב.

בפרק הבא נעבור ל-GitHub Actions ו-CI/CD — ניקח את כל מה שלמדנו על Headless mode ונטמיע אותו בתוך pipeline אוטומטי שרץ על כל PR: code review חכם, security audit, יצירת release notes, ותיעוד — הכל בלי שתצטרכו להרים אצבע.

צ׳קליסט סיום — Headless Mode and CLI Automation