From ad3c2b7117aed9d3c731abec4ee6232ef8637e19 Mon Sep 17 00:00:00 2001 From: Chaim Date: Tue, 14 Apr 2026 15:57:18 +0000 Subject: [PATCH] =?UTF-8?q?Remove=20duplicate=20paperclip-assets=20?= =?UTF-8?q?=E2=80=94=20source=20of=20truth=20is=20paperclip-config=20repo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Assets live in ezer-mishpati/paperclip-config (cloned at ~/.paperclip). Deploy via: ~/.paperclip/hebrew/apply-hebrew.sh Co-Authored-By: Claude Opus 4.6 (1M context) --- scripts/paperclip-assets/deploy.sh | 21 - scripts/paperclip-assets/patch-html.sh | 33 - scripts/paperclip-assets/rtl-override.css | 1045 ---------------- scripts/paperclip-assets/translate-he.js | 1351 --------------------- 4 files changed, 2450 deletions(-) delete mode 100755 scripts/paperclip-assets/deploy.sh delete mode 100644 scripts/paperclip-assets/patch-html.sh delete mode 100644 scripts/paperclip-assets/rtl-override.css delete mode 100644 scripts/paperclip-assets/translate-he.js diff --git a/scripts/paperclip-assets/deploy.sh b/scripts/paperclip-assets/deploy.sh deleted file mode 100755 index f99081e..0000000 --- a/scripts/paperclip-assets/deploy.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/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 deleted file mode 100644 index 8a9b7de..0000000 --- a/scripts/paperclip-assets/patch-html.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/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 deleted file mode 100644 index 3422fe3..0000000 --- a/scripts/paperclip-assets/rtl-override.css +++ /dev/null @@ -1,1045 +0,0 @@ -/* ========================================================================== - 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 deleted file mode 100644 index 1e1b724..0000000 --- a/scripts/paperclip-assets/translate-he.js +++ /dev/null @@ -1,1351 +0,0 @@ -/** - * 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(); - } -})();