SSD Nodes Learn 🎉 VPS החל מ־$5.50/חודש
מדריכים Matt Connorמאת Matt Connor · עודכן 2026-08-13

איך להריץ OpenTag בשרת עצמאי עבור סוכני תכנות

למדו כיצד להטמיע את OpenTag על גבי VPS כדי לנהל אזכורי @ ב-Slack וב-GitHub. המדריך כולל הגדרות TLS ingress, אימות חתימות webhook, ניהול הרשאות token וקונפיגורציה מאובטחת.

מה OpenTag עושה כאשר מציינים סוכן

OpenTag הופך אזכור (mention) בפורמט @ בשרשור Slack או ב-issue ב-GitHub להרצה של סוכן תכנות על מכונה שבבעלותכם. כאשר מישהו מגיב @opentag investigate this ב-issue, מאזין מקבל את אירוע הפלטפורמה, בודק את החתימה שלו, מתאים את האזכור לפרויקט משויך, מפעיל סוכן תכנות מול עותק מקומי של הקוד, ומפרסם את התוצאה בחזרה באותו השרשור.

הפרויקט מופץ תחת רישיון MIT וזמין בכתובת amplifthq/opentag. נכון לאוגוסט 2026, הגרסה האחרונה ששוחררה היא v0.9.0, שפורסמה ב-28 ביולי 2026, והיא מופצת כחבילת npm. לא קיימת תמונת container רשמית, לכן הגרסה שאתם מצמידים (pin) היא גרסת ה-npm. כל פקודה להלן מצמידה אותה.

זה הופך לפרויקט VPS ולא לפרויקט למחשב נייד בגלל הצד של GitHub.‏ GitHub מעבירה אירועי מאגר (repository events) על ידי ביצוע בקשת HTTP לכתובת URL שאתם רושמים פעם אחת, לכן ה-URL הזה חייב להשיב באותה הכתובת גם מחר.

ארבעת הרכיבים הפעילים

המאזין (listener) מקבל אירועי פלטפורמה, כאשר לכל פלטפורמה יש אירועים משלה. המאזין של GitHub הוא נקודת קצה HTTP בפורט 3050 בנתיב /github/webhooks. המאזין של Slack Events API פועל בפורט 3040 בנתיב /slack/events. Slack יכול לעבוד גם ב-Socket Mode, שבו היישום פותח WebSocket יוצא ואינו זקוק כלל לפורט נכנס.

הנתב (dispatcher) הוא המתאם. הוא מאזין כברירת מחדל בפורט 3030, שומר את מצב ההרצה בקובץ מסד נתונים מקומי המוגדר על ידי OPENTAG_DATABASE_PATH, ומתעד נתיב ביקורת (audit trail) עבור כל הרצה. שום גורם מחוץ למערכת לא אמור להגיע לפורט זה.

המריץ (runner) הוא ה-daemon המקומי. הוא מבצע polling למשימות, תובע בעלות על הרצה, מחזיק ב-lease עבורה, ושולח heartbeat בכל 15 שניות כברירת מחדל כל עוד ההרצה פעילה. הוא מסרב לכל הרצה שנתבעה אם יעד הפרויקט חסר או נמצא מחוץ ל-allowlist בהגדרות שלו; זו הבדיקה שמונעת מאירוע GitHub להפנות את הסוכן שלך למאגר שלא קישרת מעולם.

המוציא לפועל (executor) הוא סוכן הקידוד עצמו. OpenTag מפעיל אותו באמצעות ACP (פרוטוקול לקוח-סוכן), פרוטוקול JSON-RPC המתבצע דרך קלט ופלט סטנדרטיים, כך שהסוכן רץ כתהליך בן בתוך תיקיית עבודה ש-OpenTag מקצה לו. שמות מובנים כוללים את echo, codex, claude-code, cursor, opencode, hermes ו-openclaw. התחילו עם echo, המוציא לפועל שמגיע עם הגדרות הדוגמה, כיוון שהוא מוכיח שהנתיב כולו תקין לפני שמודל כלשהו נוגע בקוד שלכם.

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

