All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 1m39s
CEO wakes for weekly-feedback-job via agents.invoke without issueId, so $PAPERCLIP_TASK_ID is empty. Removed steps 4-5 (comment + close issue) from handler — now file-write only with stdout logging. Also commits pending docs and agent instructions from prior session. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
486 lines
17 KiB
Markdown
486 lines
17 KiB
Markdown
---
|
||
name: legal-docx
|
||
description: >
|
||
יצירת מסמכים משפטיים בעברית בפורמט DOCX עם תמיכה מלאה ב-RTL, עקוב אחר שינויים,
|
||
והערות. משתמש בסקיל הבסיסי docx ומוסיף התמחות בתחום המשפטי הישראלי.
|
||
|
||
טריגרים: "מסמך משפטי", "הסכם", "כתב הגנה", "כתב תביעה", "בקשה", "תצהיר",
|
||
"מכתב התראה", "חוזה", "הסכם שירותים", "ייפוי כוח", "פרוטוקול", "החלטה",
|
||
"צו", "פסק דין", "כתב טענות", בקשה ליצור מסמך DOCX בעברית, מסמך RTL,
|
||
"tracked changes בעברית", "הערות שוליים משפטיות", "עקוב אחר שינויים".
|
||
|
||
גם מתאים כאשר המשתמש מבקש מסמך Word בעברית עם פונט David/FrankRuehl/Miriam,
|
||
שוליים 2.5 ס"מ, או כל מסמך מקצועי בעברית שדורש עיצוב משפטי מדויק.
|
||
|
||
פיצ'רים: טבלאות RTL, הערות שוליים, תוכן עניינים, היפרלינקים,
|
||
לוגו/נייר פירמה, עריכת DOCX קיים, tracked changes, comments,
|
||
מרווח שורות, קו תחתי, מספר סקשנים, זיהוי אוטומטי של סוג מסמך.
|
||
---
|
||
|
||
# Legal DOCX v3.0 — מסמכים משפטיים בעברית
|
||
|
||
סקיל זה מרחיב את סקיל docx הבסיסי עם התמחות במסמכים משפטיים ישראליים.
|
||
|
||
**תמיד לקרוא קודם** את `/mnt/skills/public/docx/SKILL.md` — הסקיל הזה מניח שאתה מכיר את תהליך העבודה הבסיסי (docx-js, unpack/pack, tracked changes, comments).
|
||
|
||
---
|
||
|
||
## 🔴 קריטי: כללי RTL שחייבים לזכור
|
||
|
||
### הכלל המרכזי: START/END במקום LEFT/RIGHT
|
||
|
||
**במסמך עברי עם `bidirectional: true`, לעולם אל תשתמש ב-`AlignmentType.LEFT` או `AlignmentType.RIGHT` לפסקאות ומספור!**
|
||
|
||
| רוצה יישור ל... | ❌ לא להשתמש | ✅ להשתמש |
|
||
|-----------------|-------------|----------|
|
||
| **ימין** | `LEFT` או `RIGHT` | `AlignmentType.START` |
|
||
| **שמאל** | `LEFT` או `RIGHT` | `AlignmentType.END` |
|
||
| **מרכז** | — | `AlignmentType.CENTER` |
|
||
| **שני צדדים** | — | `AlignmentType.BOTH` |
|
||
|
||
> **למה?** כש-`bidirectional: true`, Word מתבלבל עם LEFT/RIGHT. `START` = התחלה = ימין ב-RTL, `END` = סוף = שמאל ב-RTL.
|
||
|
||
### שלוש הגדרות RTL חובה
|
||
|
||
כל מסמך עברי חייב את **שלושת** ההגדרות הבאות בכל הרמות:
|
||
|
||
```javascript
|
||
// 1. ברמת ה-Section
|
||
sections: [{
|
||
properties: {
|
||
bidi: true // ← חובה!
|
||
}
|
||
}]
|
||
|
||
// 2. ברמת כל Paragraph
|
||
new Paragraph({
|
||
bidirectional: true, // ← חובה!
|
||
alignment: AlignmentType.BOTH, // או START/CENTER/END
|
||
})
|
||
|
||
// 3. ברמת כל TextRun
|
||
new TextRun({
|
||
text: "טקסט בעברית",
|
||
rightToLeft: true, // ← חובה!
|
||
font: "David",
|
||
})
|
||
```
|
||
|
||
**חוסר באחת מהן = יישור שגוי או טקסט הפוך!**
|
||
|
||
---
|
||
|
||
## זיהוי סוג מסמך — Document Type Detection
|
||
|
||
**לפני יצירת מסמך, זהה את סוגו.** לכל סוג יש מבנה שונה:
|
||
|
||
| סוג מסמך | דוגמאות | Header בית משפט? | מבנה מיוחד |
|
||
|----------|---------|------------------|------------|
|
||
| **כתב טענות** | תביעה, הגנה, בקשה, ערעור, תצהיר, בר"ע | ✅ כן | טבלת Header עם בית משפט + מספר תיק |
|
||
| **מכתב התראה** | התראה, דרישה, מכתב עו"ד | ❌ לא | לוגו/פרטי משרד, "הנדון:", חתימה |
|
||
| **הסכם/חוזה** | הסכם שירותים, NDA, חוזה שכירות | ❌ לא | הואילים, צדדים, חתימות בשני טורים |
|
||
| **מסמך כללי** | חוות דעת, מזכר, סיכום | ❌ לא | לפי הצורך |
|
||
|
||
### טריגרים לזיהוי
|
||
|
||
```
|
||
כתב טענות ← "בית משפט", "בית הדין", "תביעה", "הגנה", "בקשה",
|
||
"ערעור", "תצהיר", "המבקש", "המשיב", "התובע", "הנתבע", "בר\"ע"
|
||
|
||
מכתב התראה ← "התראה", "דרישה", "לכבוד", "הנדון:", "נשלח מבלי לפגוע"
|
||
|
||
הסכם/חוזה ← "הסכם", "חוזה", "בין:", "לבין:", "הואיל", "צד א'", "צד ב'",
|
||
"ולראיה באו הצדדים"
|
||
```
|
||
|
||
---
|
||
|
||
## פונטים ומידות
|
||
|
||
### פונטים משפטיים
|
||
|
||
| פונט | שימוש | size (half-points) |
|
||
|------|-------|-------------------|
|
||
| **David** | ברירת מחדל, גוף טקסט | 24 (12pt) |
|
||
| **FrankRuehl** | פורמלי/שמרני | 24 (12pt) |
|
||
| **Miriam** | מודרני יותר | 24 (12pt) |
|
||
|
||
**חשוב:** תמיד להגדיר גם `w:cs` (Complex Script) וגם `w:ascii`/`w:hAnsi`:
|
||
```javascript
|
||
new TextRun({ text: "...", font: "David", rightToLeft: true })
|
||
// docx-js מייצר: <w:rFonts w:ascii="David" w:cs="David" w:eastAsia="David" w:hAnsi="David"/>
|
||
```
|
||
|
||
### מידות ושוליים
|
||
|
||
```
|
||
2.5 ס"מ = 1417 DXA (ברירת מחדל משפטי)
|
||
3.0 ס"מ = 1701 DXA
|
||
2.0 ס"מ = 1134 DXA
|
||
1.0 אינץ' = 1440 DXA
|
||
|
||
A4 = 11906 × 16838 DXA
|
||
רוחב תוכן (A4, שוליים 2.5 ס"מ) = 9072 DXA
|
||
רוחב תוכן (A4, שוליים 2.0 ס"מ) = 9638 DXA
|
||
```
|
||
|
||
---
|
||
|
||
## מספור סעיפים משפטיים
|
||
|
||
**⚠️ שים לב: `alignment: AlignmentType.START` — לא LEFT ולא RIGHT!**
|
||
|
||
```javascript
|
||
numbering: {
|
||
config: [{
|
||
reference: "legal-clauses",
|
||
levels: [
|
||
{
|
||
level: 0,
|
||
format: LevelFormat.DECIMAL,
|
||
text: "%1.",
|
||
alignment: AlignmentType.START, // ✅ START — לא RIGHT!
|
||
suffix: "tab",
|
||
style: { paragraph: { indent: { left: 720, hanging: 360 } } }
|
||
},
|
||
{
|
||
level: 1,
|
||
format: LevelFormat.DECIMAL,
|
||
text: "%1.%2",
|
||
alignment: AlignmentType.START, // ✅ START — לא RIGHT!
|
||
suffix: "tab",
|
||
style: { paragraph: { indent: { left: 1440, hanging: 500 } } }
|
||
},
|
||
{
|
||
level: 2,
|
||
format: LevelFormat.DECIMAL,
|
||
text: "%1.%2.%3",
|
||
alignment: AlignmentType.START, // ✅ START
|
||
suffix: "tab",
|
||
style: { paragraph: { indent: { left: 2160, hanging: 640 } } }
|
||
}
|
||
]
|
||
}]
|
||
}
|
||
```
|
||
|
||
**שימוש:**
|
||
```javascript
|
||
new Paragraph({
|
||
bidirectional: true,
|
||
numbering: { reference: "legal-clauses", level: 0 },
|
||
children: [new TextRun({ text: "תוכן הסעיף", font: "David", size: 24, rightToLeft: true })]
|
||
})
|
||
```
|
||
|
||
> **הבעיה שנפתרה:** בלי `AlignmentType.START`, המספור מופיע כ-".1" במקום "1."
|
||
|
||
---
|
||
|
||
## טבלאות RTL
|
||
|
||
**⚠️ קריטי: `visuallyRightToLeft: true` — בלי זה העמודות יהיו הפוכות!**
|
||
|
||
```javascript
|
||
const { Table, TableRow, TableCell, BorderStyle, WidthType, ShadingType } = require('docx');
|
||
|
||
const CONTENT_WIDTH = 9072; // A4 עם שוליים 2.5 ס"מ (11906 - 1417×2)
|
||
const border = { style: BorderStyle.SINGLE, size: 1, color: "999999" };
|
||
const borders = { top: border, bottom: border, left: border, right: border };
|
||
const noBorders = {
|
||
top: { style: BorderStyle.NONE, size: 0, color: "FFFFFF" },
|
||
bottom: { style: BorderStyle.NONE, size: 0, color: "FFFFFF" },
|
||
left: { style: BorderStyle.NONE, size: 0, color: "FFFFFF" },
|
||
right: { style: BorderStyle.NONE, size: 0, color: "FFFFFF" }
|
||
};
|
||
|
||
// Helper function לתאים בעברית
|
||
const rtlCell = (text, width, opts = {}) => new TableCell({
|
||
borders: opts.noBorders ? noBorders : borders,
|
||
width: { size: width, type: WidthType.DXA },
|
||
margins: { top: 80, bottom: 80, left: 120, right: 120 },
|
||
...(opts.shading ? { shading: { fill: opts.shading, type: ShadingType.CLEAR } } : {}),
|
||
children: [new Paragraph({
|
||
bidirectional: true,
|
||
alignment: opts.alignment || AlignmentType.CENTER,
|
||
children: [new TextRun({
|
||
text, font: "David", size: 24, rightToLeft: true, bold: opts.bold
|
||
})]
|
||
})]
|
||
});
|
||
|
||
// טבלה עם גבולות
|
||
new Table({
|
||
visuallyRightToLeft: true, // ✅ קריטי! בלי זה העמודות הפוכות
|
||
width: { size: CONTENT_WIDTH, type: WidthType.DXA },
|
||
columnWidths: [4536, 2268, 2268], // חייב להסתכם ל-CONTENT_WIDTH
|
||
rows: [
|
||
new TableRow({ children: [
|
||
rtlCell("סוג שירות", 4536, { bold: true, shading: "D5E8F0" }),
|
||
rtlCell("תעריף", 2268, { bold: true, shading: "D5E8F0" }),
|
||
rtlCell("הערות", 2268, { bold: true, shading: "D5E8F0" }),
|
||
]}),
|
||
new TableRow({ children: [
|
||
rtlCell("ייעוץ משפטי", 4536),
|
||
rtlCell("850 ש״ח", 2268),
|
||
rtlCell("בתוספת מע״מ", 2268),
|
||
]}),
|
||
]
|
||
})
|
||
|
||
// טבלה ללא גבולות (לחתימות / header)
|
||
new Table({
|
||
visuallyRightToLeft: true,
|
||
width: { size: CONTENT_WIDTH, type: WidthType.DXA },
|
||
columnWidths: [CONTENT_WIDTH / 2, CONTENT_WIDTH / 2],
|
||
rows: [
|
||
new TableRow({ children: [
|
||
rtlCell("חתימה: ________", CONTENT_WIDTH / 2, { noBorders: true, alignment: AlignmentType.CENTER }),
|
||
rtlCell("חתימה: ________", CONTENT_WIDTH / 2, { noBorders: true, alignment: AlignmentType.CENTER }),
|
||
]})
|
||
]
|
||
})
|
||
```
|
||
|
||
**כללים:**
|
||
- **`visuallyRightToLeft: true`** — חובה! בלי זה העמודות משמאל לימין
|
||
- **`WidthType.DXA`** — לא PERCENTAGE (פחות אמין ב-RTL)
|
||
- **`columnWidths`** — סכום חייב להיות שווה ל-`CONTENT_WIDTH`
|
||
- **`bidirectional: true` + `rightToLeft: true`** — בכל תא
|
||
|
||
---
|
||
|
||
## Tracked Changes — עקוב אחר שינויים
|
||
|
||
ראה [`references/tracked-changes.md`](references/tracked-changes.md) — XML patterns לשינוי ערך, מחיקת סעיף, RTL PROPS, קבלה/דחייה.
|
||
|
||
```bash
|
||
python /mnt/skills/public/docx/scripts/comment.py unpacked/ 0 "הערה" --author "עו״ד כהן"
|
||
```
|
||
|
||
---
|
||
|
||
## הערות (Comments)
|
||
|
||
הערות משמשות בסקירה משפטית להסביר *למה* בוצע שינוי:
|
||
|
||
```bash
|
||
python /mnt/skills/public/docx/scripts/comment.py unpacked/ 0 "הערה בעברית" --author "עו״ד כהן"
|
||
```
|
||
|
||
שימושים נפוצים:
|
||
- הסבר לשינוי סכום או תאריך
|
||
- דגל על סעיף בעייתי
|
||
- הפניה לפסיקה או חקיקה
|
||
- שאלה ללקוח / לצד השני
|
||
|
||
> **הערה:** `comment.py` מטפל אוטומטית ב-Content_Types ו-relationships.
|
||
|
||
---
|
||
|
||
## עריכת DOCX קיים (Unpack → Edit → Pack)
|
||
|
||
### תהליך מאומת
|
||
```bash
|
||
# 1. פתיחת הקובץ
|
||
python /mnt/skills/public/docx/scripts/unpack.py input.docx unpacked/
|
||
|
||
# 2. עריכת word/document.xml (או קבצי XML אחרים)
|
||
|
||
# 3. ארגון מחדש
|
||
python /mnt/skills/public/docx/scripts/pack.py unpacked/ output.docx --original input.docx
|
||
```
|
||
|
||
### מיקום הוספת תוכן — כלל קריטי
|
||
```
|
||
⚠️ פסקאות חדשות חייבות להיכנס *לפני* <w:sectPr> האחרון בגוף המסמך.
|
||
הוספה *אחרי* sectPr תיכשל בוולידציה.
|
||
|
||
מבנה תקין:
|
||
<w:body>
|
||
<w:p>...</w:p> ← פסקאות קיימות
|
||
<w:p>...</w:p> ← פסקה חדשה כאן ✅
|
||
<w:sectPr>...</w:sectPr> ← תמיד אחרון
|
||
</w:body>
|
||
```
|
||
|
||
### דוגמה — הוספת פסקה בעברית
|
||
```xml
|
||
<w:p>
|
||
<w:pPr>
|
||
<w:bidi/>
|
||
<w:jc w:val="both"/>
|
||
</w:pPr>
|
||
<w:r>
|
||
<w:rPr>
|
||
<w:rFonts w:ascii="David" w:cs="David" w:eastAsia="David" w:hAnsi="David"/>
|
||
<w:sz w:val="24"/>
|
||
<w:szCs w:val="24"/>
|
||
<w:rtl/>
|
||
</w:rPr>
|
||
<w:t>הטקסט החדש</w:t>
|
||
</w:r>
|
||
</w:p>
|
||
```
|
||
|
||
---
|
||
|
||
## מרווח שורות (Line Spacing)
|
||
|
||
**דרישת בתי המשפט:** בדרך כלל 1.5 שורות.
|
||
|
||
```javascript
|
||
const { LineRuleType } = require('docx');
|
||
|
||
// LineRuleType.AUTO — הערך הוא ב-1/240 שורה
|
||
spacing: { line: 240, lineRule: LineRuleType.AUTO } // 1.0 — צפוף
|
||
spacing: { line: 276, lineRule: LineRuleType.AUTO } // 1.15 — ברירת מחדל Word
|
||
spacing: { line: 360, lineRule: LineRuleType.AUTO } // 1.5 — נדרש בבתי משפט
|
||
spacing: { line: 480, lineRule: LineRuleType.AUTO } // 2.0 — כפול
|
||
|
||
// שילוב עם before/after:
|
||
spacing: { line: 360, lineRule: LineRuleType.AUTO, before: 120, after: 120 }
|
||
```
|
||
|
||
---
|
||
|
||
## קו תחתי (Underline)
|
||
|
||
```javascript
|
||
const { UnderlineType } = require('docx');
|
||
|
||
// קו תחתי רגיל:
|
||
new TextRun({
|
||
text: "נושא: הסכם שירותים",
|
||
font: "David", size: 24, rightToLeft: true,
|
||
underline: { type: UnderlineType.SINGLE }
|
||
})
|
||
|
||
// קו תחתי כפול (לכותרות חשובות):
|
||
underline: { type: UnderlineType.DOUBLE }
|
||
|
||
// סוגים שימושיים: SINGLE, DOUBLE, THICK, DOTTED, DASH, WAVE
|
||
```
|
||
|
||
---
|
||
|
||
## פיצ'רים מתקדמים
|
||
|
||
ראה [`references/advanced-features.md`](references/advanced-features.md):
|
||
- **הערות שוליים** — Footnotes עם RTL + תיקון post-unpack ב-footnotes.xml
|
||
- **תוכן עניינים** — TOC ידני (אסור `TableOfContents`)
|
||
- **מספר סקשנים** — כותרות שונות לנספחים
|
||
- **Letterhead** — לוגו/תמונה בכותרת
|
||
- **היפרלינקים** — `ExternalHyperlink` עם color+underline ידני (לא `style: "Hyperlink"`)
|
||
|
||
---
|
||
|
||
## תבניות מסמכים
|
||
|
||
ראה [`references/document-templates.md`](references/document-templates.md):
|
||
- **תבנית 1: כתב טענות** — `courtHeader()`, `mainTitle()`, `subHeading()` + מספור
|
||
- **תבנית 2: מכתב התראה** — `letterHeader()`, `subjectLine()` + פרטי משרד
|
||
- **תבנית 3: הסכם/חוזה** — `contractTitle()`, `partyClause()`, `signatureTable()` + הואילים
|
||
|
||
---
|
||
|
||
## Quick Reference — טבלת עזר מהיר
|
||
|
||
### יישור
|
||
|
||
| רוצה | השתמש ב... | ❌ לא להשתמש |
|
||
|------|-----------|-------------|
|
||
| ימין | `AlignmentType.START` | `LEFT`, `RIGHT` |
|
||
| שמאל | `AlignmentType.END` | `LEFT`, `RIGHT` |
|
||
| מרכז | `AlignmentType.CENTER` | — |
|
||
| שני צדדים | `AlignmentType.BOTH` | `JUSTIFIED` |
|
||
|
||
### גדלי טקסט (half-points)
|
||
|
||
| שימוש | size | נקודות |
|
||
|-------|------|--------|
|
||
| גוף טקסט | 24 | 12pt |
|
||
| כותרת משנה | 26 | 13pt |
|
||
| כותרת ראשית | 28-32 | 14-16pt |
|
||
| הערות שוליים | 20 | 10pt |
|
||
| Header/Footer | 18-20 | 9-10pt |
|
||
|
||
### מרווחי שורות
|
||
|
||
| רווח | line value |
|
||
|------|-----------|
|
||
| 1.0 | 240 |
|
||
| 1.15 | 276 |
|
||
| 1.5 | 360 |
|
||
| 2.0 | 480 |
|
||
|
||
### Checklist — הגדרות חובה
|
||
|
||
```
|
||
☐ Section: bidi: true
|
||
☐ Paragraph: bidirectional: true
|
||
☐ TextRun: rightToLeft: true
|
||
☐ Numbering: alignment: AlignmentType.START
|
||
☐ Table: visuallyRightToLeft: true
|
||
☐ Footnotes: alignment: AlignmentType.START
|
||
```
|
||
|
||
---
|
||
|
||
## 🔧 Troubleshooting
|
||
|
||
**מספור מופיע הפוך (.1 במקום 1.):**
|
||
→ וודא `alignment: AlignmentType.START` במספור (לא RIGHT!)
|
||
|
||
**טקסט מופיע משמאל לימין:**
|
||
→ וודא את שלושת ההגדרות: Section `bidi`, Paragraph `bidirectional`, TextRun `rightToLeft`
|
||
|
||
**עמודות טבלה הפוכות:**
|
||
→ הוסף `visuallyRightToLeft: true` לטבלה
|
||
|
||
**columnWidths לא מסתכם:**
|
||
→ וודא שסכום כל הרוחבים = CONTENT_WIDTH (9072 לשוליים 2.5 ס"מ, חישוב: 11906 - 1417×2)
|
||
|
||
**המסמך לא נפתח / שגיאה ב-Word:**
|
||
→ בדוק שלא הוספת פסקה אחרי `<w:sectPr>` (חייב להיות אחרון ב-body)
|
||
→ וודא `npm list docx` >= 8.0.0
|
||
|
||
**הערות שוליים לא ב-RTL:**
|
||
→ אחרי unpack, תקן ידנית ב-word/footnotes.xml (ראה סעיף הערות שוליים)
|
||
|
||
---
|
||
|
||
## טעויות נפוצות — Common Pitfalls
|
||
|
||
| ❌ טעות | ✅ תיקון |
|
||
|--------|---------|
|
||
| `AlignmentType.RIGHT` במספור | `AlignmentType.START` |
|
||
| `AlignmentType.LEFT` ליישור שמאלי | `AlignmentType.END` |
|
||
| טבלה בלי `visuallyRightToLeft` | הוסף `visuallyRightToLeft: true` |
|
||
| שכחת `bidirectional: true` בפסקה | הוסף לכל פסקה |
|
||
| שכחת `rightToLeft: true` ב-TextRun | הוסף לכל TextRun |
|
||
| שכחת `bidi: true` ב-Section | הוסף ל-properties |
|
||
| הוספת פסקה אחרי `sectPr` | הוסף לפני `sectPr` |
|
||
| שימוש ב-`style: "Hyperlink"` | הגדר ידנית `color` + `underline` |
|
||
| `columnWidths` לא מסתכם נכון | וודא שהסכום = `CONTENT_WIDTH` |
|
||
|
||
---
|
||
|
||
## קבצי עזר
|
||
|
||
- **[`references/document-types.md`](references/document-types.md)** — מבנים מפורטים ל-9 סוגי מסמכים
|
||
- **[`references/document-templates.md`](references/document-templates.md)** — 3 תבניות מלאות (כתב טענות, מכתב, הסכם)
|
||
- **[`references/tracked-changes.md`](references/tracked-changes.md)** — XML patterns לעקוב אחר שינויים
|
||
- **[`references/advanced-features.md`](references/advanced-features.md)** — הערות שוליים, TOC, סקשנים, letterhead, hyperlinks
|
||
- **`scripts/create-legal-doc.js`** — סקריפט בסיסי עם כל הגדרות RTL
|
||
|
||
---
|
||
|
||
## Dependencies
|
||
|
||
```bash
|
||
npm install docx
|
||
```
|
||
|
||
**גרסה מומלצת:** docx >= 8.0.0
|