diff --git a/.claude/agents/legal-ceo.md b/.claude/agents/legal-ceo.md
index dee0b61..dd82683 100644
--- a/.claude/agents/legal-ceo.md
+++ b/.claude/agents/legal-ceo.md
@@ -60,6 +60,48 @@ tools:
| בודק איכות | 1a5b229e-9220-4b13-940c-f8eb7285fc29 | QA לפני ייצוא |
| מייצא טיוטה | d0dc703b-ca83-4883-bca7-c9449e8713cd | בדיקה סופית + ייצוא DOCX מגורסת |
+## כלל: כל issue חדש = תת-משימה
+
+כשאתה יוצר issue חדש לסוכן, **תמיד** כלול `parentId` עם ה-issue ID הראשי של התיק.
+ה-issue הראשי הוא ה-issue שבו אתה עובד — `$PAPERCLIP_TASK_ID`.
+
+```bash
+curl -s -X POST -H "Authorization: Bearer $PAPERCLIP_API_KEY" \
+ -H "Content-Type: application/json" \
+ "$PAPERCLIP_API_URL/api/companies/$PAPERCLIP_COMPANY_ID/issues" \
+ -d '{"title": "...", "description": "...", "parentId": "'$PAPERCLIP_TASK_ID'", "assigneeAgentId": "..."}'
+```
+
+**אם** ה-issue שלך הוא בעצמו תת-משימה (יש לו parent), השתמש ב-parent של ה-parent — כלומר ה-issue הראשי של התיק. לקבלת ה-parent:
+```bash
+curl -s -H "Authorization: Bearer $PAPERCLIP_API_KEY" \
+ "$PAPERCLIP_API_URL/api/issues/$PAPERCLIP_TASK_ID" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('parentId') or d['id'])"
+```
+
+---
+
+## התראת מייל — חובה
+
+**בכל פעם שאתה מפרסם comment שמצפה לתשובה מחיים**, שלח מייל:
+
+```bash
+python3 /home/chaim/legal-ai/scripts/notify.py \
+ "נדרשת תשובתך — [תיאור קצר]" \
+ "[סיכום: מה בוצע, מה נדרש ממך, קישור ל-issue]"
+```
+
+**מתי לשלוח — תמיד:**
+- סיום כל שלב (B, C, D, F) — עם סיכום מה בוצע
+- כל comment שמבקש בחירה (תוצאה, כיוון, טיפול בטענות)
+- שגיאה שדורשת התערבות
+- החלטה מוכנה לביקורת דפנה
+
+**מתי לא לשלוח:**
+- עדכוני סטטוס ביניים (רק בסיום שלב)
+- שגיאות טכניות שאפשר לפתור לבד
+
+---
+
## תהליך אינטראקטיבי — שלב אחר שלב
### שלב 0: בדוק למה התעוררת
diff --git a/scripts/notify.py b/scripts/notify.py
index e566748..75a4fb6 100755
--- a/scripts/notify.py
+++ b/scripts/notify.py
@@ -15,7 +15,7 @@ SMTP_HOST = "smtp.gmail.com"
SMTP_PORT = 587
FROM_EMAIL = "notify@marcus-law.co.il"
FROM_PASS = "vuva jwed lbuz xjds"
-TO_EMAIL = "paperclip+chaim@marcus-law.co.il"
+TO_EMAIL = "chaim+paperclip@marcus-law.co.il"
def send(subject: str, body: str) -> bool:
diff --git a/scripts/paperclip-assets/deploy.sh b/scripts/paperclip-assets/deploy.sh
new file mode 100755
index 0000000..f99081e
--- /dev/null
+++ b/scripts/paperclip-assets/deploy.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# Deploy Paperclip UI assets (RTL + Hebrew translation) to the live instance.
+# Usage: bash scripts/paperclip-assets/deploy.sh
+set -e
+
+SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
+UI_DIR="/home/chaim/.npm/_npx/43414d9b790239bb/node_modules/@paperclipai/server/ui-dist"
+
+if [ ! -d "$UI_DIR/assets" ]; then
+ echo "ERROR: Paperclip ui-dist not found at $UI_DIR"
+ echo "Run: find ~/.npm/_npx -name ui-dist -path '*paperclipai*' -type d"
+ exit 1
+fi
+
+cp "$SCRIPT_DIR/rtl-override.css" "$UI_DIR/assets/rtl-override.css"
+cp "$SCRIPT_DIR/translate-he.js" "$UI_DIR/assets/translate-he.js"
+
+echo "Assets deployed to $UI_DIR/assets/"
+echo "Restarting Paperclip..."
+pm2 restart paperclip
+echo "Done."
diff --git a/scripts/paperclip-assets/patch-html.sh b/scripts/paperclip-assets/patch-html.sh
new file mode 100644
index 0000000..8a9b7de
--- /dev/null
+++ b/scripts/paperclip-assets/patch-html.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+# patch-html.sh - Inject Hebrew RTL + translation into Paperclip UI
+set -e
+
+# Find the ui-dist directory in the global npm install
+UI_DIR=$(find /usr/local/lib/node_modules/paperclipai -name "ui-dist" -type d | head -1)
+
+if [ -z "$UI_DIR" ]; then
+ echo "ERROR: Could not find Paperclip ui-dist directory"
+ exit 1
+fi
+
+echo "Found ui-dist at: $UI_DIR"
+
+# Copy assets
+cp /tmp/rtl-override.css "$UI_DIR/assets/rtl-override.css"
+cp /tmp/translate-he.js "$UI_DIR/assets/translate-he.js"
+
+# Patch index.html:
+# 1. Set dir="rtl" and lang="he"
+sed -i 's/
+sed -i 's||\n\n|' "$UI_DIR/index.html"
+
+# 3. Update page title
+sed -i 's|
Paperclip|Paperclip - פייפרקליפ|' "$UI_DIR/index.html"
+
+echo "Hebrew RTL patch applied successfully"
+echo "Patched files:"
+echo " - $UI_DIR/index.html"
+echo " - $UI_DIR/assets/rtl-override.css"
+echo " - $UI_DIR/assets/translate-he.js"
diff --git a/scripts/paperclip-assets/rtl-override.css b/scripts/paperclip-assets/rtl-override.css
new file mode 100644
index 0000000..3422fe3
--- /dev/null
+++ b/scripts/paperclip-assets/rtl-override.css
@@ -0,0 +1,1045 @@
+/* ==========================================================================
+ Paperclip AI - RTL Override for Hebrew (dir="rtl")
+ Generated from analysis of index-CYurTMty.css (Tailwind v4.1.18 + MDXEditor)
+
+ Scoped under html[dir="rtl"] to apply only in RTL mode.
+ ========================================================================== */
+
+/* --------------------------------------------------------------------------
+ 1. GLOBAL DIRECTION
+ -------------------------------------------------------------------------- */
+html[dir="rtl"] {
+ direction: rtl;
+}
+
+html[dir="rtl"] body {
+ text-align: right;
+}
+
+/* --------------------------------------------------------------------------
+ 2. TAILWIND UTILITY CLASSES - Padding Left/Right Swap
+
+ .pl-* -> padding-right, .pr-* -> padding-left
+ -------------------------------------------------------------------------- */
+html[dir="rtl"] .pl-1 { padding-left: 0; padding-right: calc(var(--spacing) * 1); }
+html[dir="rtl"] .pl-2 { padding-left: 0; padding-right: calc(var(--spacing) * 2); }
+html[dir="rtl"] .pl-3 { padding-left: 0; padding-right: calc(var(--spacing) * 3); }
+html[dir="rtl"] .pl-4 { padding-left: 0; padding-right: calc(var(--spacing) * 4); }
+html[dir="rtl"] .pl-5 { padding-left: 0; padding-right: calc(var(--spacing) * 5); }
+html[dir="rtl"] .pl-5\.5 { padding-left: 0; padding-right: calc(var(--spacing) * 5.5); }
+html[dir="rtl"] .pl-6 { padding-left: 0; padding-right: calc(var(--spacing) * 6); }
+html[dir="rtl"] .pl-7 { padding-left: 0; padding-right: calc(var(--spacing) * 7); }
+html[dir="rtl"] .pl-8 { padding-left: 0; padding-right: calc(var(--spacing) * 8); }
+
+html[dir="rtl"] .pr-1 { padding-right: 0; padding-left: calc(var(--spacing) * 1); }
+html[dir="rtl"] .pr-2 { padding-right: 0; padding-left: calc(var(--spacing) * 2); }
+html[dir="rtl"] .pr-3 { padding-right: 0; padding-left: calc(var(--spacing) * 3); }
+html[dir="rtl"] .pr-6 { padding-right: 0; padding-left: calc(var(--spacing) * 6); }
+html[dir="rtl"] .pr-8 { padding-right: 0; padding-left: calc(var(--spacing) * 8); }
+html[dir="rtl"] .pr-10 { padding-right: 0; padding-left: calc(var(--spacing) * 10); }
+
+/* data-inset padding override */
+html[dir="rtl"] .data-\[inset\]\:pl-8[data-inset] {
+ padding-left: 0;
+ padding-right: calc(var(--spacing) * 8);
+}
+
+/* Responsive padding overrides */
+html[dir="rtl"] .sm\:pl-1 { padding-left: 0; padding-right: calc(var(--spacing) * 1); }
+html[dir="rtl"] .sm\:pr-3 { padding-right: 0; padding-left: calc(var(--spacing) * 3); }
+
+/* --------------------------------------------------------------------------
+ 3. TAILWIND UTILITY CLASSES - Margin Left/Right Swap
+
+ .ml-* -> margin-right, .mr-* -> margin-left
+ -------------------------------------------------------------------------- */
+html[dir="rtl"] .-ml-1\.5 { margin-left: 0; margin-right: calc(var(--spacing) * -1.5); }
+html[dir="rtl"] .ml-0\.5 { margin-left: 0; margin-right: calc(var(--spacing) * 0.5); }
+html[dir="rtl"] .ml-1 { margin-left: 0; margin-right: calc(var(--spacing) * 1); }
+html[dir="rtl"] .ml-1\.5 { margin-left: 0; margin-right: calc(var(--spacing) * 1.5); }
+html[dir="rtl"] .ml-2 { margin-left: 0; margin-right: calc(var(--spacing) * 2); }
+html[dir="rtl"] .ml-3 { margin-left: 0; margin-right: calc(var(--spacing) * 3); }
+html[dir="rtl"] .ml-4 { margin-left: 0; margin-right: calc(var(--spacing) * 4); }
+html[dir="rtl"] .ml-5 { margin-left: 0; margin-right: calc(var(--spacing) * 5); }
+html[dir="rtl"] .ml-auto { margin-left: 0; margin-right: auto; }
+
+html[dir="rtl"] .mr-1 { margin-right: 0; margin-left: calc(var(--spacing) * 1); }
+html[dir="rtl"] .mr-1\.5 { margin-right: 0; margin-left: calc(var(--spacing) * 1.5); }
+html[dir="rtl"] .mr-2 { margin-right: 0; margin-left: calc(var(--spacing) * 2); }
+html[dir="rtl"] .mr-auto { margin-right: 0; margin-left: auto; }
+
+/* file selector button margin */
+html[dir="rtl"] .file\:mr-4::file-selector-button {
+ margin-right: 0;
+ margin-left: calc(var(--spacing) * 4);
+}
+
+/* Responsive margin overrides */
+html[dir="rtl"] .sm\:mr-1 { margin-right: 0; margin-left: calc(var(--spacing) * 1); }
+html[dir="rtl"] .md\:ml-auto { margin-left: 0; margin-right: auto; }
+
+/* --------------------------------------------------------------------------
+ 4. TAILWIND UTILITY CLASSES - Left/Right Position Swap
+ -------------------------------------------------------------------------- */
+html[dir="rtl"] .left-0 { left: auto; right: calc(var(--spacing) * 0); }
+html[dir="rtl"] .left-1\/2 { left: auto; right: 50%; }
+html[dir="rtl"] .left-2 { left: auto; right: calc(var(--spacing) * 2); }
+html[dir="rtl"] .left-2\.5 { left: auto; right: calc(var(--spacing) * 2.5); }
+html[dir="rtl"] .left-3 { left: auto; right: calc(var(--spacing) * 3); }
+html[dir="rtl"] .left-4 { left: auto; right: calc(var(--spacing) * 4); }
+html[dir="rtl"] .left-\[-14px\] { left: auto; right: -14px; }
+html[dir="rtl"] .left-\[50\%\] { left: auto; right: 50%; }
+
+html[dir="rtl"] .-right-0\.5 { right: auto; left: calc(var(--spacing) * -0.5); }
+html[dir="rtl"] .-right-2 { right: auto; left: calc(var(--spacing) * -2); }
+html[dir="rtl"] .right-0 { right: auto; left: calc(var(--spacing) * 0); }
+html[dir="rtl"] .right-1\.5 { right: auto; left: calc(var(--spacing) * 1.5); }
+html[dir="rtl"] .right-2 { right: auto; left: calc(var(--spacing) * 2); }
+html[dir="rtl"] .right-3 { right: auto; left: calc(var(--spacing) * 3); }
+html[dir="rtl"] .right-4 { right: auto; left: calc(var(--spacing) * 4); }
+html[dir="rtl"] .right-6 { right: auto; left: calc(var(--spacing) * 6); }
+
+/* Responsive left positioning */
+html[dir="rtl"] .sm\:left-3 { left: auto; right: calc(var(--spacing) * 3); }
+
+/* --------------------------------------------------------------------------
+ 5. TAILWIND UTILITY CLASSES - Text Align Swap
+ -------------------------------------------------------------------------- */
+html[dir="rtl"] .text-left { text-align: right; }
+html[dir="rtl"] .text-right { text-align: left; }
+html[dir="rtl"] .sm\:text-left { text-align: right; }
+html[dir="rtl"] .sm\:text-right { text-align: left; }
+
+/* --------------------------------------------------------------------------
+ 6. TAILWIND UTILITY CLASSES - Float Swap
+ -------------------------------------------------------------------------- */
+html[dir="rtl"] .float-right { float: left; }
+
+/* --------------------------------------------------------------------------
+ 7. TAILWIND UTILITY CLASSES - Border Left/Right Swap
+ -------------------------------------------------------------------------- */
+html[dir="rtl"] .border-l {
+ border-left-style: none;
+ border-left-width: 0;
+ border-right-style: var(--tw-border-style);
+ border-right-width: 1px;
+}
+
+html[dir="rtl"] .border-l-2 {
+ border-left-style: none;
+ border-left-width: 0;
+ border-right-style: var(--tw-border-style);
+ border-right-width: 2px;
+}
+
+html[dir="rtl"] .border-l-transparent {
+ border-left-color: initial;
+ border-right-color: #0000;
+}
+
+html[dir="rtl"] .border-r {
+ border-right-style: none;
+ border-right-width: 0;
+ border-left-style: var(--tw-border-style);
+ border-left-width: 1px;
+}
+
+/* Responsive border overrides */
+html[dir="rtl"] .sm\:border-l {
+ border-left-style: none;
+ border-left-width: 0;
+ border-right-style: var(--tw-border-style);
+ border-right-width: 1px;
+}
+
+html[dir="rtl"] .lg\:border-r {
+ border-right-style: none;
+ border-right-width: 0;
+ border-left-style: var(--tw-border-style);
+ border-left-width: 1px;
+}
+
+/* --------------------------------------------------------------------------
+ 8. TAILWIND UTILITY CLASSES - Rounded Left/Right Swap
+ -------------------------------------------------------------------------- */
+html[dir="rtl"] .rounded-l-md {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+ border-top-right-radius: .5rem;
+ border-bottom-right-radius: .5rem;
+}
+
+html[dir="rtl"] .rounded-r-md {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+ border-top-left-radius: .5rem;
+ border-bottom-left-radius: .5rem;
+}
+
+html[dir="rtl"] .rounded-r-full {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+ border-top-left-radius: 3.40282e38px;
+ border-bottom-left-radius: 3.40282e38px;
+}
+
+/* --------------------------------------------------------------------------
+ 9. TAILWIND UTILITY CLASSES - TranslateX Flip
+ -------------------------------------------------------------------------- */
+html[dir="rtl"] .-translate-x-1\/2 { --tw-translate-x: 50%; }
+html[dir="rtl"] .-translate-x-4 { --tw-translate-x: calc(var(--spacing) * 4); }
+html[dir="rtl"] .-translate-x-full { --tw-translate-x: 100%; }
+html[dir="rtl"] .translate-x-0 { --tw-translate-x: calc(var(--spacing) * 0); }
+html[dir="rtl"] .translate-x-0\.5 { --tw-translate-x: calc(var(--spacing) * -0.5); }
+html[dir="rtl"] .translate-x-4\.5 { --tw-translate-x: calc(var(--spacing) * -4.5); }
+html[dir="rtl"] .translate-x-5 { --tw-translate-x: calc(var(--spacing) * -5); }
+html[dir="rtl"] .translate-x-\[-50\%\] { --tw-translate-x: 50%; }
+
+/* --------------------------------------------------------------------------
+ 10. RADIX UI - data-side tooltip/popover offset swap
+ -------------------------------------------------------------------------- */
+html[dir="rtl"] .data-\[side\=left\]\:-translate-x-1[data-side=left] {
+ --tw-translate-x: calc(var(--spacing) * 1);
+}
+
+html[dir="rtl"] .data-\[side\=right\]\:translate-x-1[data-side=right] {
+ --tw-translate-x: calc(var(--spacing) * -1);
+}
+
+/* --------------------------------------------------------------------------
+ 11. MDXEditor - Toolbar Components
+ -------------------------------------------------------------------------- */
+
+/* Toolbar root - sticky, scrollable row */
+html[dir="rtl"] [class*="_toolbarRoot_"] {
+ flex-direction: row-reverse;
+}
+
+/* Toolbar mode switch - push to left in RTL (was margin-left:auto) */
+html[dir="rtl"] [class*="_toolbarModeSwitch_"] {
+ margin-left: 0;
+ margin-right: auto;
+}
+
+/* Toolbar separator - swap border sides */
+html[dir="rtl"] [class*="_toolbarRoot_"] div[role="separator"] {
+ border-left: 1px solid var(--baseBase);
+ border-right: 1px solid var(--baseBorder);
+}
+
+/* Toolbar button adjacency spacing */
+html[dir="rtl"] [class*="_toolbarButton_"] + [class*="_toolbarButton_"] {
+ margin-left: 0;
+ margin-right: var(--spacing-1);
+}
+
+/* Toolbar toggle first/last child border-radius swap */
+html[dir="rtl"] [class*="_toolbarToggleSingleGroup_"]:first-of-type [class*="_toolbarToggleItem_"]:only-child,
+html[dir="rtl"] [class*="_toolbarToggleSingleGroup_"]:only-child [class*="_toolbarToggleItem_"]:first-child,
+html[dir="rtl"] [class*="_toolbarModeSwitch_"] [class*="_toolbarToggleItem_"]:first-child {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+ border-top-right-radius: var(--radius-base);
+ border-bottom-right-radius: var(--radius-base);
+}
+
+html[dir="rtl"] [class*="_toolbarToggleSingleGroup_"]:last-of-type [class*="_toolbarToggleItem_"]:only-child,
+html[dir="rtl"] [class*="_toolbarToggleSingleGroup_"]:only-child [class*="_toolbarToggleItem_"]:last-child,
+html[dir="rtl"] [class*="_toolbarModeSwitch_"] [class*="_toolbarToggleItem_"]:last-child {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+ border-top-left-radius: var(--radius-base);
+ border-bottom-left-radius: var(--radius-base);
+}
+
+/* Dropdown arrow - push to right in RTL (was margin-left:auto) */
+html[dir="rtl"] [class*="_toolbarNodeKindSelectDropdownArrow_"],
+html[dir="rtl"] [class*="_selectDropdownArrow_"] {
+ margin-left: 0;
+ margin-right: auto;
+}
+
+/* Dropdown container - border radius swap */
+html[dir="rtl"] [class*="_toolbarNodeKindSelectContainer_"],
+html[dir="rtl"] [class*="_toolbarButtonDropdownContainer_"],
+html[dir="rtl"] [class*="_toolbarCodeBlockLanguageSelectContent_"],
+html[dir="rtl"] [class*="_selectContainer_"] {
+ border-bottom-left-radius: 0;
+ border-bottom-right-radius: var(--radius-base);
+}
+
+html[dir="rtl"] [class*="_toolbarButtonDropdownContainer_"],
+html[dir="rtl"] [class*="_toolbarButtonDropdownContainer_"] [class*="_selectItem_"]:first-child {
+ border-top-right-radius: 0;
+ border-top-left-radius: var(--radius-base);
+}
+
+/* Select trigger open state - radius swap */
+html[dir="rtl"] [class*="_toolbarNodeKindSelectTrigger_"][data-state="open"],
+html[dir="rtl"] [class*="_toolbarButtonSelectTrigger_"][data-state="open"],
+html[dir="rtl"] [class*="_selectTrigger_"][data-state="open"] {
+ border-bottom-right-radius: var(--radius-none);
+ border-bottom-left-radius: var(--radius-none);
+}
+
+/* Select item last child - radius swap */
+html[dir="rtl"] [class*="_toolbarNodeKindSelectItem_"]:last-child,
+html[dir="rtl"] [class*="_selectItem_"]:last-child {
+ border-bottom-left-radius: 0;
+ border-bottom-right-radius: var(--radius-base);
+}
+
+/* --------------------------------------------------------------------------
+ 12. MDXEditor - CodeMirror & Image Edit Toolbars
+ Position: was right:0 -> left:0, border-bottom-left -> border-bottom-right
+ -------------------------------------------------------------------------- */
+html[dir="rtl"] [class*="_codeMirrorToolbar_"] {
+ right: auto;
+ left: 0;
+ border-bottom-left-radius: 0;
+ border-bottom-right-radius: var(--radius-base);
+}
+
+html[dir="rtl"] [class*="_editImageToolbar_"] {
+ right: auto;
+ left: 0;
+ border-bottom-left-radius: 0;
+ border-bottom-right-radius: var(--radius-base);
+}
+
+/* --------------------------------------------------------------------------
+ 13. MDXEditor - Property Panel
+ -------------------------------------------------------------------------- */
+html[dir="rtl"] [class*="_propertyPanelTitle_"] {
+ padding-left: 0;
+ padding-right: var(--spacing-2);
+}
+
+html[dir="rtl"] [class*="_propertyEditorTable_"] th {
+ text-align: right;
+}
+
+html[dir="rtl"] [class*="_propertyEditorTable_"] [class*="_readOnlyColumnCell_"] {
+ padding-left: initial;
+ padding-right: 0;
+}
+
+html[dir="rtl"] [class*="_readOnlyColumnCell_"] {
+ padding-left: initial;
+ padding-right: 0;
+}
+
+html[dir="rtl"] [class*="_propertyEditorTable_"] td:last-child [class*="_iconButton_"] {
+ margin-left: 0;
+ margin-right: var(--spacing-4);
+}
+
+/* --------------------------------------------------------------------------
+ 14. MDXEditor - Dialog
+ -------------------------------------------------------------------------- */
+/* Dialog centered positioning - no swap needed (translate-50% centers) */
+
+html[dir="rtl"] [class*="_dialogTitle_"] {
+ padding-left: 0;
+ padding-right: var(--spacing-2);
+}
+
+/* Link dialog input button */
+html[dir="rtl"] [class*="_linkDialogInputWrapper_"] > button {
+ padding-right: 0;
+ padding-left: var(--spacing-2);
+}
+
+/* Link dialog input dropdown open state */
+html[dir="rtl"] [class*="_linkDialogInputWrapper_"][data-visible-dropdown="true"] {
+ border-bottom-left-radius: var(--radius-none);
+ border-bottom-right-radius: var(--radius-none);
+}
+
+/* Link dialog preview anchor */
+html[dir="rtl"] [class*="_linkDialogPreviewAnchor_"] {
+ margin-right: 0;
+ margin-left: var(--spacing-1);
+}
+
+/* --------------------------------------------------------------------------
+ 15. MDXEditor - Generic Component Name
+ -------------------------------------------------------------------------- */
+html[dir="rtl"] [class*="_genericComponentName_"] {
+ padding-right: 0;
+ padding-left: var(--spacing-2);
+}
+
+/* --------------------------------------------------------------------------
+ 16. MDXEditor - Table Editor
+ -------------------------------------------------------------------------- */
+html[dir="rtl"] [class*="_tableEditor_"] thead > tr > th {
+ text-align: left; /* was right, swap */
+}
+
+html[dir="rtl"] [class*="_toolCell_"] {
+ text-align: left; /* was right, swap */
+}
+
+html[dir="rtl"] [class*="_leftAlignedCell_"] {
+ text-align: right; /* was left, swap */
+}
+
+html[dir="rtl"] [class*="_rightAlignedCell_"] {
+ text-align: left; /* was right, swap */
+}
+
+/* Table column editor toolbar separators */
+html[dir="rtl"] [class*="_tableColumnEditorToolbar_"] [role="separator"] {
+ margin-left: 0;
+ margin-right: var(--spacing-1);
+}
+
+/* Add column button - was on right side */
+html[dir="rtl"] [class*="_addColumnButton_"] {
+ margin-left: 0;
+ margin-right: var(--spacing-px);
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+ border-top-left-radius: var(--radius-medium);
+ border-bottom-left-radius: var(--radius-medium);
+}
+
+/* Toggle group first/last child radius swap */
+html[dir="rtl"] [class*="_toggleGroupRoot_"] button:first-child {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+ border-top-right-radius: var(--radius-base);
+ border-bottom-right-radius: var(--radius-base);
+}
+
+html[dir="rtl"] [class*="_toggleGroupRoot_"] button:last-child {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+ border-top-left-radius: var(--radius-base);
+ border-bottom-left-radius: var(--radius-base);
+}
+
+/* --------------------------------------------------------------------------
+ 17. MDXEditor - Diff Source Toggle
+ -------------------------------------------------------------------------- */
+html[dir="rtl"] [class*="_diffSourceToggleWrapper_"] {
+ margin-left: 0;
+ margin-right: auto;
+ right: auto;
+ left: 0;
+}
+
+/* --------------------------------------------------------------------------
+ 18. MDXEditor - Select with Label
+ -------------------------------------------------------------------------- */
+html[dir="rtl"] [class*="_selectWithLabel_"] {
+ margin-left: 0;
+ margin-right: var(--spacing-2);
+}
+
+html[dir="rtl"] [class*="_toolbarTitleMode_"] {
+ margin-left: 0;
+ margin-right: var(--spacing-2);
+}
+
+/* --------------------------------------------------------------------------
+ 19. MDXEditor - Downshift Autocomplete
+ -------------------------------------------------------------------------- */
+html[dir="rtl"] [class*="_downshiftInputWrapper_"] > button {
+ padding-right: 0;
+ padding-left: var(--spacing-2);
+}
+
+html[dir="rtl"] [class*="_downshiftInputWrapper_"][data-visible-dropdown="true"] {
+ border-bottom-left-radius: var(--radius-none);
+ border-bottom-right-radius: var(--radius-none);
+}
+
+html[dir="rtl"] [class*="_downshiftAutocompleteContainer_"] ul {
+ border-bottom-left-radius: 0;
+ border-bottom-right-radius: var(--radius-medium);
+}
+
+html[dir="rtl"] [class*="_downshiftAutocompleteContainer_"] ul li:last-of-type {
+ border-bottom-left-radius: 0;
+ border-bottom-right-radius: var(--radius-medium);
+}
+
+/* --------------------------------------------------------------------------
+ 20. MDXEditor - List Items (Checkbox)
+ -------------------------------------------------------------------------- */
+html[dir="rtl"] [class*="_listItemChecked_"],
+html[dir="rtl"] [class*="_listItemUnchecked_"] {
+ padding-left: 0;
+ padding-right: var(--spacing-6);
+}
+
+html[dir="rtl"] [class*="_listItemChecked_"]:before,
+html[dir="rtl"] [class*="_listItemUnchecked_"]:before {
+ left: auto;
+ right: 0;
+}
+
+html[dir="rtl"] [class*="_listItemChecked_"]:after {
+ left: auto;
+ right: var(--spacing-1_5);
+}
+
+/* --------------------------------------------------------------------------
+ 21. MDXEditor - Admonitions (Info/Warning/Danger blocks)
+ -------------------------------------------------------------------------- */
+html[dir="rtl"] [class*="_admonitionDanger_"],
+html[dir="rtl"] [class*="_admonitionInfo_"],
+html[dir="rtl"] [class*="_admonitionNote_"],
+html[dir="rtl"] [class*="_admonitionTip_"],
+html[dir="rtl"] [class*="_admonitionCaution_"] {
+ border-left: none;
+ border-right: 3px solid var(--admonitionBorder);
+}
+
+/* --------------------------------------------------------------------------
+ 22. Paperclip Markdown Rendered Content
+ -------------------------------------------------------------------------- */
+html[dir="rtl"] .paperclip-mdxeditor-content ul,
+html[dir="rtl"] .paperclip-mdxeditor-content ol {
+ padding-left: 0;
+ padding-right: 1.6em;
+}
+
+html[dir="rtl"] .paperclip-mdxeditor-content blockquote {
+ border-left: none;
+ border-right: 3px solid var(--border);
+ padding-left: 0;
+ padding-right: 1em;
+}
+
+html[dir="rtl"] .paperclip-markdown :where(ul, ol) {
+ padding-left: 0;
+ padding-right: 1.15rem;
+}
+
+html[dir="rtl"] .paperclip-markdown li {
+ padding-left: 0;
+ padding-right: .2rem;
+}
+
+html[dir="rtl"] .paperclip-markdown blockquote {
+ border-left: none;
+ border-right: .24rem solid var(--border);
+ margin-left: initial;
+ margin-right: 0;
+ padding-left: 0;
+ padding-right: .95rem;
+}
+
+@supports (color: color-mix(in lab, red, red)) {
+ html[dir="rtl"] .paperclip-markdown blockquote {
+ border-right: .24rem solid color-mix(in oklab, var(--border) 84%, var(--muted-foreground) 16%);
+ }
+}
+
+html[dir="rtl"] .paperclip-markdown th {
+ text-align: right;
+}
+
+/* Nested list/ol padding overrides from Tailwind arbitrary selectors */
+html[dir="rtl"] .\[\&_ol\]\:pl-5 ol {
+ padding-left: 0;
+ padding-right: calc(var(--spacing) * 5);
+}
+
+html[dir="rtl"] .\[\&_ul\]\:pl-5 ul {
+ padding-left: 0;
+ padding-right: calc(var(--spacing) * 5);
+}
+
+/* --------------------------------------------------------------------------
+ 23. CodeMirror (inside MDXEditor) - Cursor & Gutters
+ -------------------------------------------------------------------------- */
+html[dir="rtl"] .paperclip-mdxeditor .cm-cursor,
+html[dir="rtl"] .paperclip-mdxeditor .cm-dropCursor {
+ border-left-color: transparent !important;
+ border-right-color: #cdd6f4 !important;
+}
+
+html[dir="rtl"] .paperclip-mdxeditor .cm-gutters {
+ border-right: none !important;
+ border-left: 1px solid #313244 !important;
+}
+
+/* --------------------------------------------------------------------------
+ 24. Sidebar Layout (shadcn/ui sidebar pattern)
+
+ The sidebar CSS variables are defined but the layout depends on the
+ app's component structure. These overrides handle common patterns.
+ -------------------------------------------------------------------------- */
+
+/* If sidebar is positioned with left:0, move to right:0 */
+html[dir="rtl"] [data-sidebar="sidebar"] {
+ left: auto;
+ right: 0;
+}
+
+/* Sidebar rail/resize handle */
+html[dir="rtl"] [data-sidebar="rail"] {
+ left: auto;
+ right: 0;
+}
+
+/* Main content margin adjustment when sidebar present */
+html[dir="rtl"] [data-sidebar="content"] {
+ margin-left: 0;
+}
+
+/* --------------------------------------------------------------------------
+ 25. Dialog Overlay - full screen, no directional change needed
+ But ensure overlay covers correctly
+ -------------------------------------------------------------------------- */
+html[dir="rtl"] [class*="_dialogOverlay_"] {
+ left: 0;
+ right: 0;
+}
+
+/* --------------------------------------------------------------------------
+ 26. Radix UI Popover/Dropdown Transform Origins
+ These use CSS variables, so they auto-adapt. No override needed.
+ -------------------------------------------------------------------------- */
+
+/* --------------------------------------------------------------------------
+ 27. Group rotation for collapsible triggers (chevron icons)
+ In RTL, a right-pointing chevron should point left by default
+ and rotate when open
+ -------------------------------------------------------------------------- */
+html[dir="rtl"] .group-data-\[state\=open\]\:rotate-90:is(:where(.group)[data-state=open] *) {
+ rotate: -90deg;
+}
+
+/* --------------------------------------------------------------------------
+ 28. General Hebrew typography adjustments
+ -------------------------------------------------------------------------- */
+html[dir="rtl"] input,
+html[dir="rtl"] textarea,
+html[dir="rtl"] select {
+ text-align: right;
+}
+
+html[dir="rtl"] input[type="email"],
+html[dir="rtl"] input[type="url"],
+html[dir="rtl"] input[type="number"] {
+ text-align: left;
+ direction: ltr;
+}
+
+/* Placeholder text alignment */
+html[dir="rtl"] input::placeholder,
+html[dir="rtl"] textarea::placeholder {
+ text-align: right;
+}
+
+/* --------------------------------------------------------------------------
+ 29. Scrollbar position (WebKit) - move to left side in RTL
+ -------------------------------------------------------------------------- */
+html[dir="rtl"] ::-webkit-scrollbar {
+ /* Scrollbars auto-flip in RTL for most browsers */
+}
+
+/* --------------------------------------------------------------------------
+ 30. Active SVG translate (press feedback) - flip X direction
+ -------------------------------------------------------------------------- */
+html[dir="rtl"] [class*="_toolbarToggleItem_"]:active svg,
+html[dir="rtl"] [class*="_toolbarButton_"]:active svg,
+html[dir="rtl"] [class*="_actionButton_"]:active svg,
+html[dir="rtl"] [class*="_tableColumnEditorTrigger_"]:active svg,
+html[dir="rtl"] [class*="_tableColumnEditorToolbar_"] > button:active svg,
+html[dir="rtl"] [class*="_toggleGroupRoot_"] button:active svg,
+html[dir="rtl"] [class*="_addColumnButton_"]:active svg,
+html[dir="rtl"] [class*="_addRowButton_"]:active svg {
+ transform: translate(-1px, 1px);
+}
+
+/* --------------------------------------------------------------------------
+ 31. Responsive breakpoint overrides
+ -------------------------------------------------------------------------- */
+@media (min-width: 640px) {
+ html[dir="rtl"] .sm\:flex-row {
+ flex-direction: row-reverse;
+ }
+}
+
+@media (min-width: 768px) {
+ html[dir="rtl"] .md\:flex-row {
+ flex-direction: row-reverse;
+ }
+}
+
+@media (min-width: 1024px) {
+ html[dir="rtl"] .lg\:flex-row {
+ flex-direction: row-reverse;
+ }
+}
+
+@media (min-width: 1280px) {
+ html[dir="rtl"] .xl\:flex-row {
+ flex-direction: row-reverse;
+ }
+}
+
+/* --------------------------------------------------------------------------
+ 32. Fix for centered dialogs using left:50% + translate(-50%, -50%)
+ These should remain centered, so override left->right and flip translate
+ -------------------------------------------------------------------------- */
+html[dir="rtl"] [class*="_dialogContent_"],
+html[dir="rtl"] [class*="_largeDialogContent_"] {
+ left: auto;
+ right: 50%;
+ transform: translate(50%, -50%);
+}
+
+@keyframes rtl-contentShow {
+ 0% {
+ opacity: 0;
+ transform: translate(50%, -48%) scale(.96);
+ }
+ to {
+ opacity: 1;
+ transform: translate(50%, -50%) scale(1);
+ }
+}
+
+html[dir="rtl"] [class*="_dialogContent_"],
+html[dir="rtl"] [class*="_largeDialogContent_"] {
+ animation: rtl-contentShow .15s cubic-bezier(.16, 1, .3, 1);
+}
+
+/* --------------------------------------------------------------------------
+ 33. Fix Tailwind space-x utilities
+ These already use margin-inline-start/end, so they should auto-adapt.
+ No override needed for space-x-* classes (they use logical properties).
+ -------------------------------------------------------------------------- */
+
+/* --------------------------------------------------------------------------
+ 34. Override for the bottom-positioned elements with safe-area-inset
+ These are vertical-only, no RTL swap needed.
+ -------------------------------------------------------------------------- */
+
+/* --------------------------------------------------------------------------
+ 35. Miscellaneous icon and decorative element adjustments
+ -------------------------------------------------------------------------- */
+
+/* Ensure icons in buttons don't get mirrored unintentionally */
+html[dir="rtl"] svg {
+ /* Most icons should NOT be mirrored. Only directional icons need it. */
+}
+
+/* Mirror directional icons (arrows, chevrons) */
+html[dir="rtl"] [class*="chevron-left"] svg,
+html[dir="rtl"] [class*="chevron-right"] svg,
+html[dir="rtl"] [class*="arrow-left"] svg,
+html[dir="rtl"] [class*="arrow-right"] svg {
+ transform: scaleX(-1);
+}
+
+/* --------------------------------------------------------------------------
+ COMMENT HEADER — agent name + date row RTL alignment
+ -------------------------------------------------------------------------- */
+html[dir="rtl"] .flex.items-center.justify-between.mb-1 {
+ direction: rtl;
+}
+
+html[dir="rtl"] [href*="/agents/"] {
+ direction: rtl;
+}
+
+/* --------------------------------------------------------------------------
+ ACTIVITY LOG — RTL alignment
+ -------------------------------------------------------------------------- */
+html[dir="rtl"] [id^="activity-"] {
+ direction: rtl;
+ text-align: right;
+}
+
+html[dir="rtl"] [id^="activity-"] .flex-1 {
+ text-align: right;
+}
+
+html[dir="rtl"] [id^="activity-"] .flex.items-start.gap-2\.5 {
+ flex-direction: row-reverse;
+}
+
+/* --------------------------------------------------------------------------
+ TABLES inside comments — RTL alignment
+ -------------------------------------------------------------------------- */
+html[dir="rtl"] .paperclip-markdown table {
+ direction: rtl;
+ text-align: right;
+}
+
+html[dir="rtl"] .paperclip-markdown table th,
+html[dir="rtl"] .paperclip-markdown table td {
+ text-align: right;
+}
+
+html[dir="rtl"] .paperclip-markdown {
+ direction: rtl;
+ text-align: right;
+}
+
+/* --------------------------------------------------------------------------
+ GLOBAL RTL — all flex rows with gap should be RTL
+ -------------------------------------------------------------------------- */
+html[dir="rtl"] [id^="run-"],
+html[dir="rtl"] [id^="activity-"],
+html[dir="rtl"] [id^="comment-"] {
+ direction: rtl;
+}
+
+html[dir="rtl"] [id^="run-"] .flex,
+html[dir="rtl"] [id^="activity-"] .flex,
+html[dir="rtl"] [id^="comment-"] .flex {
+ direction: rtl;
+}
+
+html[dir="rtl"] [id^="run-"] .flex.items-center {
+ flex-direction: row-reverse;
+}
+
+html[dir="rtl"] [id^="run-"] .flex.items-center.gap-2\.5 {
+ flex-direction: row-reverse;
+}
+
+html[dir="rtl"] .min-w-0.flex-1 {
+ text-align: right;
+ direction: rtl;
+}
+
+/* Inner flex rows inside run/activity items — text flows RTL */
+html[dir="rtl"] .min-w-0.flex-1 > .flex {
+ direction: rtl;
+ justify-content: flex-start;
+}
+
+/* The outer row: avatar on right, content on left */
+html[dir="rtl"] .flex.items-center.gap-2\.5.py-1\.5 {
+ direction: rtl;
+}
+
+/* Same for items-start variant (activity log) */
+html[dir="rtl"] .flex.items-start.gap-2\.5.py-1\.5 {
+ direction: rtl;
+}
+
+/* --------------------------------------------------------------------------
+ ACTIVITY TAB — global RTL for all activity content
+ -------------------------------------------------------------------------- */
+html[dir="rtl"] [id*="-content-activity"] {
+ direction: rtl;
+ text-align: right;
+}
+
+html[dir="rtl"] [id*="-content-activity"] .flex {
+ direction: rtl;
+}
+
+html[dir="rtl"] [id*="-content-activity"] .flex.items-center,
+html[dir="rtl"] [id*="-content-activity"] .flex.items-start {
+ direction: rtl;
+}
+
+html[dir="rtl"] [id*="-content-activity"] .min-w-0 {
+ text-align: right;
+}
+
+/* --------------------------------------------------------------------------
+ PROPERTIES PANEL — global RTL
+ -------------------------------------------------------------------------- */
+html[dir="rtl"] [data-slot="sheet-content"],
+html[dir="rtl"] [role="dialog"] {
+ direction: rtl;
+ text-align: right;
+}
+
+html[dir="rtl"] [data-slot="sheet-content"] .flex,
+html[dir="rtl"] [role="dialog"] .flex {
+ direction: rtl;
+}
+
+html[dir="rtl"] [data-slot="sheet-content"] label,
+html[dir="rtl"] [role="dialog"] label {
+ text-align: right;
+}
+
+/* --------------------------------------------------------------------------
+ GLOBAL CATCH-ALL — any remaining LTR flex containers in main content
+ -------------------------------------------------------------------------- */
+html[dir="rtl"] main {
+ direction: rtl;
+}
+
+html[dir="rtl"] main .flex.items-center {
+ direction: rtl;
+}
+
+html[dir="rtl"] main .flex.items-start {
+ direction: rtl;
+}
+
+html[dir="rtl"] main .min-w-0 {
+ text-align: right;
+}
+
+html[dir="rtl"] main .space-y-1\.5,
+html[dir="rtl"] main .space-y-2,
+html[dir="rtl"] main .space-y-3,
+html[dir="rtl"] main .space-y-4 {
+ direction: rtl;
+ text-align: right;
+}
+
+/* --------------------------------------------------------------------------
+ PROPERTIES SIDEBAR — the p-4 container with property rows
+ -------------------------------------------------------------------------- */
+html[dir="rtl"] .p-4 .space-y-4,
+html[dir="rtl"] .p-4 .space-y-1 {
+ direction: rtl;
+ text-align: right;
+}
+
+/* Property row: label (w-20) on right, value on left */
+html[dir="rtl"] .p-4 .flex.items-center.gap-3.py-1\.5 {
+ direction: rtl;
+}
+
+/* The label span */
+html[dir="rtl"] .p-4 .shrink-0.w-20 {
+ text-align: right;
+}
+
+/* --------------------------------------------------------------------------
+ BREADCRUMB — RTL direction + flip chevron separator
+ -------------------------------------------------------------------------- */
+html[dir="rtl"] [data-slot="breadcrumb"] {
+ direction: rtl;
+}
+
+html[dir="rtl"] [data-slot="breadcrumb-list"] {
+ direction: rtl;
+}
+
+html[dir="rtl"] [data-slot="breadcrumb-separator"] svg {
+ transform: scaleX(-1);
+}
+
+/* Top header bar */
+html[dir="rtl"] .border-b.border-border .flex.items-center {
+ direction: rtl;
+}
+
+/* --------------------------------------------------------------------------
+ FILTER BAR — the "For [assignee] in [project]" row
+ -------------------------------------------------------------------------- */
+html[dir="rtl"] .overflow-x-auto .inline-flex.items-center.gap-2 {
+ direction: rtl;
+}
+
+/* --------------------------------------------------------------------------
+ PLUGIN PAGE + CARDS — RTL for all card content
+ -------------------------------------------------------------------------- */
+html[dir="rtl"] [data-slot="tabs"][dir="ltr"] {
+ direction: rtl !important;
+}
+
+html[dir="rtl"] [data-slot="card"],
+html[dir="rtl"] [data-slot="card-header"],
+html[dir="rtl"] [data-slot="card-content"],
+html[dir="rtl"] [data-slot="card-title"] {
+ direction: rtl;
+ text-align: right;
+}
+
+html[dir="rtl"] [data-slot="card-content"] .flex.justify-between {
+ direction: rtl;
+}
+
+html[dir="rtl"] [data-slot="card-content"] .flex.items-center.justify-between {
+ direction: rtl;
+}
+
+html[dir="rtl"] [data-slot="card-content"] .grid {
+ direction: rtl;
+}
+
+html[dir="rtl"] [data-slot="card-description"] {
+ text-align: right;
+}
+
+/* Status change row: reverse order so old→new reads RTL */
+html[dir="rtl"] .flex.flex-wrap.items-center.gap-2.text-sm {
+ direction: rtl;
+}
+
+/* Flip the arrow in status change rows */
+html[dir="rtl"] .flex.flex-wrap.items-center.gap-2.text-sm .lucide-arrow-right {
+ transform: scaleX(-1);
+}
+
+/* --------------------------------------------------------------------------
+ PROPERTIES PANEL (aside) - RTL fixes
+ -------------------------------------------------------------------------- */
+
+/* Fix truncation direction: show start of text, not end */
+html[dir="rtl"] aside .truncate {
+ direction: rtl;
+ text-align: right;
+ text-overflow: ellipsis;
+}
+
+/* Widen properties panel to fill the gap */
+html[dir="rtl"] aside.hidden.md\:flex {
+ width: 460px !important;
+}
+html[dir="rtl"] aside .w-80 {
+ width: 460px;
+ min-width: 460px;
+}
+
+/* Ensure property labels don't shrink too much */
+html[dir="rtl"] aside .shrink-0.w-20 {
+ width: 5.5rem;
+}
+
+/* Properties panel rows: reverse flex so label is on the right */
+html[dir="rtl"] aside .flex.items-center.gap-3.py-1\.5 {
+ flex-direction: row-reverse;
+}
+
+/* Property value containers: align right */
+html[dir="rtl"] aside .flex.items-center.gap-1\.5.min-w-0.flex-1 {
+ flex-direction: row-reverse;
+ justify-content: flex-start;
+}
+
+/* Property buttons inside panel: reverse icon+text order */
+html[dir="rtl"] aside .flex.items-center.gap-1\.5.min-w-0.flex-1 button {
+ flex-direction: row-reverse;
+}
+
+/* Panel header */
+html[dir="rtl"] aside .flex.items-center.justify-between {
+ flex-direction: row-reverse;
+}
+
+/* Panel text alignment */
+html[dir="rtl"] aside .text-sm {
+ text-align: right;
+}
+
+html[dir="rtl"] aside .text-xs.text-muted-foreground.shrink-0 {
+ text-align: right;
+}
+
+/* --------------------------------------------------------------------------
+ TIMELINE + COMMENT BOX - newest first, editor after newest
+ Comment reordering is handled by JS (translate-he.js: reverseComments).
+ CSS column-reverse removed to avoid double-reverse conflicts.
+ -------------------------------------------------------------------------- */
diff --git a/scripts/paperclip-assets/translate-he.js b/scripts/paperclip-assets/translate-he.js
new file mode 100644
index 0000000..1e1b724
--- /dev/null
+++ b/scripts/paperclip-assets/translate-he.js
@@ -0,0 +1,1351 @@
+/**
+ * Paperclip AI - Hebrew Translation Injection
+ * Replaces English UI text with Hebrew after React renders.
+ * Uses MutationObserver to catch route changes and dynamic content.
+ */
+(function () {
+ "use strict";
+
+ // =========================================================================
+ // TRANSLATION MAP
+ // =========================================================================
+ const T = {
+ // --- Sidebar / Navigation ---
+ "Dashboard": "לוח בקרה",
+ "Inbox": "תיבת דואר",
+ "Work": "עבודה",
+ "Issues": "משימות",
+ "Routines": "שגרות",
+ "Goals": "יעדים",
+ "Company": "חברה",
+ "Org": "ארגון",
+ "Skills": "כישורים",
+ "Costs": "עלויות",
+ "Activity": "פעילות",
+ "Settings": "הגדרות",
+ "General": "כללי",
+ "Heartbeats": "פעימות",
+ "Experimental": "ניסיוני",
+ "Plugins": "תוספים",
+ "Me": "אני",
+ "Agents": "סוכנים",
+ "Projects": "פרויקטים",
+ "Home": "בית",
+ "Create": "צור",
+ "Not Found": "לא נמצא",
+ "Open sidebar": "פתח סרגל צד",
+ "Close sidebar": "סגור סרגל צד",
+ "Skip to Main Content": "דלג לתוכן הראשי",
+
+ // --- Common Buttons ---
+ "Save": "שמור",
+ "Cancel": "ביטול",
+ "Delete": "מחק",
+ "Edit": "ערוך",
+ "Update": "עדכן",
+ "Close": "סגור",
+ "Confirm": "אשר",
+ "Back": "חזור",
+ "Next": "הבא",
+ "Previous": "הקודם",
+ "Done": "סיום",
+ "Apply": "החל",
+ "Continue": "המשך",
+ "Dismiss": "סגור",
+ "Clear": "נקה",
+ "Reset": "אפס",
+ "Retry": "נסה שוב",
+ "Submit": "שלח",
+ "OK": "אישור",
+ "Yes": "כן",
+ "No": "לא",
+ "Go": "עבור",
+ "Search": "חיפוש",
+ "Filter": "סינון",
+ "Sort": "מיון",
+ "Copy": "העתק",
+ "Download": "הורד",
+ "Upload": "העלה",
+ "Export": "ייצוא",
+ "Import": "ייבוא",
+ "Enable": "הפעל",
+ "Disable": "השבת",
+ "Install": "התקן",
+ "Uninstall": "הסר התקנה",
+ "Start": "התחל",
+ "Stop": "עצור",
+ "Pause": "השהה",
+ "Resume": "חדש",
+ "Run": "הפעל",
+ "Launch": "הפעל",
+ "Approve": "אשר",
+ "Reject": "דחה",
+ "Archive": "ארכיון",
+ "Restore": "שחזר",
+ "Pin": "הצמד",
+ "Revoke": "בטל",
+ "Assign": "הקצה",
+ "Block": "חסום",
+ "Link": "קישור",
+ "View": "צפה",
+ "Show": "הצג",
+ "Hide": "הסתר",
+ "Open": "פתח",
+ "Select": "בחר",
+ "Remove": "הסר",
+ "Comment": "תגובה",
+ "Restart": "הפעל מחדש",
+ "Schedule": "תזמן",
+ "Configure": "הגדר",
+ "Choose": "בחר",
+
+ // --- Activity Log ---
+ "updated this task": "עדכן משימה זו",
+ "created this task": "יצר משימה זו",
+ "created this issue": "יצר משימה זו",
+ "updated this issue": "עדכן משימה זו",
+ "commented on this task": "הגיב על משימה זו",
+ "commented on this issue": "הגיב על משימה זו",
+ "assigned this task": "הקצה משימה זו",
+ "assigned this issue": "הקצה משימה זו",
+ "changed status": "שינה סטטוס",
+ "changed priority": "שינה עדיפות",
+ "unassigned this task": "ביטל הקצאת משימה",
+ "checked out this task": "לקח משימה",
+ "released this task": "שחרר משימה",
+ "just now": "הרגע",
+ "1m ago": "לפני דקה",
+ "2m ago": "לפני 2 דקות",
+ "3m ago": "לפני 3 דקות",
+ "5m ago": "לפני 5 דקות",
+ "10m ago": "לפני 10 דקות",
+ "15m ago": "לפני 15 דקות",
+ "20m ago": "לפני 20 דקות",
+ "25m ago": "לפני 25 דקות",
+ "28m ago": "לפני 28 דקות",
+ "30m ago": "לפני 30 דקות",
+ "45m ago": "לפני 45 דקות",
+ "1h ago": "לפני שעה",
+ "2h ago": "לפני שעתיים",
+ "3h ago": "לפני 3 שעות",
+ "yesterday": "אתמול",
+ "You": "אני",
+ "Copy as markdown": "העתק כ-markdown",
+
+ // --- Run Statuses ---
+ "succeeded": "הצליח",
+ "failed": "נכשל",
+ "running": "רץ",
+ "timed_out": "חרג מזמן",
+ "queued": "בתור",
+ "skipped": "דולג",
+ "blocked": "חסום",
+ "completed": "הושלם",
+ "cancelled": "בוטל",
+ "started": "התחיל",
+
+ // --- Activity Log Actions ---
+ "started a run": "התחיל ריצה",
+ "completed a run": "השלים ריצה",
+ "checked out": "לקח לטיפול",
+ "released": "שחרר",
+ "moved to": "עבר ל",
+ "changed status to": "שינה סטטוס ל",
+ "assigned to": "הוקצה ל",
+ "unassigned from": "בוטלה הקצאה מ",
+ "added a comment": "הוסיף תגובה",
+ "ran": "הריץ",
+ "set priority": "קבע עדיפות",
+ "set status": "קבע סטטוס",
+
+ // --- Run Details ---
+ "Transcript": "תמליל",
+ "No transcript captured": "לא נקלט תמליל",
+ "No transcript captured.": "לא נקלט תמליל.",
+ "Run details": "פרטי ריצה",
+ "Duration": "משך",
+ "Tokens": "טוקנים",
+ "Cost": "עלות",
+ "Model": "מודל",
+ "Turns": "סיבובים",
+ "Exit code": "קוד יציאה",
+ "Error": "שגיאה",
+ "Heartbeat": "פעימה",
+ "Heartbeats": "פעימות",
+ "Latest run": "ריצה אחרונה",
+ "All runs": "כל הריצות",
+ "No runs yet": "אין ריצות עדיין",
+ "No runs yet.": "אין ריצות עדיין.",
+ "Run": "ריצה",
+ "Runs": "ריצות",
+ "Input tokens": "טוקני קלט",
+ "Output tokens": "טוקני פלט",
+ "Cache read": "קריאה ממטמון",
+ "Cache write": "כתיבה למטמון",
+ "Total cost": "עלות כוללת",
+ "Session": "סשן",
+ "Agent": "סוכן",
+ "Source": "מקור",
+ "Trigger": "טריגר",
+ "on_demand": "לפי דרישה",
+ "manual": "ידני",
+ "timer": "טיימר",
+ "assignment": "הקצאה",
+ "automation": "אוטומציה",
+
+ // --- Filter/Context ---
+ "For": "עבור",
+ "for": "עבור",
+ "in": "ב",
+ "In": "ב",
+ "of": "של",
+ "to": "ל",
+ "by": "על ידי",
+ "from": "מ",
+ "with": "עם",
+ "and": "ו",
+ "or": "או",
+ "on": "ב",
+ "at": "ב",
+ "as": "בתור",
+ "via": "דרך",
+ "No results": "אין תוצאות",
+ "No results.": "אין תוצאות.",
+ "No items": "אין פריטים",
+ "No data": "אין נתונים",
+
+ // --- Settings Page ---
+ "General Settings": "הגדרות כלליות",
+ "Server Configuration": "הגדרות שרת",
+ "Deployment Mode": "מצב פריסה",
+ "Exposure": "חשיפה",
+ "Allowed Hostnames": "שמות מארח מורשים",
+ "Public Base URL": "כתובת URL ציבורית",
+ "Disable Sign Up": "ביטול הרשמה",
+ "Disable sign up": "ביטול הרשמה",
+ "Backup Settings": "הגדרות גיבוי",
+ "Backup Interval": "מרווח גיבוי",
+ "Retention Days": "ימי שמירה",
+ "Database Mode": "מצב מסד נתונים",
+ "Embedded PostgreSQL": "PostgreSQL מובנה",
+ "Storage Provider": "ספק אחסון",
+ "Local Disk": "דיסק מקומי",
+ "Secret Provider": "ספק סודות",
+ "Logging Mode": "מצב לוגים",
+ "Log Directory": "תיקיית לוגים",
+ "Save Changes": "שמור שינויים",
+ "Configuration saved": "ההגדרות נשמרו",
+ "Configuration saved.": "ההגדרות נשמרו.",
+ "Restart required": "נדרש הפעלה מחדש",
+ "Instance": "מופע",
+ "Server": "שרת",
+ "Auth": "אימות",
+ "Authentication": "אימות",
+ "Sign-up": "הרשמה",
+ "Allowed": "מורשה",
+ "Port": "פורט",
+ "Host": "מארח",
+ "public": "ציבורי",
+ "private": "פרטי",
+ "authenticated": "מאומת",
+ "enabled": "מופעל",
+ "disabled": "מושבת",
+ "Database": "מסד נתונים",
+ "Backups": "גיבויים",
+ "Storage": "אחסון",
+ "Secrets": "סודות",
+ "Logging": "לוגים",
+ "Server port": "פורט שרת",
+ "Listen host": "מארח האזנה",
+ "Base URL": "כתובת בסיס",
+ "Interval (minutes)": "מרווח (דקות)",
+ "Retention (days)": "שמירה (ימים)",
+ "Data directory": "תיקיית נתונים",
+ "Backup directory": "תיקיית גיבוי",
+ "Key file path": "נתיב קובץ מפתח",
+ "Mode": "מצב",
+ "Provider": "ספק",
+ "Path": "נתיב",
+ "Danger Zone": "אזור סכנה",
+
+ // --- Experimental Page ---
+ "Opt into features that are still being evaluated before they become default behavior.": "הצטרף לפיצ׳רים שעדיין בהערכה לפני שהם הופכים לברירת מחדל.",
+ "Enable Isolated Workspaces": "הפעל סביבות עבודה מבודדות",
+ "Show execution workspace controls in project configuration and allow isolated workspace behavior for new and existing issue runs.": "הצג אפשרויות סביבת עבודה בהגדרות פרויקט ואפשר התנהגות מבודדת לריצות חדשות וקיימות.",
+ "Auto-Restart Dev Server When Idle": "הפעלה מחדש אוטומטית של שרת פיתוח בזמן חוסר פעילות",
+ "In `pnpm dev:once`, wait for all queued and running local agent runs to finish, then restart the server automatically when backend changes or migrations make the current boot stale.": "ב-pnpm dev:once, המתן לסיום כל ריצות הסוכנים בתור וברצף, ואז הפעל מחדש אוטומטית כששינויים בשרת הופכים את האתחול הנוכחי למיושן.",
+
+ // --- Plugin Status Page ---
+ "Runtime Dashboard": "לוח בקרה תפעולי",
+ "Worker process, scheduled jobs, and webhook deliveries": "תהליך עובד, משימות מתוזמנות ומשלוחי webhook",
+ "Worker Process": "תהליך עובד",
+ "Pending RPCs": "קריאות ממתינות",
+ "Uptime": "זמן פעילות",
+ "Recent Job Runs": "ריצות אחרונות",
+ "Recent Webhook Deliveries": "משלוחי webhook אחרונים",
+ "No webhook deliveries recorded yet.": "טרם נרשמו משלוחי webhook.",
+ "Last checked": "בדיקה אחרונה",
+ "Health Status": "מצב בריאות",
+ "Overall": "כולל",
+ "ready": "מוכן",
+ "error": "שגיאה",
+ "registry": "רישום",
+ "manifest": "מניפסט",
+ "error_state": "מצב שגיאה",
+ "Permissions": "הרשאות",
+ "Details": "פרטים",
+ "Plugin ID": "מזהה תוסף",
+ "Plugin Key": "מפתח תוסף",
+ "NPM Package": "חבילת NPM",
+ "Version": "גרסה",
+ "Configuration": "הגדרות",
+ "Status": "סטטוס",
+
+ // --- Action Buttons ---
+ "Disable All": "השבת הכל",
+ "Enable All": "הפעל הכל",
+ "Disable all": "השבת הכל",
+ "Enable all": "הפעל הכל",
+ "Select All": "בחר הכל",
+ "Select all": "בחר הכל",
+ "Deselect All": "בטל בחירה",
+ "Deselect all": "בטל בחירה",
+ "Clear All": "נקה הכל",
+ "Clear all": "נקה הכל",
+ "Remove All": "הסר הכל",
+ "Remove all": "הסר הכל",
+ "Delete All": "מחק הכל",
+ "Delete all": "מחק הכל",
+ "Refresh": "רענן",
+ "Reload": "טען מחדש",
+ "Load More": "טען עוד",
+ "Load more": "טען עוד",
+ "Show More": "הצג עוד",
+ "Show more": "הצג עוד",
+ "Show Less": "הצג פחות",
+ "Show less": "הצג פחות",
+ "View All": "הצג הכל",
+ "View all": "הצג הכל",
+ "Expand All": "הרחב הכל",
+ "Expand all": "הרחב הכל",
+ "Collapse All": "צמצם הכל",
+ "Collapse all": "צמצם הכל",
+ "Copy ID": "העתק מזהה",
+ "Copy URL": "העתק כתובת",
+ "Go to": "עבור אל",
+ "Jump to": "קפוץ אל",
+ "Mark all": "סמן הכל",
+ "Danger zone": "אזור סכנה",
+ "Reset": "איפוס",
+ "Reset instance": "איפוס מופע",
+ "This action cannot be undone.": "לא ניתן לבטל פעולה זו.",
+ "Are you sure?": "האם אתה בטוח?",
+
+ // --- Settings: General Tab ---
+ "Configure instance-wide defaults that affect how operator-visible logs are displayed.": "הגדר ברירות מחדל ברמת המופע שמשפיעות על אופן הצגת הלוגים.",
+ "Censor username in logs": "הסתר שם משתמש בלוגים",
+ "Hide the username segment in home-directory paths and similar operator-visible log output. Standalone username mentions outside of paths are not yet masked in the live transcript view. This is off by default.": "הסתר את שם המשתמש בנתיבי תיקיות ובפלט לוגים. אזכורי שם משתמש עצמאיים מחוץ לנתיבים עדיין אינם מוסתרים בתצוגת התמליל החי. מושבת כברירת מחדל.",
+
+ // --- Settings: Keyboard Shortcuts ---
+ "Keyboard Shortcuts": "קיצורי מקלדת",
+ "Enable app keyboard shortcuts, including inbox navigation and global shortcuts like creating issues or toggling panels. This is off by default.": "הפעל קיצורי מקלדת באפליקציה, כולל ניווט בתיבת הדואר וקיצורים גלובליים כמו יצירת משימות או מעבר בין פנלים. מושבת כברירת מחדל.",
+
+ // --- Settings: AI Feedback ---
+ "AI Feedback Sharing": "שיתוף משוב AI",
+ "Control whether thumbs up and thumbs down votes can send the voted AI output to Paperclip Labs. Votes are always saved locally.": "קבע אם הצבעות אגודל למעלה ולמטה ישלחו את פלט ה-AI ל-Paperclip Labs. ההצבעות תמיד נשמרות מקומית.",
+ "Read our Terms of Service": "קרא את תנאי השירות שלנו",
+ "No default is saved yet. The next thumbs up or thumbs down choice will ask once and then save the answer here.": "טרם נשמרה בחירת ברירת מחדל. ההצבעה הבאה תשאל פעם אחת ותשמור את התשובה כאן.",
+ "Always allow": "אפשר תמיד",
+ "Always Allow": "אפשר תמיד",
+ "Share voted AI outputs automatically.": "שתף פלטי AI שנבחרו אוטומטית.",
+ "Never allow": "אל תאפשר",
+ "Never Allow": "אל תאפשר",
+ "Keep voted AI outputs local only.": "שמור פלטי AI שנבחרו מקומית בלבד.",
+ "To retest the first-use prompt in local dev, remove the feedbackDataSharingPreference key from the instance_settings.general JSON row for this instance, or set it back to \"prompt\". Unset and \"prompt\" both mean no default has been chosen yet.": "לבדיקה מחדש של ההנחיה הראשונית, הסר את המפתח feedbackDataSharingPreference מטבלת instance_settings או החזר ל-prompt.",
+
+ // --- Tabs & Sections ---
+ "Sub-issues": "תת-משימות",
+ "Subissues": "תת-משימות",
+ "sub-issues": "תת-משימות",
+ "Work Products": "תוצרי עבודה",
+ "Linked": "מקושר",
+ "Related": "קשור",
+ "Parent": "משימת אב",
+ "Timeline": "ציר זמן",
+ "History": "היסטוריה",
+ "Approvals": "אישורים",
+
+ // --- Comments Section ---
+ "No comments yet": "אין תגובות עדיין",
+ "No comments yet.": "אין תגובות עדיין.",
+ "Add a comment": "הוסף תגובה",
+ "Write a comment": "כתוב תגובה",
+ "Write a comment...": "כתוב תגובה...",
+ "Type a comment": "הקלד תגובה",
+ "Type a comment...": "הקלד תגובה...",
+
+ // --- Activity Section ---
+ "No activity yet": "אין פעילות עדיין",
+ "No activity yet.": "אין פעילות עדיין.",
+
+ // --- Sub-issues Section ---
+ "No sub-issues": "אין תת-משימות",
+ "No sub-issues.": "אין תת-משימות.",
+ "Create sub-issue": "צור תת-משימה",
+ "Add sub-issue": "הוסף תת-משימה",
+
+ // --- Action Buttons ---
+ "Save changes": "שמור שינויים",
+ "Save Configuration": "שמור הגדרות",
+ "Save note": "שמור הערה",
+ "Save routine": "שמור שגרה",
+ "Save trigger": "שמור טריגר",
+ "Save failed": "השמירה נכשלה",
+ "Add Agent": "הוסף סוכן",
+ "Add Goal": "הוסף יעד",
+ "Add Project": "הוסף פרויקט",
+ "Add company": "הוסף חברה",
+ "Add item": "הוסף פריט",
+ "Add trigger": "הוסף טריגר",
+ "Add a new agent": "הוסף סוכן חדש",
+ "Add a skill source": "הוסף מקור כישורים",
+ "Add a short note": "הוסף הערה קצרה",
+ "Add a comment...": "הוסף תגובה...",
+ "Add a description...": "הוסף תיאור...",
+ "Add description...": "הוסף תיאור...",
+ "Add instructions...": "הוסף הוראות...",
+ "Adding...": "מוסיף...",
+ "Create Issue": "צור משימה",
+ "Create Item": "צור פריט",
+ "Create Account": "צור חשבון",
+ "Create API Key": "צור מפתח API",
+ "Create agent": "צור סוכן",
+ "Create document": "צור מסמך",
+ "Create goal": "צור יעד",
+ "Create label": "צור תווית",
+ "Create one": "צור אחד",
+ "Create one here": "צור כאן",
+ "Create project": "צור פרויקט",
+ "Create routine": "צור שגרה",
+ "Create skill": "צור כישור",
+ "Create new agent": "צור סוכן חדש",
+ "Create new company": "צור חברה חדשה",
+ "Create new issue": "צור משימה חדשה",
+ "Create new project": "צור פרויקט חדש",
+ "Create another company": "צור חברה נוספת",
+ "Create a new agent": "צור סוכן חדש",
+ "Create your Paperclip account": "צור את חשבון Paperclip שלך",
+ "Create your first agent": "צור את הסוכן הראשון שלך",
+ "Create your first company": "צור את החברה הראשונה שלך",
+ "Delete Company": "מחק חברה",
+ "Delete attachment": "מחק קובץ מצורף",
+ "Delete document": "מחק מסמך",
+ "Delete failed": "המחיקה נכשלה",
+ "Delete image": "מחק תמונה",
+ "Delete issue": "מחק משימה",
+ "Edit document": "ערוך מסמך",
+ "Edit image": "ערוך תמונה",
+ "Copy Agent ID": "העתק מזהה סוכן",
+ "Copy to clipboard": "העתק ללוח",
+ "Copy snippet": "העתק קטע",
+ "Copy document": "העתק מסמך",
+ "Approve CLI access": "אשר גישת CLI",
+ "Approve Paperclip CLI access": "אשר גישת Paperclip CLI",
+ "Approving...": "מאשר...",
+ "Archive company": "העבר חברה לארכיון",
+ "Assign Task": "הקצה משימה",
+ "Assign to me": "הקצה לי",
+ "Assign to requester": "הקצה למבקש",
+ "Import company": "ייבא חברה",
+ "Import complete": "הייבוא הושלם",
+ "Import failed": "הייבוא נכשל",
+ "Import preview": "תצוגה מקדימה של ייבוא",
+ "Import source": "מקור ייבוא",
+ "Export company": "ייצא חברה",
+ "Export downloaded": "הייצוא הורד",
+ "Export failed": "הייצוא נכשל",
+ "Install Plugin": "התקן תוסף",
+ "Install Example": "התקן דוגמה",
+ "Install update": "התקן עדכון",
+ "Uninstall Plugin": "הסר תוסף",
+ "Run now": "הפעל עכשיו",
+ "Run routine": "הפעל שגרה",
+ "Run Activity": "הפעל פעילות",
+ "Run Heartbeat": "הפעל פעימה",
+ "Open board": "פתח לוח",
+ "Open budgets": "פתח תקציבים",
+ "Open command palette": "פתח לוח פקודות",
+ "Open Command Palette": "פתח לוח פקודות",
+ "Open dashboard": "פתח לוח בקרה",
+ "Open docs": "פתח מסמכים",
+ "Open Settings": "פתח הגדרות",
+ "Open Issues": "משימות פתוחות",
+ "Open Side Panel": "פתח פאנל צדי",
+ "View agent": "צפה בסוכן",
+ "View details": "צפה בפרטים",
+ "View full error": "צפה בשגיאה מלאה",
+ "View inbox": "צפה בתיבת דואר",
+ "View run": "צפה בהרצה",
+ "Mark all as read": "סמן הכל כנקרא",
+ "Mark as done": "סמן כבוצע",
+ "Mark as read": "סמן כנקרא",
+ "Clear all": "נקה הכל",
+ "Clear repo": "נקה מאגר",
+ "Clear local folder": "נקה תיקיה מקומית",
+ "Sign in": "התחבר",
+ "Sign in required": "נדרשת התחברות",
+ "Sign in to Paperclip": "התחבר ל-Paperclip",
+ "Sign in / Create account": "התחבר / צור חשבון",
+ "Go home": "חזור לדף הבית",
+ "Back to all workspaces": "חזור לכל סביבות העבודה",
+ "Back to approvals": "חזור לאישורים",
+ "Back to runs": "חזור להרצות",
+ "Back to workspaces": "חזור לסביבות עבודה",
+ "Check for updates": "בדוק עדכונים",
+ "Start Onboarding": "התחל הקמה",
+ "Stop editing": "הפסק עריכה",
+ "Deploy to production": "פרוס לייצור",
+ "Restart Required": "נדרש הפעלה מחדש",
+ "Reset Sessions": "אפס הפעלות",
+ "Reset defaults": "אפס ברירות מחדל",
+ "Reset filters": "אפס מסננים",
+ "Download document": "הורד מסמך",
+ "Upload attachment": "העלה קובץ מצורף",
+ "Upload an image": "העלה תמונה",
+ "Upload failed": "ההעלאה נכשלה",
+ "Filter Bar": "סרגל סינון",
+ "Filter by agent name": "סנן לפי שם סוכן",
+ "Filter by type": "סנן לפי סוג",
+ "Filter skills": "סנן כישורים",
+ "Show properties": "הצג מאפיינים",
+ "Show secret": "הצג סוד",
+ "Hide secret": "הסתר סוד",
+ "Show full log": "הצג יומן מלא",
+ "Hide full log": "הסתר יומן מלא",
+ "Set repo": "הגדר מאגר",
+ "Change repo": "שנה מאגר",
+ "Submit join request": "שלח בקשת הצטרפות",
+ "Join request submitted": "בקשת ההצטרפות נשלחה",
+ "Accept bootstrap invite": "קבל הזמנת הקמה",
+ "Return to latest": "חזור לעדכני",
+ "Jump to live": "עבור לשידור חי",
+ "Select company": "בחר חברה",
+ "Select model": "בחר מודל",
+ "Select status": "בחר סטטוס",
+ "Select an option": "בחר אפשרות",
+ "Watch issue": "עקוב אחר משימה",
+ "Wake now": "העיר עכשיו",
+ "Keep my draft": "שמור את הטיוטה שלי",
+ "Keep paused": "השאר מושהה",
+ "Discard Draft": "מחק טיוטה",
+
+ // --- Navigation Tabs ---
+ "Overview": "סקירה כללית",
+ "Instructions": "הוראות",
+ "Configuration": "הגדרות",
+ "Runs": "הרצות",
+ "Budget": "תקציב",
+ "Workspaces": "סביבות עבודה",
+ "All": "הכל",
+ "Active": "פעיל",
+ "Paused": "מושהה",
+ "Error": "שגיאה",
+ "Recent": "אחרונים",
+ "Mine": "שלי",
+ "Unread": "לא נקרא",
+ "Status": "סטטוס",
+
+ // --- Status Labels ---
+ "Backlog": "רשימת המתנה",
+ "Todo": "לביצוע",
+ "In Progress": "בביצוע",
+ "In Review": "בסקירה",
+ "Planned": "מתוכנן",
+ "Completed": "הושלם",
+ "Cancelled": "בוטל",
+ "Critical": "קריטי",
+ "High": "גבוה",
+ "Medium": "בינוני",
+ "Low": "נמוך",
+ "Default": "ברירת מחדל",
+ "Blocked": "חסום",
+ "Queued": "בתור",
+ "Running": "פועל",
+ "Enabled": "מופעל",
+ "Disabled": "מושבת",
+ "Pending": "ממתין",
+ "Resolved": "נפתר",
+ "Unknown": "לא ידוע",
+ "New": "חדש",
+ "Archived": "בארכיון",
+ "Passed": "עבר",
+ "Failed": "נכשל",
+ "Managed": "מנוהל",
+ "Live": "חי",
+ "Observed": "נצפה",
+ "Cached": "במטמון",
+ "Sealed": "חתום",
+ "Recommended": "מומלץ",
+ "Beta": "בטא",
+ "Unlimited budget": "תקציב ללא הגבלה",
+ "Under budget": "בתוך התקציב",
+ "Out of date": "לא מעודכן",
+ "Up to date": "מעודכן",
+ "Not set.": "לא הוגדר.",
+ "Not installed": "לא מותקן",
+
+ // --- Thinking Effort ---
+ "Auto": "אוטומטי",
+ "Minimal": "מינימלי",
+ "X-High": "גבוה מאוד",
+ "Max": "מקסימום",
+
+ // --- Workspace Options ---
+ "Project default": "ברירת מחדל של פרויקט",
+ "New isolated workspace": "סביבת עבודה מבודדת חדשה",
+ "Reuse existing workspace": "שימוש חוזר בסביבה קיימת",
+ "Remote git repo": "מאגר git מרוחק",
+ "Local git checkout": "checkout מקומי של git",
+ "Local non-git path": "נתיב מקומי ללא git",
+ "Remote-managed workspace": "סביבת עבודה מנוהלת מרחוק",
+ "Git worktree": "Git worktree",
+ "Local folder": "תיקיה מקומית",
+
+ // --- Frequency Options ---
+ "Every minute": "כל דקה",
+ "Every hour": "כל שעה",
+ "Every day": "כל יום",
+ "Weekdays": "ימי חול",
+ "Weekly": "שבועי",
+ "Monthly": "חודשי",
+ "Custom (cron)": "מותאם אישית (cron)",
+
+ // --- Dashboard Cards ---
+ "Agents Enabled": "סוכנים מופעלים",
+ "Tasks In Progress": "משימות בביצוע",
+ "Month Spend": "הוצאות החודש",
+ "Pending Approvals": "אישורים ממתינים",
+ "Active Agents": "סוכנים פעילים",
+ "Active incidents": "תקלות פעילות",
+ "Active Keys": "מפתחות פעילים",
+ "Companies": "חברות",
+ "Live Runs": "הרצות חיות",
+ "Recent Activity": "פעילות אחרונה",
+ "Recent Issues": "משימות אחרונות",
+ "Recent Tasks": "משימות אחרונות",
+ "Success Rate": "אחוז הצלחה",
+ "Failed runs": "הרצות שנכשלו",
+ "Cost Summary": "סיכום עלויות",
+
+ // --- Page Titles ---
+ "Company Settings": "הגדרות חברה",
+ "Instance Settings": "הגדרות מופע",
+ "Approvals": "אישורים",
+ "Plugin Manager": "מנהל תוספים",
+ "Available Plugins": "תוספים זמינים",
+ "Installed Plugins": "תוספים מותקנים",
+ "Design Guide": "מדריך עיצוב",
+ "Org Chart": "מבנה ארגוני",
+ "Finance": "כספים",
+ "Budgets": "תקציבים",
+ "Budget control plane": "מישור בקרת תקציב",
+ "Scheduler Heartbeats": "פעימות מתזמן",
+ "Run Detail": "פרטי הרצה",
+ "Issue List": "רשימת משימות",
+ "Issue Properties": "מאפייני משימה",
+ "Execution Workspaces": "סביבות ביצוע",
+ "Company Packages": "חבילות חברה",
+ "Keyboard Shortcuts": "קיצורי מקלדת",
+ "Danger Zone": "אזור מסוכן",
+ "New Agent": "סוכן חדש",
+ "New Company": "חברה חדשה",
+ "New Issue": "משימה חדשה",
+ "New document": "מסמך חדש",
+ "New issue": "משימה חדשה",
+ "New project": "פרויקט חדש",
+ "New routine": "שגרה חדשה",
+ "Revision history": "היסטוריית גרסאות",
+
+ // --- Form Labels ---
+ "Name": "שם",
+ "Title": "כותרת",
+ "Description": "תיאור",
+ "Priority": "עדיפות",
+ "Assignee": "מוקצה",
+ "Project": "פרויקט",
+ "Labels": "תוויות",
+ "Created": "נוצר",
+ "Updated": "עודכן",
+ "Target Date": "תאריך יעד",
+ "Start date": "תאריך התחלה",
+ "Lead": "אחראי",
+ "Author": "מחבר",
+ "Email": "אימייל",
+ "Password": "סיסמה",
+ "Company name": "שם חברה",
+ "Agent name": "שם סוכן",
+ "Branch name": "שם ענף",
+ "Branch template": "תבנית ענף",
+ "Base ref": "הפניית בסיס",
+ "Repo URL": "כתובת מאגר",
+ "Brand color": "צבע מותג",
+ "Command": "פקודה",
+ "Adapter type": "סוג מתאם",
+ "Prompt Template": "תבנית פרומפט",
+ "Environment variables": "משתני סביבה",
+ "Timeout (sec)": "זמן קצוב (שניות)",
+ "Max concurrent runs": "הרצות מקבילות מקסימום",
+ "Max turns per run": "סיבובים מקסימום להרצה",
+ "Model": "מודל",
+ "Thinking effort": "מאמץ חשיבה",
+ "Reports to": "מדווח ל",
+ "Capabilities": "יכולות",
+ "Capabilities (optional)": "יכולות (אופציונלי)",
+ "Role": "תפקיד",
+ "Budget (USD)": "תקציב (דולר)",
+ "New budget (USD)": "תקציב חדש (דולר)",
+ "Heartbeat on interval": "פעימה במרווחי זמן",
+ "Wake on demand": "התעוררות לפי דרישה",
+ "Default model": "מודל ברירת מחדל",
+ "Collision strategy": "אסטרטגיית התנגשות",
+ "Description (optional)": "תיאור (אופציונלי)",
+ "Workspace name": "שם סביבת עבודה",
+ "Execution workspace": "סביבת ביצוע",
+ "Provision command": "פקודת הקמה",
+ "Teardown command": "פקודת פירוק",
+ "Cleanup command": "פקודת ניקוי",
+ "Runtime services": "שירותי ריצה",
+ "Plugin Key": "מפתח תוסף",
+ "Plugin ID": "מזהה תוסף",
+ "Key": "מפתח",
+ "Skill name": "שם כישור",
+ "Document key": "מפתח מסמך",
+ "Variables": "משתנים",
+ "Default value": "ערך ברירת מחדל",
+ "Source": "מקור",
+ "Mode": "מצב",
+ "Kind": "סוג",
+ "Type": "סוג",
+ "Concurrency": "מקביליות",
+ "Version": "גרסה",
+ "PID": "PID",
+ "Uptime": "זמן פעילות",
+ "Auto-Restart On": "הפעלה מחדש אוטומטית",
+ "AI feedback sharing": "שיתוף משוב AI",
+ "Feedback Sharing": "שיתוף משוב",
+
+ // --- Placeholders ---
+ "Search icons...": "חפש אייקונים...",
+ "Search issues, agents, projects...": "חפש משימות, סוכנים, פרויקטים...",
+ "Search issues...": "חפש משימות...",
+ "Search assignees...": "חפש מוקצים...",
+ "Search labels...": "חפש תוויות...",
+ "Search projects...": "חפש פרויקטים...",
+ "Search models...": "חפש מודלים...",
+ "Search files...": "חפש קבצים...",
+ "Search inbox\u2026": "חפש בתיבת דואר\u2026",
+ "Type a command or search...": "הקלד פקודה או חפש...",
+ "Issue title": "כותרת משימה",
+ "Project name": "שם פרויקט",
+ "Target date": "תאריך יעד",
+ "Goal title": "כותרת יעד",
+ "Leave a comment...": "השאר תגובה...",
+ "Write something...": "כתוב משהו...",
+ "Enter a name": "הזן שם",
+ "Describe...": "תאר...",
+ "Choose a value": "בחר ערך",
+ "Choose frequency...": "בחר תדירות...",
+ "Category": "קטגוריה",
+ "Approval status": "סטטוס אישור",
+ "Routine title": "כותרת שגרה",
+ "Optional title": "כותרת אופציונלית",
+ "Markdown body": "גוף Markdown",
+ "New label": "תווית חדשה",
+ "Short description": "תיאור קצר",
+ "Optional company description": "תיאור חברה אופציונלי",
+ "Execution workspace name": "שם סביבת ביצוע",
+ "NPM Package Name": "שם חבילת NPM",
+
+ // --- Empty States ---
+ "No results found.": "לא נמצאו תוצאות.",
+ "No issues": "אין משימות",
+ "No labels": "אין תוויות",
+ "No goal": "אין יעד",
+ "No project": "אין פרויקט",
+ "No parent": "אין הורה",
+ "No manager": "אין מנהל",
+ "No assignee": "אין מוקצה",
+ "No value": "אין ערך",
+ "No default": "אין ברירת מחדל",
+ "No runs yet": "אין הרצות עדיין",
+ "No runs yet.": "אין הרצות עדיין.",
+ "No revisions yet": "אין גרסאות עדיין",
+ "No icons match": "לא נמצאו אייקונים",
+ "No agents match the selected filter.": "אין סוכנים שתואמים למסנן שנבחר.",
+ "No agents attached": "לא צורפו סוכנים",
+ "No active API keys.": "אין מפתחות API פעילים.",
+ "No activity yet.": "אין פעילות עדיין.",
+ "No plugins installed": "לא הותקנו תוספים",
+ "No goals.": "אין יעדים.",
+ "No tasks yet.": "אין משימות עדיין.",
+ "No triggers configured yet.": "לא הוגדרו טריגרים עדיין.",
+ "No description": "אין תיאור",
+ "No diagnostics": "אין אבחנות",
+ "No company selected": "לא נבחרה חברה",
+ "No cost data yet.": "אין נתוני עלויות עדיין.",
+ "No cost events yet.": "אין אירועי עלות עדיין.",
+ "No items added yet.": "לא נוספו פריטים עדיין.",
+ "No recent agent runs.": "אין הרצות סוכנים אחרונות.",
+ "No recent issues.": "אין משימות אחרונות.",
+ "No sub-goals.": "אין תת-יעדים.",
+ "Sub-Goals": "תת-יעדים",
+ "Sub Goal": "תת-יעד",
+ "No sub-issues.": "אין תת-משימות.",
+ "None": "ללא",
+ "Unassigned": "לא מוקצה",
+ "You have no agents.": "אין לך סוכנים.",
+ "No unsaved changes.": "אין שינויים שלא נשמרו.",
+ "No configuration options available.": "אין אפשרויות הגדרה זמינות.",
+
+ // --- Loading States ---
+ "Loading...": "טוען...",
+ "Loading\u2026": "טוען\u2026",
+ "Loading companies...": "טוען חברות...",
+ "Loading plugins...": "טוען תוספים...",
+ "Loading revisions...": "טוען גרסאות...",
+ "Loading workspaces...": "טוען סביבות עבודה...",
+ "Loading workspace\u2026": "טוען סביבת עבודה\u2026",
+ "Loading run logs...": "טוען יומני הרצה...",
+ "Loading log...": "טוען יומן...",
+ "Loading keys...": "טוען מפתחות...",
+ "Loading invite...": "טוען הזמנה...",
+ "Loading plugin details...": "טוען פרטי תוסף...",
+ "Checking health...": "בודק תקינות...",
+ "Uploading logo...": "מעלה לוגו...",
+ "Building export...": "בונה ייצוא...",
+
+ // --- Toast & Notifications ---
+ "Copied!": "הועתק!",
+ "Saved": "נשמר",
+ "Approval confirmed": "האישור אושר",
+ "CLI access approved": "גישת CLI אושרה",
+ "Bootstrap complete": "ההקמה הושלמה",
+ "Action failed": "הפעולה נכשלה",
+ "Comment failed": "התגובה נכשלה",
+ "Copy failed": "ההעתקה נכשלה",
+ "Archive failed": "הארכוב נכשל",
+ "Approve failed": "האישור נכשל",
+ "Reject failed": "הדחייה נכשלה",
+ "Update failed": "העדכון נכשל",
+ "Routine created": "השגרה נוצרה",
+ "Routine saved": "השגרה נשמרה",
+ "Routine run failed": "הרצת השגרה נכשלה",
+ "Routine run started": "הרצת השגרה החלה",
+ "Skill created": "הכישור נוצר",
+ "Skill saved": "הכישור נשמר",
+ "Skill updated": "הכישור עודכן",
+ "Plugin installed successfully": "התוסף הותקן בהצלחה",
+ "Plugin uninstalled successfully": "התוסף הוסר בהצלחה",
+ "Plugin enabled": "התוסף הופעל",
+ "Plugin disabled": "התוסף הושבת",
+ "Plugin error": "שגיאת תוסף",
+ "Trigger added": "הטריגר נוסף",
+ "Trigger deleted": "הטריגר נמחק",
+ "Trigger saved": "הטריגר נשמר",
+ "Run completed": "ההרצה הושלמה",
+ "Run failed": "ההרצה נכשלה",
+ "Command failed": "הפקודה נכשלה",
+ "Invite not available": "ההזמנה לא זמינה",
+ "Invite not found": "ההזמנה לא נמצאה",
+ "Interrupt requested": "התבקשה הפסקה",
+ "Interrupt failed": "ההפסקה נכשלה",
+
+ // --- Error Messages ---
+ "An error was thrown.": "אירעה שגיאה.",
+ "Authentication failed": "ההתחברות נכשלה",
+ "Unknown error": "שגיאה לא ידועה",
+ "Invalid JSON.": "JSON לא תקין.",
+ "Failed to create issue. Try again.": "יצירת המשימה נכשלה. נסה שוב.",
+ "Failed to create company": "יצירת החברה נכשלה",
+ "Failed to create agent": "יצירת הסוכן נכשלה",
+ "Failed to save": "השמירה נכשלה",
+ "Failed to approve": "האישור נכשל",
+ "Failed to reject": "הדחייה נכשלה",
+ "Instance setup required": "נדרשת הגדרת מופע",
+
+ // --- Dialog & Confirmation ---
+ "Delete this company and all its data? This cannot be undone.": "למחוק חברה זו וכל הנתונים שלה? לא ניתן לבטל פעולה זו.",
+ "Delete this document? This cannot be undone.": "למחוק מסמך זה? לא ניתן לבטל פעולה זו.",
+ "Mark all as read?": "לסמן הכל כנקרא?",
+ "Already have an account?": "כבר יש לך חשבון?",
+
+ // --- Section Headings ---
+ "Actions": "פעולות",
+ "Advanced": "מתקדם",
+ "Alerts": "התראות",
+ "Appearance": "מראה",
+ "Attachments": "קבצים מצורפים",
+ "Automation": "אוטומציה",
+ "Categories": "קטגוריות",
+ "Cleanup": "ניקוי",
+ "Codebase": "בסיס קוד",
+ "Comments": "תגובות",
+ "Company skills": "כישורי חברה",
+ "Config": "הגדרות",
+ "Context": "הקשר",
+ "Controls": "בקרה",
+ "Credits": "זיכויים",
+ "Debits": "חיובים",
+ "Details": "פרטים",
+ "Documents": "מסמכים",
+ "Environment": "סביבה",
+ "Error Details": "פרטי שגיאה",
+ "Files": "קבצים",
+ "Filters": "מסננים",
+ "Git status": "סטטוס Git",
+ "Hiring": "גיוס",
+ "Identity": "זהות",
+ "Invites": "הזמנות",
+ "Invocation": "הפעלה",
+ "Join requests": "בקשות הצטרפות",
+ "Lifecycle": "מחזור חיים",
+ "Linked Issues": "משימות מקושרות",
+ "Linked issues": "משימות מקושרות",
+ "Options": "אפשרויות",
+ "Output": "פלט",
+ "Owner": "בעלים",
+ "Permissions": "הרשאות",
+ "Properties": "מאפיינים",
+ "Providers": "ספקים",
+ "Quick filters": "מסננים מהירים",
+ "Recent financial events": "אירועי כספים אחרונים",
+ "Recent operations": "פעולות אחרונות",
+ "Remaining": "נותר",
+ "Result": "תוצאה",
+ "Revoked Keys": "מפתחות שבוטלו",
+ "Runtime services": "שירותי ריצה",
+ "Selected skills": "כישורים נבחרים",
+ "Summary": "סיכום",
+ "Tokens": "אסימונים",
+ "Unsaved changes": "שינויים שלא נשמרו",
+ "Warnings": "אזהרות",
+ "Workspace context": "הקשר סביבת עבודה",
+ "Worktree": "עץ עבודה",
+
+ // --- Table/List Headers ---
+ "Action": "פעולה",
+ "Agent": "סוכן",
+ "Branch": "ענף",
+ "Cost": "עלות",
+ "Created by": "נוצר על ידי",
+ "Current": "נוכחי",
+ "Current state": "מצב נוכחי",
+ "Date": "תאריך",
+ "Input tokens": "אסימוני קלט",
+ "Output tokens": "אסימוני פלט",
+ "Cached tokens": "אסימונים ממטמון",
+ "Last Crash": "קריסה אחרונה",
+ "Last run": "הרצה אחרונה",
+ "Overall": "כולל",
+ "Requested by": "התבקש על ידי",
+ "Task": "משימה",
+ "Total": "סך הכל",
+ "Total cost": "עלות כוללת",
+ "Used by": "בשימוש על ידי",
+
+ // --- Misc UI Labels ---
+ "About": "אודות",
+ "Adapter": "מתאם",
+ "After": "אחרי",
+ "Before": "לפני",
+ "Board view": "תצוגת לוח",
+ "Coming soon": "בקרוב",
+ "Documentation": "תיעוד",
+ "Earlier": "מוקדם יותר",
+ "Estimated": "משוער",
+ "External": "חיצוני",
+ "Human": "אנושי",
+ "My recent issues": "המשימות האחרונות שלי",
+ "Optional": "אופציונלי",
+ "Per issue": "למשימה",
+ "Per run": "להרצה",
+ "Secret": "סוד",
+ "See All \u2192": "ראה הכל \u2192",
+ "Small": "קטן",
+ "Large": "גדול",
+ "User": "משתמש",
+ "View details \u2192": "צפה בפרטים \u2192",
+ "All approval statuses": "כל סטטוסי האישור",
+ "All categories": "כל הקטגוריות",
+ "All providers": "כל הספקים",
+ "All types": "כל הסוגים",
+ "All Time": "כל הזמנים",
+ "Last 14 days": "14 ימים אחרונים",
+ "Automation enabled.": "אוטומציה מופעלת.",
+ "Automation paused.": "אוטומציה מושהית.",
+ "Mobile navigation": "ניווט נייד",
+
+ // --- Command Palette ---
+ "Pages": "דפים",
+
+ // --- Onboarding ---
+ "Bootstrap your Paperclip instance": "הקם את מופע ה-Paperclip שלך",
+ "Name your company": "תן שם לחברה שלך",
+ "This is the organization your agents will work for.": "זהו הארגון שעבורו הסוכנים שלך יעבדו.",
+ "This will be the CEO": "זה יהיה המנכ\"ל",
+ "Give it something to do": "תן לו משהו לעשות",
+ "Ready to launch": "מוכן להפעלה",
+ "Welcome to Paperclip. Set up your first company and agent to get started.": "ברוכים הבאים ל-Paperclip. הקם את החברה והסוכן הראשונים שלך כדי להתחיל.",
+ "I want advanced configuration myself": "אני רוצה להגדיר בעצמי הגדרות מתקדמות",
+ "Get started by creating a company.": "התחל ביצירת חברה.",
+
+ // --- Descriptions ---
+ "Choose how this agent will run tasks.": "בחר כיצד סוכן זה יריץ משימות.",
+ "Choose your adapter type for advanced setup.": "בחר את סוג המתאם להגדרה מתקדמת.",
+ "Plugins are alpha.": "התוספים בשלב אלפא.",
+ "Read our terms of service": "קרא את תנאי השירות שלנו",
+ "Select a company first.": "בחר חברה תחילה.",
+ "Sharing is currently disabled.": "השיתוף מושבת כרגע.",
+ "Don't allow": "אל תאפשר",
+ "Always allow": "אפשר תמיד",
+ "What could have been better?": "מה יכול היה להיות טוב יותר?",
+ "Drop image to upload": "גרור תמונה להעלאה",
+
+ // --- Aria Labels ---
+ "breadcrumb": "ניווט",
+ "toggle menu": "החלפת תפריט",
+ "Instance settings": "הגדרות מופע",
+ "Scroll to bottom": "גלול למטה",
+ "Change project color": "שנה צבע פרויקט",
+ "Zoom in": "הגדל",
+ "Zoom out": "הקטן",
+ "Fit chart to screen": "התאם תרשים למסך"
+ };
+
+ // =========================================================================
+ // TRANSLATION ENGINE
+ // =========================================================================
+
+ // Build a reverse lookup for performance: lowercase -> original key
+ const lowerMap = {};
+ for (const key in T) {
+ lowerMap[key.toLowerCase()] = key;
+ }
+
+ /**
+ * Translate a text string if a translation exists.
+ * Uses exact match first, then case-insensitive.
+ */
+ // Regex patterns for dynamic time strings
+ const TIME_PATTERNS = [
+ [/^(\d+)m ago$/, (m) => `לפני ${m[1]} דקות`],
+ [/^(\d+)h ago$/, (m) => `לפני ${m[1]} שעות`],
+ [/^(\d+)d ago$/, (m) => `לפני ${m[1]} ימים`],
+ [/^(\d+)s ago$/, (m) => `לפני ${m[1]} שניות`],
+ [/^(\d+) minutes? ago$/, (m) => `לפני ${m[1]} דקות`],
+ [/^(\d+) hours? ago$/, (m) => `לפני ${m[1]} שעות`],
+ [/^(\d+) days? ago$/, (m) => `לפני ${m[1]} ימים`],
+ [/^just now$/, () => "הרגע"],
+ [/^yesterday$/, () => "אתמול"],
+ // Tabs with counts
+ [/^Sub-Goals\s*\((\d+)\)$/, (m) => `תת-יעדים (${m[1]})`],
+ [/^Projects\s*\((\d+)\)$/, (m) => `פרויקטים (${m[1]})`],
+ [/^Issues\s*\((\d+)\)$/, (m) => `משימות (${m[1]})`],
+ [/^Agents\s*\((\d+)\)$/, (m) => `סוכנים (${m[1]})`],
+ [/^Members\s*\((\d+)\)$/, (m) => `חברים (${m[1]})`],
+ [/^Comments\s*\((\d+)\)$/, (m) => `תגובות (${m[1]})`],
+ [/^Documents\s*\((\d+)\)$/, (m) => `מסמכים (${m[1]})`],
+ [/^Routines\s*\((\d+)\)$/, (m) => `שגרות (${m[1]})`],
+ [/^Skills\s*\((\d+)\)$/, (m) => `כישורים (${m[1]})`],
+ [/^Labels\s*\((\d+)\)$/, (m) => `תוויות (${m[1]})`],
+ ];
+
+ // Regex patterns for date strings
+ const DATE_MONTHS = {
+ "Jan": "ינו׳", "Feb": "פבר׳", "Mar": "מרץ", "Apr": "אפר׳",
+ "May": "מאי", "Jun": "יוני", "Jul": "יולי", "Aug": "אוג׳",
+ "Sep": "ספט׳", "Oct": "אוק׳", "Nov": "נוב׳", "Dec": "דצמ׳"
+ };
+
+ function translate(text) {
+ const trimmed = text.trim().replace(/\s+/g, ' ');
+ if (!trimmed) return null;
+ // Exact match
+ if (T[trimmed] !== undefined) return T[trimmed];
+ // Case-insensitive match
+ const lk = trimmed.toLowerCase();
+ if (lowerMap[lk]) return T[lowerMap[lk]];
+ // Regex time patterns
+ for (const [pattern, replacer] of TIME_PATTERNS) {
+ const match = trimmed.match(pattern);
+ if (match) return replacer(match);
+ }
+ // Date format with time: "Apr 7, 2026, 6:02 PM" → "7 אפר׳ 2026, 18:02"
+ const dateTimeMatch = trimmed.match(/^(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+(\d+),\s+(\d{4}),\s+(\d+):(\d+)\s+(AM|PM)$/);
+ if (dateTimeMatch) {
+ const [, mon, day, year, hr, min, ampm] = dateTimeMatch;
+ let hour = parseInt(hr);
+ if (ampm === "PM" && hour !== 12) hour += 12;
+ if (ampm === "AM" && hour === 12) hour = 0;
+ return `${day} ${DATE_MONTHS[mon] || mon} ${year}, ${hour.toString().padStart(2,"0")}:${min}`;
+ }
+ // Date format without time: "Apr 7, 2026" → "7 אפר׳ 2026"
+ const dateMatch = trimmed.match(/^(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+(\d+),\s+(\d{4})$/);
+ if (dateMatch) {
+ const [, mon, day, year] = dateMatch;
+ return `${day} ${DATE_MONTHS[mon] || mon} ${year}`;
+ }
+ return null;
+ }
+
+ /**
+ * Check if a node is likely user-generated content (should NOT be translated).
+ * This includes agent names, issue titles in dynamic lists, etc.
+ */
+ function isUserContent(node) {
+ let el = node.parentElement;
+ while (el) {
+ // Skip elements with contenteditable (editors)
+ if (el.contentEditable === "true") return true;
+ // Skip code blocks
+ const tag = el.tagName;
+ if (tag === "CODE" || tag === "PRE") return true;
+ // Skip markdown rendered content body (but not headings/labels)
+ if (el.classList && el.classList.contains("paperclip-markdown")) return true;
+ // Skip elements explicitly marked as user content
+ if (el.dataset && el.dataset.noTranslate === "true") return true;
+ el = el.parentElement;
+ }
+ return false;
+ }
+
+ /**
+ * Walk all text nodes under a root and translate them.
+ */
+ function translateTextNodes(root) {
+ const walker = document.createTreeWalker(
+ root,
+ NodeFilter.SHOW_TEXT,
+ null
+ );
+ let node;
+ while ((node = walker.nextNode())) {
+ if (isUserContent(node)) continue;
+ const original = node.nodeValue;
+ const translated = translate(original);
+ if (translated !== null && translated !== original) {
+ // Add space when text follows a number in a sibling span (e.g. "0" + "active" → "0 פעיל")
+ const prev = node.previousSibling;
+ if (prev && prev.nodeType === 1 && /^\d+$/.test(prev.textContent.trim())) {
+ node.nodeValue = " " + translated;
+ } else {
+ node.nodeValue = translated;
+ }
+ }
+ }
+ }
+
+ /**
+ * Translate placeholder and aria-label attributes.
+ */
+ function translateAttributes(root) {
+ // Placeholders
+ const inputs = root.querySelectorAll("input[placeholder], textarea[placeholder]");
+ inputs.forEach(function (el) {
+ const t = translate(el.placeholder);
+ if (t) el.placeholder = t;
+ });
+
+ // aria-labels
+ const ariaEls = root.querySelectorAll("[aria-label]");
+ ariaEls.forEach(function (el) {
+ const t = translate(el.getAttribute("aria-label"));
+ if (t) el.setAttribute("aria-label", t);
+ });
+
+ // title attributes
+ const titleEls = root.querySelectorAll("[title]");
+ titleEls.forEach(function (el) {
+ const t = translate(el.getAttribute("title"));
+ if (t) el.setAttribute("title", t);
+ });
+ }
+
+ /**
+ * Full translation pass on the entire document.
+ */
+ /**
+ * Translate tab buttons and other elements whose textContent contains
+ * dynamic patterns like "Sub-Goals (0)" that text node walking misses.
+ */
+ function translateButtonLabels(root) {
+ const buttons = root.querySelectorAll('button[role="tab"], button[data-slot="tabs-trigger"]');
+ buttons.forEach(function(btn) {
+ const text = btn.textContent.trim().replace(/\s+/g, ' ');
+ const t = translate(text);
+ if (t && t !== text) {
+ btn.textContent = t;
+ }
+ });
+ }
+
+ function translateAll() {
+ translateTextNodes(document.body);
+ translateAttributes(document.body);
+ translateButtonLabels(document.body);
+ // Translate page title
+ if (document.title) {
+ const t = translate(document.title);
+ if (t) document.title = t;
+ }
+ }
+
+ // =========================================================================
+ // MUTATION OBSERVER - catch route changes and dynamic content
+ // =========================================================================
+ let translateTimer = null;
+
+ function scheduleTranslation() {
+ if (translateTimer) return;
+ translateTimer = setTimeout(function () {
+ translateTimer = null;
+ translateAll();
+ }, 50);
+ }
+
+ // Observe #root for changes (React renders here)
+ function startObserver() {
+ const root = document.getElementById("root");
+ if (!root) return;
+
+ const observer = new MutationObserver(function (mutations) {
+ let hasTextChange = false;
+ for (let i = 0; i < mutations.length; i++) {
+ const m = mutations[i];
+ if (m.type === "childList" && m.addedNodes.length > 0) {
+ hasTextChange = true;
+ break;
+ }
+ if (m.type === "characterData") {
+ hasTextChange = true;
+ break;
+ }
+ }
+ if (hasTextChange) {
+ scheduleTranslation();
+ }
+ });
+
+ observer.observe(root, {
+ childList: true,
+ subtree: true,
+ characterData: true
+ });
+
+ // Also observe body for Radix portals (dialogs, tooltips, dropdowns)
+ const bodyObserver = new MutationObserver(function (mutations) {
+ for (let i = 0; i < mutations.length; i++) {
+ const m = mutations[i];
+ if (m.type === "childList") {
+ for (let j = 0; j < m.addedNodes.length; j++) {
+ const node = m.addedNodes[j];
+ if (node.nodeType === 1 && node !== root) {
+ translateTextNodes(node);
+ translateAttributes(node);
+ }
+ }
+ }
+ }
+ });
+
+ bodyObserver.observe(document.body, {
+ childList: true,
+ subtree: false
+ });
+ }
+
+ // =========================================================================
+ // INIT
+ // =========================================================================
+ function init() {
+ // Wait for React to render
+ setTimeout(function () {
+ translateAll();
+ startObserver();
+ }, 300);
+
+ // Additional pass after longer delay for lazy-loaded content
+ setTimeout(translateAll, 1500);
+ setTimeout(translateAll, 4000);
+ }
+
+ // =========================================================================
+ // COMMENT ORDER — newest first
+ // =========================================================================
+ function reverseComments() {
+ // Find comment containers by anchor IDs
+ const commentAnchors = document.querySelectorAll('[id^="comment-"]');
+ if (!commentAnchors.length) return;
+
+ // Group by parent container
+ const parents = new Set();
+ commentAnchors.forEach(el => {
+ const parent = el.parentElement;
+ if (parent && !parent.dataset.reversed && parent.children.length > 1) {
+ parents.add(parent);
+ }
+ });
+
+ parents.forEach(parent => {
+ const children = Array.from(parent.children);
+ children.reverse().forEach(child => parent.appendChild(child));
+
+ // Move comment input box right after the newest comment.
+ // After reverse, the editor (originally last) is now first.
+ // Find it: it's the child without a comment-* ID.
+ const firstComment = parent.querySelector('[id^="comment-"]');
+ if (firstComment) {
+ // Find all non-comment children (editor/input boxes)
+ Array.from(parent.children).forEach(child => {
+ if (!child.id || !child.id.startsWith("comment-")) {
+ // Insert after the first (newest) comment
+ firstComment.after(child);
+ }
+ });
+ }
+
+ parent.dataset.reversed = "true";
+ });
+ }
+
+ // Re-run on route changes (SPA)
+ let lastUrl = location.href;
+ const urlObserver = new MutationObserver(() => {
+ if (location.href !== lastUrl) {
+ lastUrl = location.href;
+ // Reset reversed flags on navigation
+ document.querySelectorAll('[data-reversed]').forEach(el => {
+ delete el.dataset.reversed;
+ });
+ setTimeout(reverseComments, 500);
+ }
+ });
+
+ function initCommentOrder() {
+ urlObserver.observe(document.body, { childList: true, subtree: true });
+ // Also run after each mutation to catch late-loading comments
+ const commentMutObs = new MutationObserver(() => {
+ setTimeout(reverseComments, 200);
+ });
+ commentMutObs.observe(document.body, { childList: true, subtree: true });
+ setTimeout(reverseComments, 1000);
+ }
+
+ // Start when DOM is ready
+ if (document.readyState === "loading") {
+ document.addEventListener("DOMContentLoaded", () => { init(); initCommentOrder(); });
+ } else {
+ init();
+ initCommentOrder();
+ }
+})();