מדוע מחשב נייד ומנהרה אינם מספיקים

מדריך ההגדרה של GitHub מנחה אתכם להריץ את ngrok http 3050 ולהדביק את מארח המנהרה (tunnel host) בתוך ה-webhook של המאגר. זה עובד בעשר הדקות הראשונות. מארח מנהרה חינמי משתנה בכל פעם שהתהליך עובר אתחול, והוא מפסיק להתקיים כאשר המחשב הנייד עובר למצב שינה. GitHub שומרת את כתובת ה-payload URL הישנה וממשיכה לנסות אותה, לכן לשונית ה-Recent Deliveries בהגדרות ה-webhook מתמלאת בכישלונות בעוד השרשור נותר דומם. איש אינו מבחין בכך במשך שבוע, כיוון ש-webhook שאינו עושה דבר נראה בדיוק כמו בוט שאף אחד לא הזכיר.

שרת VPS פותר את שני הדברים שנשברים. שם ה-DNS אינו משתנה, לכן ה-payload URL שהדבקתם פעם אחת נשאר תקין. המכונה אינה נכנסת למצב שינה, כך שתגובה בשעה 02:00 מקבלת מענה. הגדירו את השרת כראוי תחילה: עשר הדקות הראשונות ב-VPS חדש מכסה את משתמש ההתחברות ואת ה-firewall שמדריך זה מניח את קיומם.

Slack הוא היוצא מן הכלל. במצב Socket Mode הוא מתחבר החוצה ואינו זקוק לכתובת URL ציבורית, לכן פריסה של Slack בלבד יכולה להישאר סגורה. ל-GitHub אין שירות מקביל. ה-webhooks של המאגר הם מסוג HTTP נכנס, מה שאומר נקודת קצה ציבורית, וזה מחייב TLS (אבטחת שכבת תעבורה) ובדיקת חתימה.

אירוח עצמי של OpenTag על Ubuntu מגרסה נעולה

OpenTag בגרסה v0.9.0 דורש Node.js 22 ומעלה. Ubuntu 24.04 מספקת את Node 18 במאגרים שלה, לכן יש להתקין מתוך NodeSource.

curl -fsSL https://deb.nodesource.com/setup_22.x -o nodesource_setup.sh
sudo -E bash nodesource_setup.sh
sudo apt install -y nodejs
node -v

הפקודה node -v חייבת להדפיס v22 או גרסה גבוהה יותר. ב-Node 20 ההתקנה מציגה אזהרת EBADENGINE וה-CLI עלול להיכשל ברגע ההפעלה.

הקצו לשירות חשבון משתמש ייעודי. הסוכן רץ בהרשאות של משתמש זה, לכן הוא לא אמור להיות המשתמש שלכם ולא משתמש root. המדריך משתמשים בעלי הרשאות מינימליות ב-VPS מסביר מדוע הפרדה זו מצדיקה את הצעד הנוסף.

sudo adduser --disabled-password --gecos "" opentag
sudo loginctl enable-linger opentag
sudo npm install -g @opentag/cli@0.9.0
command -v opentag

הפקודה command -v opentag אמורה להדפיס נתיב כגון /usr/bin/opentag. הגדרת ה-linger קריטית ב-Linux: OpenTag מתקין את שירות הרקע שלו דרך systemd, ושירות משתמש ללא linger ייעצר ברגע שתסגרו את סשן ה-SSH.

הריצו את ההתקנה בתור אותו משתמש.

sudo -iu opentag opentag setup

תהליך ההתקנה מבקש שישה פרטים: שפת ה-CLI, כתובת ההאזנה המקומית, סוכן הקידוד, הפרויקט המקומי לעבודה, פרטי הגישה לפלטפורמה לשמירה, ואופן ההרצה. השאירו את כתובת ההאזנה על 127.0.0.1, מכיוון ש-nginx מבצע TLS termination ומעביר אליה את הבקשות, כך שהמאזינים לא צריכים להיות נגישים מבחוץ. עבור GitHub הוא גם מבקש את המאגר בפורמט owner/repo, האם מותר לו לפתוח pull requests, את פורט ה-webhook (ברירת המחדל היא 3050) ואת ה-token. בסיום, בחרו במצב שירות רקע. אם כבר יש לכם קובץ הגדרות ואתם רוצים להתקין את השירות ללא שאלות, opentag setup --service מבצע זאת.

הגדרות נשמרות ב-/home/opentag/.config/opentag/config.json ומצב זמן הריצה ב-/home/opentag/.local/state/opentag. כדאי לבדוק את המפתחות הללו ידנית לאחר שההתקנה כותבת את הקובץ.

{
  "runnerId": "runner_local",
  "dispatcherUrl": "http://localhost:3030",
  "runnerToken": "...",
  "approvalMode": "ask",
  "repositories": []
}

העדיפו את runnerToken, ה-bearer token המוגבל ל-runner, על פני ה-pairingToken המשותף הישן. קובץ ההגדרות מחזיק את פרטי הגישה בטקסט גלוי אלא אם תחליפו אותם בהפניה ל-secret, שקוראת את הערך ממשתני הסביבה או מקובץ על הדיסק בזמן העלייה. כך או כך, קובץ זה הוא הרכיב הרגיש ביותר בשרת: הגדירו לו הרשאות 600, בעלות של opentag, ולעולם אל תשמרו אותו בתוך מאגר git. הטיעון המורחב מופיע ב-שמירה על סודות מחוץ לסוכני AI.

בדקו את ההתקנה לפני חשיפת שירות כלשהו.

sudo -iu opentag opentag doctor
sudo -iu opentag opentag status

הפקודה opentag doctor בודקת את ה-dispatcher, ה-bindings, ה-checkouts וה-executors. הפקודה opentag status מדפיסה את ההגדרות ומצב זמן הריצה, וניתן להגביל אותה להרצה בודדת ברגע שקיימות הרצות. תקנו כל שגיאה ש-doctor מדווח עליה לפני שתפנו פלטפורמה כלשהי לשרת זה.

הצבת TLS בחזית ופתיחת שני נתיבים בלבד

Nginx מסיים את ה-TLS ומעביר הלאה שני נתיבים בלבד. כל בקשה אחרת מחזירה 404, כך שסורק שמוצא את ה-host לא לומד דבר על מה שרץ מאחוריו.

כתבו בלוק server פשוט בפורט 80 ב-/etc/nginx/sites-available/opentag עם שני ה-locations להלן, ואז תנו ל-Certbot להוסיף את חלק ה-TLS.

sudo apt install -y nginx certbot python3-certbot-nginx
sudo ln -s /etc/nginx/sites-available/opentag /etc/nginx/sites-enabled/opentag
sudo nginx -t && sudo systemctl reload nginx
sudo certbot --nginx -d opentag.example.com

nginx -t מדפיס את syntax is ok ו-test is successful, וזהו הדבר היחיד שעומד בין שגיאת הקלדה לבין reload שמפיל את האתר. Certbot ב-Ubuntu 24.04 עם nginx מכסה חידוש ודרכים שבהן אתגר ACME (סביבת ניהול תעודות אוטומטית) נכשל. הבלוק המוגמר נראה כך.

server {
    listen 443 ssl;
    server_name opentag.example.com;

    ssl_certificate     /etc/letsencrypt/live/opentag.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/opentag.example.com/privkey.pem;

    client_max_body_size 2m;

    location = /github/webhooks {
        proxy_pass http://127.0.0.1:3050;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
    }

    location = /slack/events {
        proxy_pass http://127.0.0.1:3040;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
    }

    location / {
        return 404;
    }
}

ה-= ב-location = /github/webhooks הוא התאמה מדויקת, ו-proxy_pass ללא כל תוספת אחרי הפורט מעביר את ה-URI המקורי ללא שינוי. השמיטו את ה-= וכל נתיב תחת /github/webhooks/ יועבר גם הוא, מה שמהווה שטח פנים גדול ממה שהמאזין צריך.

ה-firewall נשאר מצומצם.

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw status

פורטים 3030, 3040 ו-3050 לעולם אינם נפתחים. ודאו שהם מאוגדים ל-loopback ולא לכל ממשק.

sudo ss -tlnp

כל שורת OpenTag צריכה להציג 127.0.0.1:3030 או דומה. שורה שקוראת 0.0.0.0:3050 משמעותה שהמאזין מציע את עצמו לכל האינטרנט ורק ufw עוצר אותו, מה שמרחק טעות firewall אחת מהפעלת סוכן פתוח. יסודות ה-firewall של ufw מסביר מה ה-deny המוגדר כברירת מחדל עושה באמת.

שתי בדיקות מוכיחות את הדלת הקדמית. curl -I https://opentag.example.com/ מחזיר 404 מ-nginx, מה שמראה שהתעודה תקינה ושה-catch-all סגור. בקשה ל-/slack/events או /github/webhooks ללא חתימה לעולם לא צריכה להחזיר 200.

אימות כל חתימה, כיוון שה־URL ציבורי

כל אחד יכול למצוא את ה־URL של ה־payload. הוא מופיע בהגדרות ה־repository, בהיסטוריית הדפדפן, או בצילום מסך שצורף לכרטיס תמיכה. החתימה היא הדבר היחיד שמבדיל בין משלוח אמיתי מ־GitHub לבין בקשה שמישהו הקליד ידנית.

GitHub חותם על כל משלוח באמצעות ה־webhook secret ושולח את התוצאה ב־header מסוג x-hub-signature-256. המערכת OpenTag מאמתת את ה־header הזה מול platforms.github.webhookSecret. הערות האבטחה של הפרויקט מציגות את הכלל באופן ישיר: אין לקבל אירועי מקור לא חתומים ב־/github/webhooks. השירות Slack חותם על כל בקשה באמצעות SLACK_SIGNING_SECRET וכולל חותמת זמן, כך שלא ניתן להריץ מחדש (replay) גוף בקשה שנתפס שעות לאחר מכן.

דילוג על שלב זה אינו סיכון קטן. endpoint שלא עבר אימות יקבל payload מסוג issue_comment שנכתב ידנית ומכיל @opentag, ואז OpenTag יריץ סוכן קידוד, עם ה־token שלכם, בתוך ה־checkout שלכם, לפי הוראות של זר. התגובה תישלח לכל thread שה־payload המזויף יציין.

OpenTag מוסיף שתי שכבות הגנה נוספות. משלוחי מקור מנוטרים לפי delivery ID, כך ששליחה חוזרת של אותו אירוע לא תפעיל הרצה שנייה. קריאות ל־runner מקבלות מפתחות idempotency, כך ששידור חוזר של בקשה אחת יחזיר הצלחה מבלי להוסיף אירוע ביקורת נוסף.

מגבלות קצב (rate limits) ניתנות להגדרה וחובה להפעילן. OPENTAG_RATE_LIMIT_WINDOW_MS ו־OPENTAG_RATE_LIMIT_MAX_REQUESTS מגבילים את קצב הבקשות, OPENTAG_MAX_REQUEST_BODY_BYTES מגביל את גוף הבקשה, ו־payload חורג מהגודל המותר נדחה עם 413 request_body_too_large. הגדרת OPENTAG_RATE_LIMIT_DISABLED=true קיימת לצורכי פיתוח מקומי בלבד, ואין לה מקום על שרת ציבורי. כלל נוסף מאותן הערות: URL ממסר (relay) ציבורי חייב להשתמש ב־HTTPS, וה־CLI מאפשר HTTP רגיל עבור localhost בלבד.

אילו הרשאות (scopes) הבוט באמת צריך?

ב-GitHub,‏ OpenTag משתמש ב-personal access token מפורט (fine-grained) ולא ב-GitHub App. התיעוד מציין כי נתיב ה-App מתוכנן לעתיד ואינו ברירת המחדל ב-CLI כיום, ולכך יש השלכה שמשתמשים רבים מפספסים: הבוט מגיב בשם האדם שיצר את ה-token. צרו אותו תחת חשבון שאתם מוכנים לראות מצוטט בכל תגובת מיון (triage).

הגבילו את ההרשאות בדיוק לפי מדריך ההתקנה. בחרו ב-Only select repositories ובחרו מאגר אחד. העניקו הרשאות Issues: Read and write ו-Pull requests: Read and write. זה מספיק כדי לקרוא אזכור ולהשיב בשרשור.

שימו לב למה שחסר: הרשאת כתיבה לקוד. OpenTag לא מבצע push לענפים אלא אם preparePullRequestBranch מוגדר כ-true, וקיים githubApplyToken נפרד כך שה-token שכותב קוד אינו ה-token שכותב תגובות. הפרידו ביניהם, והשאירו את ה-write token מושבת עד שנתיב הקריאה והתגובה יפעל כשורה במשך כמה שבועות.

התצורה שיש להימנע ממנה היא token עם Contents: Read and write עבור All repositories. כל מי שיכול להגיב באחד מהמאגרים הללו יכול כעת לכוון סוכן בעל הרשאות commit, ודו"ח הביקורת יציג את בעל ה-token כמי שביצע זאת. הרחיבו את ההרשאות מאגר אחד בכל פעם, לאחר שהסוכן הוכיח את אמינותו.

ב-Slack, הרשאות הבוט הן app_mentions:read, chat:write, reactions:write ו-channels:history. ערוצים פרטיים דורשים גם את groups:history בתוספת מנוי לאירוע message.groups. מצב Socket Mode דורש app-level token עם connections:write, זה שמתחיל ב-xapp-. ההרשאה channels:history קוראת את היסטוריית ההודעות בערוצים הציבוריים שאליהם הבוט צורף, לכן הוסיפו את הבוט לערוצים הרצויים בלבד ולא לכל מקום.

ניתוב אירוע מסוג issue מקצה לקצה

התחילו ב־webhook. במאגר (repository), פתחו את Settings, לאחר מכן Webhooks, ולחצו על Add webhook. כתובת ה-payload URL היא https://opentag.example.com/github/webhooks, סוג התוכן הוא application/json, וה-secret הוא זה שהוגדר בתהליך ההתקנה. הירשמו לאירועים מסוג Issue comments ו-Pull request review comments בלבד.

GitHub שולח הודעת ping מיד עם השמירה. פתחו את Recent Deliveries וודאו שהבקשה הגיעה לשרת. שגיאת 502 מעידה על כך ש-nginx לא הצליח להגיע למאזין (listener); זו בעיה מקומית, לא בעיה ב-GitHub.

כעת השתמשו בשירות. פתחו issue שמתאר באג והוסיפו תגובה:

@opentag triage this. Reproduce the report against the current main branch, then reply with the file and function most likely responsible, plus the test you would write first.

להלן סדר הפעולות הצפוי. Recent Deliveries מתעד את המשלוח issue_comment עם תגובת 2xx. ה-dispatcher מתעד הרצה (run). ה-runner תופס את המשימה ומתחיל לשלוח אותות heartbeat. ה-executor מבצע checkout ומתחיל לעבוד. התשובה מופיעה כתגובה באותו שרשור של ה-issue. הפקודה sudo -iu opentag opentag status מציגה את ההרצה בזמן אמת, כך שניתן לעקוב אחריה במקום לנחש.

הגדירו את approvalMode ל-ask לפני ההרצה האמיתית הראשונה. במצב ask, ההרצה מושהית וממתינה לאישור אנושי לפני ביצוע פעולה שמשנה מצב כלשהו. קיימים גם המצבים auto ו-autonomous, והם מתאימים לשלבים מאוחרים יותר, לאחר שצברתם ניסיון של חודש בקריאת תמלילי ההרצות במאגר.

בצד של Slack, אותה הרצה מתחילה עם /bind owner/repo בערוץ, ולאחריו אזכור (mention). הבוט מגיב גם ל-/help, /status, /doctor, /stop ו-/unbind confirm. הגבילו את המורשים לשינוי קישורים (bindings) באמצעות OPENTAG_SLACK_BINDING_ADMIN_USER_IDS, רשימה מופרדת בפסיקים של מזהי משתמש ב-Slack, שכן הקישור הוא המיפוי בין ערוץ ציבורי לבין ה-checkout בשרת שלכם.

Triage הוא מסלול ראשוני טוב מכיוון שהוא מבצע קריאה בלבד ללא כתיבה, והתשובה קלה להערכה. Review הוא השלב הבא, שבו הסוכן מגיב על diff במקום על issue: סוכן לביקורת pull request באירוח עצמי משתמש באותה ארכיטקטורה המופנית ל-pull requests. אם ברצונכם שהסוכן יגיע למערכות שלכם בזמן העבודה, זהו התפקיד של שרתי MCP על גבי VPS. חיפוש ברשת הוא יכולת נוספת ש-triage דורש לעיתים קרובות, ו-חיבור הסוכן למופע SearXNG משלכם שומר על החיפושים הללו בחומרה שבבעלותכם, במחיר של ערוץ נוסף שדרכו טקסט של גורם חיצוני מגיע לסוכן.

מה קורה כשהסוכן טועה מול כולם?

הוא יטעה. השאלה היא מה המחיר של זה.

תגובה שגויה בנושא ציבורי היא הערה תחת שם שהצוות שלכם מזהה, ו-GitHub שולח אותה באימייל לכל מי שרשום ברגע הפרסום. מחיקת ההערה לא מבטלת את האימייל. כך גם לגבי התראה ב-Slack. תכננו את המערכת מתוך הנחה שהתשובה תהיה שגויה בפומבי, ולא מתוך הנחה שהיא תהיה נכונה בפרטיות.

ארבע אפשרויות מגבילות את הנזק, והן חשובות יותר מכל prompt שתכתבו.

  • עבדו במצב ask, כך שהסוכן מציע, אדם מאשר, ותוכנית שגויה עולה בלחיצה אחת בלבד.
  • השאירו את preparePullRequestBranch בערך ברירת המחדל שלו, false, כך שהתוצאה הגרועה ביותר של הרצה כושלת היא הערה שגויה ולא branch שגוי.
  • קשרו repository אחד וערוץ אחד בתור התחלה. ה-runner דוחה כל הרצה שיעד הפרויקט שלה נמצא מחוץ ל-allowlist המקומי, כך ש-repository שלא נקשר לא יכול למשוך את הסוכן אליו.
  • שמרו על ה-token של ההערות נפרד מכל token של ביצוע (apply), כך שביטול הרשאות כתיבה לא ישבית גם את ה-triage.

ל-Slack יש פקודת /stop עבור הרצה שמתנהלת בכיוון הלא נכון. כל הרצה מותירה גם תיעוד ביקורת (audit record) המכיל את ה-mention שהתחיל אותה ואת הפעולות שביצע הסוכן; זה מה שקוראים לאחר מכן כדי להבין היכן התרחשה הטעות.

החלק החברתי חשוב לא פחות מהתצורה. הציבו את הבוט בערוץ שבו אנשים מצפים למכונה ויודעים שהיא עלולה לטעות. תשובה שגויה שנאמרת בביטחון בערוץ של ארבעים איש, שסבורים שאדם סקר אותה, עולה יותר מהזמן שנחסך ב-triage. כתבו בתיאור הערוץ מי הבעלים של הבוט ומי בודק את הפלט שלו.

גיבויים, שדרוגים וקיבוע גרסה

שני נתיבים מכילים את כל המידע: /home/opentag/.config/opentag/config.json ו־/home/opentag/.local/state/opentag. הראשון מכיל את פרטי ההזדהות שלכם, והשני מכיל את היסטוריית ההרצות ואת קובץ מסד הנתונים. בצעו גיבוי לשניהם עם הרשאות 600, ושמרו אותם מחוץ לשרת. אובדן שלהם משמעו יצירה מחדש של אסימונים (tokens) וקישורים, ולא בנייה מחדש של השרת.

שדרוגים מבוצעים על ידי עדכון גרסה ואתחול.

sudo npm install -g @opentag/cli@0.9.0
sudo -iu opentag opentag service stop
sudo -iu opentag opentag service start
sudo -iu opentag opentag doctor

קבעו (pin) את הגרסה במקום לעקוב אחר @latest. תוכנה זו מריצה סוכן קידוד מול ה-repository שלכם עם אסימון פעיל, לכן גרסה שפורסמה במהלך הלילה מהווה שינוי שלא עבר סקירה. מדיניות האבטחה אינה מבצעת backport לגרסאות קודמות, ותיקונים מגיעים רק לגרסה העדכנית ביותר; לכן, קיבוע גרסה משמעו שאתם קוראים את ה-changelog ומבצעים את השדרוג באופן יזום. אין זה אומר להישאר בגרסה v0.9.0 לנצח. ההיסטוריה עד יולי 2026 מראה מספר גרסאות בחודש, וזו סיבה טובה לקרוא את הערות השחרור לפני כל עדכון גרסה.

FAQ

האם אני זקוק ל-VPS כדי להריץ את OpenTag, או שמחשב נייד מספיק?

מחשב נייד מספיק עבור Slack בלבד, כיוון ש-Socket Mode פותח WebSocket יוצא ואינו זקוק לפורט נכנס. GitHub פועל אחרת. ה-webhooks של ה-repository מגיעים דרך HTTP נכנס לכתובת URL שאתה רושם פעם אחת, לכן הכתובת חייבת להישאר קבועה ועליה להשיב גם כשאתה ישן. מארח מנהרה (tunnel host) מחשבון חינמי משתנה בכל אתחול, ו-GitHub ממשיך לשלוח בקשות לכתובת הישנה, מה שמופיע כרשומות כושלות בלשונית Recent Deliveries ב-repository וכשתיקה בשרשור. VPS עם שם DNS קבוע ותעודה פותר את שתי הבעיות הללו.

אילו הרשאות GitHub נדרשות ל-OpenTag?

נדרש personal access token מפורט (fine-grained) המוגבל ל-Only select repositories, עם הרשאות Issues: Read and write ו-Pull requests: Read and write. זה מכסה קריאת אזכורים ותגובה בשרשור. אין צורך בהרשאת כתיבה לקוד אלא אם הגדרת את preparePullRequestBranch כ-true כדי ש-OpenTag ידחוף (push) ענפים, וקיים githubApplyToken נפרד כדי שה-token לכתיבת קוד יישאר מופרד מזה של התגובות. הימנע משימוש ב-token לכל ה-repositories עם הרשאת כתיבת תוכן, כיוון שכל מי שיכול להגיב באחד מה-repositories הללו יוכל להכווין סוכן בעל יכולת ביצוע commit.

כיצד אוכל לעצור הרצה שמשתבשת?

ב-Slack קיים פקודת /stop בדיוק למטרה זו. בשרת, הפקודה opentag status מציגה מה רץ, ו-opentag service stop עוצרת את ה-daemon, מה שמסיים את כל ה-pipeline במקום הרצה בודדת. כדי להימנע מהצורך בשניהם, הגדר את approvalMode ל-ask כך שהרצות יושהו עבור אדם לפני שהן משנות משהו, והשאר את preparePullRequestBranch על false כך שהרצה שגויה תייצר תגובה במקום ענף.

מדוע ה-webhook שלי מחזיר 502 בעוד השרשור נשאר שקט?

שגיאת 502 מגיעה מ-nginx, לא מ-OpenTag, והיא מציינת שה-proxy לא הצליח להגיע למאזין (listener). הפקודה /var/log/nginx/error.log תציג את connect() failed (111: Connection refused) while connecting to upstream. או שהמאזין נעצר, או שהוא נמצא בפורט שונה מזה שצוין בשורת ה-proxy_pass. הרץ את sudo ss -tlnp וודא שמשהו מאזין ב-127.0.0.1:3050 עבור GitHub וב-127.0.0.1:3040 עבור Slack, לאחר מכן הרץ את opentag doctor עבור ה-bindings וה-executors.

#opentag#ai-agents#slack#github#webhooks#self-hosting