Phase 1: scaffold Next.js 16 web-ui + Coolify staging
- create-next-app with TypeScript, Tailwind v4, App Router - Port design-system.css tokens into Tailwind @theme (navy/gold/parchment, Heebo) - Install TanStack Query, react-hook-form, zod, lucide-react, react-dropzone - layout.tsx: RTL Hebrew + Heebo via next/font/google - AppShell component with navy header + gold rule + nav - next.config.ts: output:standalone + rewrites to proxy /api/* to production FastAPI - Dockerfile: multi-stage Node 20 Alpine build for Next.js standalone (branch-local override of the FastAPI Dockerfile; main is unaffected) - Switch .taskmaster to claude-code provider (no API key required) - Add 7 phase tasks (83-89) tracking the full rewrite plan Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,20 +1,20 @@
|
|||||||
{
|
{
|
||||||
"models": {
|
"models": {
|
||||||
"main": {
|
"main": {
|
||||||
"provider": "anthropic",
|
"provider": "claude-code",
|
||||||
"modelId": "claude-opus-4-20250514",
|
"modelId": "opus",
|
||||||
"maxTokens": 64000,
|
"maxTokens": 32000,
|
||||||
"temperature": 0.2
|
"temperature": 0.2
|
||||||
},
|
},
|
||||||
"research": {
|
"research": {
|
||||||
"provider": "anthropic",
|
"provider": "claude-code",
|
||||||
"modelId": "claude-sonnet-4-20250514",
|
"modelId": "opus",
|
||||||
"maxTokens": 64000,
|
"maxTokens": 32000,
|
||||||
"temperature": 0.1
|
"temperature": 0.1
|
||||||
},
|
},
|
||||||
"fallback": {
|
"fallback": {
|
||||||
"provider": "anthropic",
|
"provider": "claude-code",
|
||||||
"modelId": "claude-sonnet-4-20250514",
|
"modelId": "sonnet",
|
||||||
"maxTokens": 64000,
|
"maxTokens": 64000,
|
||||||
"temperature": 0.2
|
"temperature": 0.2
|
||||||
}
|
}
|
||||||
|
|||||||
3
.taskmaster/state.json
Normal file
3
.taskmaster/state.json
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"migrationNoticeShown": true
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
"master": {
|
"master": {
|
||||||
"tasks": [
|
"tasks": [
|
||||||
{
|
{
|
||||||
"id": "32",
|
"id": 32,
|
||||||
"title": "הקמת סביבת פיתוח ותשתית בסיסית",
|
"title": "הקמת סביבת פיתוח ותשתית בסיסית",
|
||||||
"description": "הקמת סביבת הפיתוח הבסיסית עם Python, FastAPI, PostgreSQL ו-Infisical לניהול סודות",
|
"description": "הקמת סביבת הפיתוח הבסיסית עם Python, FastAPI, PostgreSQL ו-Infisical לניהול סודות",
|
||||||
"details": "יצירת פרויקט Python עם FastAPI כשרת API, PostgreSQL כמסד נתונים, ו-Infisical לניהול סודות. הגדרת Docker containers לפיתוח מקומי. יצירת מבנה תיקיות: /src, /tests, /docs, /data. הגדרת requirements.txt עם כל התלויות הנדרשות: fastapi, uvicorn, sqlalchemy, psycopg2, python-multipart, python-docx, PyPDF2, anthropic, infisical-python. הגדרת משתני סביבה דרך Infisical.",
|
"details": "יצירת פרויקט Python עם FastAPI כשרת API, PostgreSQL כמסד נתונים, ו-Infisical לניהול סודות. הגדרת Docker containers לפיתוח מקומי. יצירת מבנה תיקיות: /src, /tests, /docs, /data. הגדרת requirements.txt עם כל התלויות הנדרשות: fastapi, uvicorn, sqlalchemy, psycopg2, python-multipart, python-docx, PyPDF2, anthropic, infisical-python. הגדרת משתני סביבה דרך Infisical.",
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
"updatedAt": "2026-04-03T08:53:33.842Z"
|
"updatedAt": "2026-04-03T08:53:33.842Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "33",
|
"id": 33,
|
||||||
"title": "מודול קליטה ועיבוד מסמכים",
|
"title": "מודול קליטה ועיבוד מסמכים",
|
||||||
"description": "פיתוח מודול לקליטת קבצי PDF, DOCX, MD וחילוץ טקסט כולל OCR",
|
"description": "פיתוח מודול לקליטת קבצי PDF, DOCX, MD וחילוץ טקסט כולל OCR",
|
||||||
"details": "יצירת מחלקה DocumentProcessor שמטפלת בקבצים מסוגים שונים. עבור PDF: שימוש ב-PyPDF2 לטקסט רגיל ו-pytesseract לOCR של קבצים סרוקים. עבור DOCX: שימוש ב-python-docx. עבור MD: קריאה ישירה. הוספת זיהוי אוטומטי של קבצים סרוקים. יצירת API endpoint POST /documents/upload שמקבל קבצים ומחזיר טקסט מחולץ. שמירת מטא-דאטה של כל מסמך במסד הנתונים.",
|
"details": "יצירת מחלקה DocumentProcessor שמטפלת בקבצים מסוגים שונים. עבור PDF: שימוש ב-PyPDF2 לטקסט רגיל ו-pytesseract לOCR של קבצים סרוקים. עבור DOCX: שימוש ב-python-docx. עבור MD: קריאה ישירה. הוספת זיהוי אוטומטי של קבצים סרוקים. יצירת API endpoint POST /documents/upload שמקבל קבצים ומחזיר טקסט מחולץ. שמירת מטא-דאטה של כל מסמך במסד הנתונים.",
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
"updatedAt": "2026-04-03T09:38:55.716Z"
|
"updatedAt": "2026-04-03T09:38:55.716Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "34",
|
"id": 34,
|
||||||
"title": "מודול סיווג מסמכים וזיהוי צדדים",
|
"title": "מודול סיווג מסמכים וזיהוי צדדים",
|
||||||
"description": "פיתוח מודול לסיווג מסמכים לסוגים (ערר, תשובה, פרוטוקול וכו') וזיהוי צדדים",
|
"description": "פיתוח מודול לסיווג מסמכים לסוגים (ערר, תשובה, פרוטוקול וכו') וזיהוי צדדים",
|
||||||
"details": "יצירת מחלקה DocumentClassifier שמשתמשת ב-Claude API לסיווג מסמכים. הגדרת prompt מובנה שמזהה: סוג מסמך (ערר/תשובה/תגובה/פרוטוקול/תכנית/היתר/פסק דין/החלטה), צדדים (עוררים, משיבים, ועדה, מבקשי היתר), סוג ערר לפי מספר תיק (1xxx=רישוי, 8xxx=השבחה, 9xxx=פיצויים). יצירת מבנה נתונים מובנה לשמירת המידע המסווג. הוספת ולידציה לתוצאות הסיווג.",
|
"details": "יצירת מחלקה DocumentClassifier שמשתמשת ב-Claude API לסיווג מסמכים. הגדרת prompt מובנה שמזהה: סוג מסמך (ערר/תשובה/תגובה/פרוטוקול/תכנית/היתר/פסק דין/החלטה), צדדים (עוררים, משיבים, ועדה, מבקשי היתר), סוג ערר לפי מספר תיק (1xxx=רישוי, 8xxx=השבחה, 9xxx=פיצויים). יצירת מבנה נתונים מובנה לשמירת המידע המסווג. הוספת ולידציה לתוצאות הסיווג.",
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
"updatedAt": "2026-04-03T09:43:02.411Z"
|
"updatedAt": "2026-04-03T09:43:02.411Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "35",
|
"id": 35,
|
||||||
"title": "מודול חילוץ טענות",
|
"title": "מודול חילוץ טענות",
|
||||||
"description": "פיתוח מודול לחילוץ וסיכום טענות מכתבי טענות לפי צד",
|
"description": "פיתוח מודול לחילוץ וסיכום טענות מכתבי טענות לפי צד",
|
||||||
"details": "יצירת מחלקה ClaimsExtractor שמחלצת טענות מכתבי ערר ותשובה. שימוש ב-Claude API עם prompt מיוחד שמזהה טענות לפי צד ומסכם אותן בצורה נאמנה למקור. יצירת מבנה נתונים שמקשר בין טענה למסמך המקור ולמיקום בו. הוספת מנגנון לזיהוי טענות חוזרות או דומות. שמירת הטענות במסד הנתונים עם קישור לתיק ולצד.",
|
"details": "יצירת מחלקה ClaimsExtractor שמחלצת טענות מכתבי ערר ותשובה. שימוש ב-Claude API עם prompt מיוחד שמזהה טענות לפי צד ומסכם אותן בצורה נאמנה למקור. יצירת מבנה נתונים שמקשר בין טענה למסמך המקור ולמיקום בו. הוספת מנגנון לזיהוי טענות חוזרות או דומות. שמירת הטענות במסד הנתונים עם קישור לתיק ולצד.",
|
||||||
@@ -56,7 +56,7 @@
|
|||||||
"updatedAt": "2026-04-03T09:45:38.799Z"
|
"updatedAt": "2026-04-03T09:45:38.799Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "36",
|
"id": 36,
|
||||||
"title": "מודול זיהוי תכניות ופסיקה",
|
"title": "מודול זיהוי תכניות ופסיקה",
|
||||||
"description": "פיתוח מודול לזיהוי תכניות חלות על המקרקעין ופסיקה מצוטטת במסמכים",
|
"description": "פיתוח מודול לזיהוי תכניות חלות על המקרקעין ופסיקה מצוטטת במסמכים",
|
||||||
"details": "יצירת מחלקה LegalReferencesExtractor שמזהה: תכניות (תב\"ע, תמ\"א, תכניות מקומיות), פסיקה מצוטטת (עם מספרי תיק ושנה), חקיקה רלוונטית. שימוש ב-regex patterns לזיהוי דפוסים נפוצים ו-Claude API לאימות ועידון. יצירת מאגר מקומי של תכניות ופסיקה שכבר זוהו. הוספת מנגנון לולידציה של הפניות שזוהו.",
|
"details": "יצירת מחלקה LegalReferencesExtractor שמזהה: תכניות (תב\"ע, תמ\"א, תכניות מקומיות), פסיקה מצוטטת (עם מספרי תיק ושנה), חקיקה רלוונטית. שימוש ב-regex patterns לזיהוי דפוסים נפוצים ו-Claude API לאימות ועידון. יצירת מאגר מקומי של תכניות ופסיקה שכבר זוהו. הוספת מנגנון לולידציה של הפניות שזוהו.",
|
||||||
@@ -70,7 +70,7 @@
|
|||||||
"updatedAt": "2026-04-03T09:48:16.636Z"
|
"updatedAt": "2026-04-03T09:48:16.636Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "37",
|
"id": 37,
|
||||||
"title": "ממשק הזנת תוצאה וסיעור מוחות",
|
"title": "ממשק הזנת תוצאה וסיעור מוחות",
|
||||||
"description": "פיתוח ממשק CLI להזנת תוצאה (דחייה/קבלה/חלקית) ומנגנון סיעור מוחות",
|
"description": "פיתוח ממשק CLI להזנת תוצאה (דחייה/קבלה/חלקית) ומנגנון סיעור מוחות",
|
||||||
"details": "יצירת CLI interface עם typer שמאפשר לחיים להזין: סוג תוצאה (דחייה/קבלה/קבלה חלקית), נימוק (אופציונלי). אם לא הוזן נימוק - הפעלת מודול BrainstormingEngine שמציג טענות מרכזיות ומציע 2-3 כיוונים אפשריים. יצירת שיח אינטראקטיבי בין חיים למערכת עד הגעה לכיוון מוסכם. שמירת מסמך הכיוון הסופי. הוספת מנגנון מניעה מכתיבת דיון ללא כיוון מאושר.",
|
"details": "יצירת CLI interface עם typer שמאפשר לחיים להזין: סוג תוצאה (דחייה/קבלה/קבלה חלקית), נימוק (אופציונלי). אם לא הוזן נימוק - הפעלת מודול BrainstormingEngine שמציג טענות מרכזיות ומציע 2-3 כיוונים אפשריים. יצירת שיח אינטראקטיבי בין חיים למערכת עד הגעה לכיוון מוסכם. שמירת מסמך הכיוון הסופי. הוספת מנגנון מניעה מכתיבת דיון ללא כיוון מאושר.",
|
||||||
@@ -85,7 +85,7 @@
|
|||||||
"updatedAt": "2026-04-03T09:55:06.069Z"
|
"updatedAt": "2026-04-03T09:55:06.069Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "38",
|
"id": 38,
|
||||||
"title": "מנוע כתיבת בלוק הפתיחה (בלוק ה)",
|
"title": "מנוע כתיבת בלוק הפתיחה (בלוק ה)",
|
||||||
"description": "פיתוח מנוע לכתיבת בלוק הפתיחה בסגנון דפנה",
|
"description": "פיתוח מנוע לכתיבת בלוק הפתיחה בסגנון דפנה",
|
||||||
"details": "יצירת מחלקה OpeningBlockWriter שכותבת את בלוק הפתיחה. ניתוח דפוסי הפתיחה מ-7 ההחלטות הקיימות (\"לפנינו\" vs \"עניינה של החלטה זו\"). יצירת prompt מובנה שמתאים את הפתיחה לסוג הערר ולמורכבות התיק. הוספת מנגנון לבחירת נוסח הפתיחה המתאים. שמירת תבניות פתיחה במסד הנתונים.",
|
"details": "יצירת מחלקה OpeningBlockWriter שכותבת את בלוק הפתיחה. ניתוח דפוסי הפתיחה מ-7 ההחלטות הקיימות (\"לפנינו\" vs \"עניינה של החלטה זו\"). יצירת prompt מובנה שמתאים את הפתיחה לסוג הערר ולמורכבות התיק. הוספת מנגנון לבחירת נוסח הפתיחה המתאים. שמירת תבניות פתיחה במסד הנתונים.",
|
||||||
@@ -99,7 +99,7 @@
|
|||||||
"updatedAt": "2026-04-03T09:58:34.296Z"
|
"updatedAt": "2026-04-03T09:58:34.296Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "39",
|
"id": 39,
|
||||||
"title": "מנוע כתיבת בלוק הרקע (בלוק ו)",
|
"title": "מנוע כתיבת בלוק הרקע (בלוק ו)",
|
||||||
"description": "פיתוח מנוע לכתיבת בלוק הרקע בצורה ניטרלית",
|
"description": "פיתוח מנוע לכתיבת בלוק הרקע בצורה ניטרלית",
|
||||||
"details": "יצירת מחלקה BackgroundBlockWriter שכותבת רקע ניטרלי. הגדרת כללי ניטרליות: אין ציטוטים מצדדים, אין מילות שיפוט, הצגת עובדות בלבד. יצירת רשימת מילים אסורות ומנגנון ולידציה. שימוש במידע מהמסמכים המסווגים לבניית הרקע. הוספת מנגנון לקביעת אורך הרקע לפי מורכבות התיק (3%-18% מההחלטה).",
|
"details": "יצירת מחלקה BackgroundBlockWriter שכותבת רקע ניטרלי. הגדרת כללי ניטרליות: אין ציטוטים מצדדים, אין מילות שיפוט, הצגת עובדות בלבד. יצירת רשימת מילים אסורות ומנגנון ולידציה. שימוש במידע מהמסמכים המסווגים לבניית הרקע. הוספת מנגנון לקביעת אורך הרקע לפי מורכבות התיק (3%-18% מההחלטה).",
|
||||||
@@ -113,7 +113,7 @@
|
|||||||
"updatedAt": "2026-04-03T09:58:34.300Z"
|
"updatedAt": "2026-04-03T09:58:34.300Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "40",
|
"id": 40,
|
||||||
"title": "מנוע כתיבת בלוק הטענות (בלוק ז)",
|
"title": "מנוע כתיבת בלוק הטענות (בלוק ז)",
|
||||||
"description": "פיתוח מנוע לכתיבת סיכום טענות הצדדים בגוף שלישי",
|
"description": "פיתוח מנוע לכתיבת סיכום טענות הצדדים בגוף שלישי",
|
||||||
"details": "יצירת מחלקה ClaimsBlockWriter שמסכמת טענות בגוף שלישי. שימוש בטענות שחולצו במודול חילוץ הטענות. הבטחת נאמנות מוחלטת למקור - אין שינוי מילים או קיצור ללא ציון. יצירת מבנה לוגי של הצגת הטענות לפי צד. הוספת מנגנון לקישור כל טענה למקור המדויק במסמך.",
|
"details": "יצירת מחלקה ClaimsBlockWriter שמסכמת טענות בגוף שלישי. שימוש בטענות שחולצו במודול חילוץ הטענות. הבטחת נאמנות מוחלטת למקור - אין שינוי מילים או קיצור ללא ציון. יצירת מבנה לוגי של הצגת הטענות לפי צד. הוספת מנגנון לקישור כל טענה למקור המדויק במסמך.",
|
||||||
@@ -127,7 +127,7 @@
|
|||||||
"updatedAt": "2026-04-03T09:58:34.303Z"
|
"updatedAt": "2026-04-03T09:58:34.303Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "41",
|
"id": 41,
|
||||||
"title": "מנוע כתיבת בלוק ההליכים (בלוק ח)",
|
"title": "מנוע כתיבת בלוק ההליכים (בלוק ח)",
|
||||||
"description": "פיתוח מנוע לכתיבת בלוק ההליכים (רק כשהיו הליכים מעבר לדיון פשוט)",
|
"description": "פיתוח מנוע לכתיבת בלוק ההליכים (רק כשהיו הליכים מעבר לדיון פשוט)",
|
||||||
"details": "יצירת מחלקה ProceduresBlockWriter שכותבת תיעוד כרונולוגי של הליכים. זיהוי אוטומטי מתי נדרש הבלוק (סיור, השלמות טיעון, החלטות ביניים). יצירת ציר זמן של האירועים מהמסמכים. הבטחת דיוק עובדתי ומבנה כרונולוגי. הוספת מנגנון להחלטה אוטומטית האם הבלוק נדרש.",
|
"details": "יצירת מחלקה ProceduresBlockWriter שכותבת תיעוד כרונולוגי של הליכים. זיהוי אוטומטי מתי נדרש הבלוק (סיור, השלמות טיעון, החלטות ביניים). יצירת ציר זמן של האירועים מהמסמכים. הבטחת דיוק עובדתי ומבנה כרונולוגי. הוספת מנגנון להחלטה אוטומטית האם הבלוק נדרש.",
|
||||||
@@ -141,7 +141,7 @@
|
|||||||
"updatedAt": "2026-04-03T09:58:34.305Z"
|
"updatedAt": "2026-04-03T09:58:34.305Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "42",
|
"id": 42,
|
||||||
"title": "מנוע כתיבת בלוק התכניות (בלוק ט)",
|
"title": "מנוע כתיבת בלוק התכניות (בלוק ט)",
|
||||||
"description": "פיתוח מנוע לכתיבת בלוק התכניות והמסגרת הנורמטיבית",
|
"description": "פיתוח מנוע לכתיבת בלוק התכניות והמסגרת הנורמטיבית",
|
||||||
"details": "יצירת מחלקה PlansBlockWriter שמטפלת ברישום תכניות. הגדרת כללי החלטה מתי נדרש פרק נפרד (מורכבות תכנונית, שאלה משפטית כמו ס' 152). שימוש במידע התכניות שזוהו במודול זיהוי התכניות. יצירת מבנה הירכי של התכניות (ארציות, מחוזיות, מקומיות). הוספת מנגנון לקביעת עומק הפירוט הנדרש.",
|
"details": "יצירת מחלקה PlansBlockWriter שמטפלת ברישום תכניות. הגדרת כללי החלטה מתי נדרש פרק נפרד (מורכבות תכנונית, שאלה משפטית כמו ס' 152). שימוש במידע התכניות שזוהו במודול זיהוי התכניות. יצירת מבנה הירכי של התכניות (ארציות, מחוזיות, מקומיות). הוספת מנגנון לקביעת עומק הפירוט הנדרש.",
|
||||||
@@ -155,7 +155,7 @@
|
|||||||
"updatedAt": "2026-04-03T09:58:34.308Z"
|
"updatedAt": "2026-04-03T09:58:34.308Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "43",
|
"id": 43,
|
||||||
"title": "מנוע כתיבת בלוק הדיון (בלוק י) - ליבת המערכת",
|
"title": "מנוע כתיבת בלוק הדיון (בלוק י) - ליבת המערכת",
|
||||||
"description": "פיתוח מנוע הכתיבה המרכזי לבלוק הדיון בשיטת CREAC",
|
"description": "פיתוח מנוע הכתיבה המרכזי לבלוק הדיון בשיטת CREAC",
|
||||||
"details": "יצירת מחלקה DiscussionBlockWriter - הליבה של המערכת. יישום שיטת CREAC: מסקנה בפתיחה, כלל משפטי, הסבר, יישום על המקרה, מסקנה. הבטחת מענה לכל טענה מבלוק ז. שימוש בכיוון שנקבע בשלב סיעור המוחות. הוספת מנגנון למניעת כפילויות והפניות לבלוקים קודמים. יצירת מבנה לוגי של הנימוקים לפי סדר חשיבות.",
|
"details": "יצירת מחלקה DiscussionBlockWriter - הליבה של המערכת. יישום שיטת CREAC: מסקנה בפתיחה, כלל משפטי, הסבר, יישום על המקרה, מסקנה. הבטחת מענה לכל טענה מבלוק ז. שימוש בכיוון שנקבע בשלב סיעור המוחות. הוספת מנגנון למניעת כפילויות והפניות לבלוקים קודמים. יצירת מבנה לוגי של הנימוקים לפי סדר חשיבות.",
|
||||||
@@ -169,7 +169,7 @@
|
|||||||
"updatedAt": "2026-04-03T09:58:34.311Z"
|
"updatedAt": "2026-04-03T09:58:34.311Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "44",
|
"id": 44,
|
||||||
"title": "מנוע כתיבת בלוק הסיכום (בלוק יא)",
|
"title": "מנוע כתיבת בלוק הסיכום (בלוק יא)",
|
||||||
"description": "פיתוח מנוע לכתיבת בלוק הסיכום עם הוראות אופרטיביות",
|
"description": "פיתוח מנוע לכתיבת בלוק הסיכום עם הוראות אופרטיביות",
|
||||||
"details": "יצירת מחלקה SummaryBlockWriter שכותבת הוראות אופרטיביות. גזירת ההוראות מהדיון שנכתב בבלוק י. הבטחת התאמה מדויקת להכרעה שנקבעה. יצירת מבנה ברור של ההוראות (מה מתקבל, מה נדחה, מה התנאים). הוספת מנגנון לולידציה של עקביות בין הדיון לסיכום.",
|
"details": "יצירת מחלקה SummaryBlockWriter שכותבת הוראות אופרטיביות. גזירת ההוראות מהדיון שנכתב בבלוק י. הבטחת התאמה מדויקת להכרעה שנקבעה. יצירת מבנה ברור של ההוראות (מה מתקבל, מה נדחה, מה התנאים). הוספת מנגנון לולידציה של עקביות בין הדיון לסיכום.",
|
||||||
@@ -183,7 +183,7 @@
|
|||||||
"updatedAt": "2026-04-03T09:58:34.313Z"
|
"updatedAt": "2026-04-03T09:58:34.313Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "45",
|
"id": 45,
|
||||||
"title": "מנוע ייצוא DOCX מעוצב",
|
"title": "מנוע ייצוא DOCX מעוצב",
|
||||||
"description": "פיתוח מנוע לייצוא ההחלטה לקובץ DOCX מעוצב בעברית RTL",
|
"description": "פיתוח מנוע לייצוא ההחלטה לקובץ DOCX מעוצב בעברית RTL",
|
||||||
"details": "יצירת מחלקה DocxExporter שמייצרת DOCX מעוצב. הגדרת גופן David, כיוון RTL, כותרות מעוצבות, מספור סעיפים רציף. יצירת תבנית DOCX בסיסית עם הגדרות העיצוב. הוספת מנגנון לסימון מקומות תמונה (GIS, תשריט, סיור). הבטחת תמיכה מלאה בעברית ובכיוון RTL. יצירת מבנה היררכי של כותרות וסעיפים.",
|
"details": "יצירת מחלקה DocxExporter שמייצרת DOCX מעוצב. הגדרת גופן David, כיוון RTL, כותרות מעוצבות, מספור סעיפים רציף. יצירת תבנית DOCX בסיסית עם הגדרות העיצוב. הוספת מנגנון לסימון מקומות תמונה (GIS, תשריט, סיור). הבטחת תמיכה מלאה בעברית ובכיוון RTL. יצירת מבנה היררכי של כותרות וסעיפים.",
|
||||||
@@ -197,7 +197,7 @@
|
|||||||
"updatedAt": "2026-04-03T10:12:36.842Z"
|
"updatedAt": "2026-04-03T10:12:36.842Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "46",
|
"id": 46,
|
||||||
"title": "מנגנון בקרת איכות ווולידציה",
|
"title": "מנגנון בקרת איכות ווולידציה",
|
||||||
"description": "פיתוח מנגנון בקרת איכות לוולידציה של ההחלטה לפני הפלט",
|
"description": "פיתוח מנגנון בקרת איכות לוולידציה של ההחלטה לפני הפלט",
|
||||||
"details": "יצירת מחלקה QualityController שבודקת: אפס הזיות (כל הפניה מול מסמכים שסופקו), מענה לכל טענה, רקע ניטרלי (ללא מילות שיפוט), משקלות בלוקים בטווח יחסי הזהב ±10%, ציטוטים נאמנים למקור. יצירת דוח ולידציה מפורט. הוספת מנגנון למניעת פלט במקרה של כשלון ולידציה קריטי.",
|
"details": "יצירת מחלקה QualityController שבודקת: אפס הזיות (כל הפניה מול מסמכים שסופקו), מענה לכל טענה, רקע ניטרלי (ללא מילות שיפוט), משקלות בלוקים בטווח יחסי הזהב ±10%, ציטוטים נאמנים למקור. יצירת דוח ולידציה מפורט. הוספת מנגנון למניעת פלט במקרה של כשלון ולידציה קריטי.",
|
||||||
@@ -211,7 +211,7 @@
|
|||||||
"updatedAt": "2026-04-03T10:14:00.311Z"
|
"updatedAt": "2026-04-03T10:14:00.311Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "47",
|
"id": 47,
|
||||||
"title": "מודול לולאת למידה",
|
"title": "מודול לולאת למידה",
|
||||||
"description": "פיתוח מודול לקליטת גרסה סופית והשוואה לטיוטה ללמידה",
|
"description": "פיתוח מודול לקליטת גרסה סופית והשוואה לטיוטה ללמידה",
|
||||||
"details": "יצירת מחלקה LearningLoop שמקבלת את הגרסה הסופית שדפנה חתמה. השוואת הטיוטה לגרסה הסופית וזיהוי הבדלים. חילוץ לקחים: ביטויים חדשים, דפוסים שהשתנו, שגיאות חוזרות. עדכון מודל הסגנון על בסיס הלקחים. יצירת דוח למידה לחיים. שמירת הלקחים במסד הנתונים לשיפור עתידי.",
|
"details": "יצירת מחלקה LearningLoop שמקבלת את הגרסה הסופית שדפנה חתמה. השוואת הטיוטה לגרסה הסופית וזיהוי הבדלים. חילוץ לקחים: ביטויים חדשים, דפוסים שהשתנו, שגיאות חוזרות. עדכון מודל הסגנון על בסיס הלקחים. יצירת דוח למידה לחיים. שמירת הלקחים במסד הנתונים לשיפור עתידי.",
|
||||||
@@ -225,7 +225,7 @@
|
|||||||
"updatedAt": "2026-04-03T10:15:14.639Z"
|
"updatedAt": "2026-04-03T10:15:14.639Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "48",
|
"id": 48,
|
||||||
"title": "מודול מדדי הצלחה ודשבורד",
|
"title": "מודול מדדי הצלחה ודשבורד",
|
||||||
"description": "פיתוח מודול למדידת KPIs ויצירת דשבורד מעקב",
|
"description": "פיתוח מודול למדידת KPIs ויצירת דשבורד מעקב",
|
||||||
"details": "יצירת מחלקה MetricsTracker שמודדת: אחוז שינוי (השוואת טיוטה לגרסה סופית), זמן לטיוטה (מקצה לקצה), אפס הזיות (ספירת הפניות לא תקינות), מענה לכל טענה, משקלות בלוקים, רקע ניטרלי. יצירת דשבורד פשוט עם הצגת המדדים לאורך זמן. הוספת התראות כשמדד יורד מתחת לסף המינימום.",
|
"details": "יצירת מחלקה MetricsTracker שמודדת: אחוז שינוי (השוואת טיוטה לגרסה סופית), זמן לטיוטה (מקצה לקצה), אפס הזיות (ספירת הפניות לא תקינות), מענה לכל טענה, משקלות בלוקים, רקע ניטרלי. יצירת דשבורד פשוט עם הצגת המדדים לאורך זמן. הוספת התראות כשמדד יורד מתחת לסף המינימום.",
|
||||||
@@ -239,7 +239,7 @@
|
|||||||
"updatedAt": "2026-04-03T10:16:10.708Z"
|
"updatedAt": "2026-04-03T10:16:10.708Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "49",
|
"id": 49,
|
||||||
"title": "מנגנון ניהול סודות ואבטחה",
|
"title": "מנגנון ניהול סודות ואבטחה",
|
||||||
"description": "יישום מנגנון אבטחה מלא עם Infisical וניהול סודות",
|
"description": "יישום מנגנון אבטחה מלא עם Infisical וניהול סודות",
|
||||||
"details": "הגדרת Infisical לניהול כל הסודות: Anthropic API key, מחרוזות חיבור למסד נתונים, מפתחות הצפנה. יצירת מנגנון הצפנה לחומרי התיקים במסד הנתונים. הגדרת מדיניות גישה והרשאות. יצירת מנגנון audit log לכל הפעולות. הבטחת שחומרי התיקים לא נשלחים לשירותים חיצוניים מלבד Anthropic API.",
|
"details": "הגדרת Infisical לניהול כל הסודות: Anthropic API key, מחרוזות חיבור למסד נתונים, מפתחות הצפנה. יצירת מנגנון הצפנה לחומרי התיקים במסד הנתונים. הגדרת מדיניות גישה והרשאות. יצירת מנגנון audit log לכל הפעולות. הבטחת שחומרי התיקים לא נשלחים לשירותים חיצוניים מלבד Anthropic API.",
|
||||||
@@ -253,7 +253,7 @@
|
|||||||
"updatedAt": "2026-04-03T10:17:43.954Z"
|
"updatedAt": "2026-04-03T10:17:43.954Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "50",
|
"id": 50,
|
||||||
"title": "מנגנון גיבוי ושחזור",
|
"title": "מנגנון גיבוי ושחזור",
|
||||||
"description": "יישום מנגנון גיבוי יומי אוטומטי ושחזור מסד הנתונים",
|
"description": "יישום מנגנון גיבוי יומי אוטומטי ושחזור מסד הנתונים",
|
||||||
"details": "יצירת סקריפט גיבוי יומי אוטומטי למסד הנתונים PostgreSQL. הגדרת cron job לביצוע הגיבוי בשעות הלילה. יצירת מנגנון שחזור מגיבוי. שמירת הגיבויים במיקום מאובטח. הוספת מנגנון לבדיקת תקינות הגיבויים. יצירת תיעוד לתהליכי גיבוי ושחזור.",
|
"details": "יצירת סקריפט גיבוי יומי אוטומטי למסד הנתונים PostgreSQL. הגדרת cron job לביצוע הגיבוי בשעות הלילה. יצירת מנגנון שחזור מגיבוי. שמירת הגיבויים במיקום מאובטח. הוספת מנגנון לבדיקת תקינות הגיבויים. יצירת תיעוד לתהליכי גיבוי ושחזור.",
|
||||||
@@ -267,7 +267,7 @@
|
|||||||
"updatedAt": "2026-04-03T10:18:18.247Z"
|
"updatedAt": "2026-04-03T10:18:18.247Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "51",
|
"id": 51,
|
||||||
"title": "ממשק CLI מלא ותיעוד",
|
"title": "ממשק CLI מלא ותיעוד",
|
||||||
"description": "פיתוח ממשק CLI מלא עם כל הפקודות הנדרשות ותיעוד מקיף",
|
"description": "פיתוח ממשק CLI מלא עם כל הפקודות הנדרשות ותיעוד מקיף",
|
||||||
"details": "יצירת CLI מקיף עם typer שכולל: העלאת מסמכים, הזנת תוצאה, סיעור מוחות, יצירת טיוטה, הזנת גרסה סופית, הצגת מדדים. הוספת help מפורט לכל פקודה. יצירת תיעוד מקיף למשתמש עם דוגמאות שימוש. הוספת מנגנון לולידציה של קלטים. יצירת מנגנון לטיפול בשגיאות ומסרי שגיאה ברורים בעברית.",
|
"details": "יצירת CLI מקיף עם typer שכולל: העלאת מסמכים, הזנת תוצאה, סיעור מוחות, יצירת טיוטה, הזנת גרסה סופית, הצגת מדדים. הוספת help מפורט לכל פקודה. יצירת תיעוד מקיף למשתמש עם דוגמאות שימוש. הוספת מנגנון לולידציה של קלטים. יצירת מנגנון לטיפול בשגיאות ומסרי שגיאה ברורים בעברית.",
|
||||||
@@ -282,7 +282,7 @@
|
|||||||
"updatedAt": "2026-04-03T10:19:20.241Z"
|
"updatedAt": "2026-04-03T10:19:20.241Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "52",
|
"id": 52,
|
||||||
"title": "בדיקות אינטגרציה ומבחן הסמכה",
|
"title": "בדיקות אינטגרציה ומבחן הסמכה",
|
||||||
"description": "יצירת חבילת בדיקות מקיפה ומבחן הסמכה על תיק אמיתי",
|
"description": "יצירת חבילת בדיקות מקיפה ומבחן הסמכה על תיק אמיתי",
|
||||||
"details": "יצירת בדיקות אינטגרציה לכל התהליך מקצה לקצה. בדיקה עם תיק הכט (תיק שכבר יש לו החלטה סופית) - השוואת הטיוטה שהמערכת מייצרת להחלטה הסופית. מדידת פער ווידוא שהוא קטן מ-10%. יצירת מבחן הסמכה מובנה לפני שימוש מבצעי. הוספת בדיקות ביצועים - וידוא שהמערכת מייצרת טיוטה תוך יום עבודה.",
|
"details": "יצירת בדיקות אינטגרציה לכל התהליך מקצה לקצה. בדיקה עם תיק הכט (תיק שכבר יש לו החלטה סופית) - השוואת הטיוטה שהמערכת מייצרת להחלטה הסופית. מדידת פער ווידוא שהוא קטן מ-10%. יצירת מבחן הסמכה מובנה לפני שימוש מבצעי. הוספת בדיקות ביצועים - וידוא שהמערכת מייצרת טיוטה תוך יום עבודה.",
|
||||||
@@ -296,7 +296,7 @@
|
|||||||
"updatedAt": "2026-04-04T07:50:59.998Z"
|
"updatedAt": "2026-04-04T07:50:59.998Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "53",
|
"id": 53,
|
||||||
"title": "הוספת שלב 6 - הגהת דפנה לדרישות הפונקציונליות",
|
"title": "הוספת שלב 6 - הגהת דפנה לדרישות הפונקציונליות",
|
||||||
"description": "הגדרת שלב הגהת דפנה החסר מהדרישות הפונקציונליות, כולל זרימת העבודה והממשקים",
|
"description": "הגדרת שלב הגהת דפנה החסר מהדרישות הפונקציונליות, כולל זרימת העבודה והממשקים",
|
||||||
"details": "יש להגדיר בדרישות הפונקציונליות: (1) איך דפנה מקבלת את הטיוטה בפורמט DOCX, (2) איך מחזירה הערות ותיקונים (ממשק או פורמט מובנה), (3) מי מעלה את הגרסה הסופית ללולאת הלמידה. כולל הגדרת API endpoints לקבלת הטיוטה ולהחזרת הערות, ומנגנון עדכון המודל על בסיס הפידבק.",
|
"details": "יש להגדיר בדרישות הפונקציונליות: (1) איך דפנה מקבלת את הטיוטה בפורמט DOCX, (2) איך מחזירה הערות ותיקונים (ממשק או פורמט מובנה), (3) מי מעלה את הגרסה הסופית ללולאת הלמידה. כולל הגדרת API endpoints לקבלת הטיוטה ולהחזרת הערות, ומנגנון עדכון המודל על בסיס הפידבק.",
|
||||||
@@ -308,7 +308,7 @@
|
|||||||
"updatedAt": "2026-04-02T20:58:19.827Z"
|
"updatedAt": "2026-04-02T20:58:19.827Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "54",
|
"id": 54,
|
||||||
"title": "החלפת דרישת 'אפס הזיות' במנגנון grounding ווולידציה",
|
"title": "החלפת דרישת 'אפס הזיות' במנגנון grounding ווולידציה",
|
||||||
"description": "החלפת הדרישה הלא ריאלית של אפס הזיות במנגנון grounding מתקדם ומערכת וולידציה אוטומטית",
|
"description": "החלפת הדרישה הלא ריאלית של אפס הזיות במנגנון grounding מתקדם ומערכת וולידציה אוטומטית",
|
||||||
"details": "יישום מנגנון grounding שמקשר כל הפניה למסמך מקור ספציפי עם citation tracking. פיתוח מערכת וולידציה אוטומטית שבודקת כל ציטוט/הפניה מול המסמכים שסופקו. הגדרת מדד: שיעור הפניות שלא עוברות וולידציה = 0. כולל מנגנון flagging של הפניות חשודות ודרישה לאישור ידני.",
|
"details": "יישום מנגנון grounding שמקשר כל הפניה למסמך מקור ספציפי עם citation tracking. פיתוח מערכת וולידציה אוטומטית שבודקת כל ציטוט/הפניה מול המסמכים שסופקו. הגדרת מדד: שיעור הפניות שלא עוברות וולידציה = 0. כולל מנגנון flagging של הפניות חשודות ודרישה לאישור ידני.",
|
||||||
@@ -320,7 +320,7 @@
|
|||||||
"updatedAt": "2026-04-02T20:58:55.741Z"
|
"updatedAt": "2026-04-02T20:58:55.741Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "55",
|
"id": 55,
|
||||||
"title": "הוספת ניהול context window overflow",
|
"title": "הוספת ניהול context window overflow",
|
||||||
"description": "פיתוח מנגנון לטיפול בתיקים מורכבים שחורגים מ-context window של המודל",
|
"description": "פיתוח מנגנון לטיפול בתיקים מורכבים שחורגים מ-context window של המודל",
|
||||||
"details": "יישום מדידת גודל חומרים בטוקנים, אסטרטגיית chunking חכמה ו/או summarization של מסמכים ארוכים. הגדרת סף התראה כשמתקרבים לגבול context window. פיתוח אלגוריתם לסדר עדיפויות של מסמכים והחלטה איזה חלקים לכלול בהקשר הנוכחי.",
|
"details": "יישום מדידת גודל חומרים בטוקנים, אסטרטגיית chunking חכמה ו/או summarization של מסמכים ארוכים. הגדרת סף התראה כשמתקרבים לגבול context window. פיתוח אלגוריתם לסדר עדיפויות של מסמכים והחלטה איזה חלקים לכלול בהקשר הנוכחי.",
|
||||||
@@ -332,7 +332,7 @@
|
|||||||
"updatedAt": "2026-04-02T20:59:34.704Z"
|
"updatedAt": "2026-04-02T20:59:34.704Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "56",
|
"id": 56,
|
||||||
"title": "הגדרה מתמטית מדויקת של 'אחוז שינוי'",
|
"title": "הגדרה מתמטית מדויקת של 'אחוז שינוי'",
|
||||||
"description": "הגדרה ברורה ומתמטית של מדד אחוז השינוי עם דוגמאות קונקרטיות",
|
"description": "הגדרה ברורה ומתמטית של מדד אחוז השינוי עם דוגמאות קונקרטיות",
|
||||||
"details": "הגדרת מדד אחוז שינוי מבוסס edit distance על מילים (לא תווים). ספירת שינויים: הוספה, מחיקה, החלפה של מילים. נוסחה: (מספר שינויים / סך מילים בטקסט המקורי) * 100. כולל דוגמאות מפורטות ומקרי קצה כמו שינוי סדר מילים, שינויי פיסוק, וטיפול בסעיפים חדשים.",
|
"details": "הגדרת מדד אחוז שינוי מבוסס edit distance על מילים (לא תווים). ספירת שינויים: הוספה, מחיקה, החלפה של מילים. נוסחה: (מספר שינויים / סך מילים בטקסט המקורי) * 100. כולל דוגמאות מפורטות ומקרי קצה כמו שינוי סדר מילים, שינויי פיסוק, וטיפול בסעיפים חדשים.",
|
||||||
@@ -344,7 +344,7 @@
|
|||||||
"updatedAt": "2026-04-02T21:00:03.477Z"
|
"updatedAt": "2026-04-02T21:00:03.477Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "57",
|
"id": 57,
|
||||||
"title": "הוספת דרישות לבלוקים א-ד ויב",
|
"title": "הוספת דרישות לבלוקים א-ד ויב",
|
||||||
"description": "הגדרת דרישות פונקציונליות לבלוקים החסרים: כותרת, הרכב, צדדים וחתימות",
|
"description": "הגדרת דרישות פונקציונליות לבלוקים החסרים: כותרת, הרכב, צדדים וחתימות",
|
||||||
"details": "הגדרת דרישות מפורטות לבלוק א (כותרת התיק), בלוק ב (הרכב בית הדין), בלוק ג (זיהוי הצדדים), בלוק ד (פרטים נוספים על הצדדים), ובלוק יב (חתימות). כולל פורמט הפלט, מקורות המידע, וכללי עיבוד לכל בלוק. התאמה לתבנית הפסיקה הסטנדרטית.",
|
"details": "הגדרת דרישות מפורטות לבלוק א (כותרת התיק), בלוק ב (הרכב בית הדין), בלוק ג (זיהוי הצדדים), בלוק ד (פרטים נוספים על הצדדים), ובלוק יב (חתימות). כולל פורמט הפלט, מקורות המידע, וכללי עיבוד לכל בלוק. התאמה לתבנית הפסיקה הסטנדרטית.",
|
||||||
@@ -358,7 +358,7 @@
|
|||||||
"updatedAt": "2026-04-02T20:58:19.831Z"
|
"updatedAt": "2026-04-02T20:58:19.831Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "58",
|
"id": 58,
|
||||||
"title": "יישום מנגנון שמירת מצב ביניים (persistence)",
|
"title": "יישום מנגנון שמירת מצב ביניים (persistence)",
|
||||||
"description": "פיתוח מערכת לשמירת מצב העבודה ו-recovery מנפילות מערכת",
|
"description": "פיתוח מערכת לשמירת מצב העבודה ו-recovery מנפילות מערכת",
|
||||||
"details": "יישום מנגנון auto-save שמשמר את מצב העבודה כל כמה דקות. שמירת גרסאות ביניים של כל בלוק, מעקב אחר השלב הנוכחי בתהליך, ומנגנון recovery שמאפשר המשך עבודה מהנקודה האחרונה שנשמרה. כולל ממשק למשתמש לבחירת נקודת שחזור.",
|
"details": "יישום מנגנון auto-save שמשמר את מצב העבודה כל כמה דקות. שמירת גרסאות ביניים של כל בלוק, מעקב אחר השלב הנוכחי בתהליך, ומנגנון recovery שמאפשר המשך עבודה מהנקודה האחרונה שנשמרה. כולל ממשק למשתמש לבחירת נקודת שחזור.",
|
||||||
@@ -370,7 +370,7 @@
|
|||||||
"updatedAt": "2026-04-02T21:01:07.799Z"
|
"updatedAt": "2026-04-02T21:01:07.799Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "59",
|
"id": 59,
|
||||||
"title": "תיקון ספירת שלבים בטבלת מעקב",
|
"title": "תיקון ספירת שלבים בטבלת מעקב",
|
||||||
"description": "עדכון טבלת המעקב להתאמה למספר השלבים בפועל",
|
"description": "עדכון טבלת המעקב להתאמה למספר השלבים בפועל",
|
||||||
"details": "עדכון הטבלה לציון 7 שלבים במקום 6, כולל השלב החדש של הגהת דפנה. עדכון כל הרפרנסים למספר השלבים במסמכי הדרישות והתיעוד. וידוא עקביות בין כל המסמכים.",
|
"details": "עדכון הטבלה לציון 7 שלבים במקום 6, כולל השלב החדש של הגהת דפנה. עדכון כל הרפרנסים למספר השלבים במסמכי הדרישות והתיעוד. וידוא עקביות בין כל המסמכים.",
|
||||||
@@ -384,7 +384,7 @@
|
|||||||
"updatedAt": "2026-04-02T21:01:45.876Z"
|
"updatedAt": "2026-04-02T21:01:45.876Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "60",
|
"id": 60,
|
||||||
"title": "הכרה ב-MVP לרישוי והשבחה בלבד",
|
"title": "הכרה ב-MVP לרישוי והשבחה בלבד",
|
||||||
"description": "הגדרת גרסה ראשונה שמכסה רק רישוי והשבחה בשל חוסר נתוני אימון לפיצויים",
|
"description": "הגדרת גרסה ראשונה שמכסה רק רישוי והשבחה בשל חוסר נתוני אימון לפיצויים",
|
||||||
"details": "הגדרת MVP שמתמקד ברישוי והשבחה בלבד. תיעוד המגבלות הנוכחיות בנוגע לפיצויים ותכנית לאיסוף נתוני אימון עתידיים. הגדרת קריטריונים להרחבה לפיצויים בגרסאות עתידיות. עדכון מטריקות הצלחה בהתאם למגבלות הגרסה הראשונה.",
|
"details": "הגדרת MVP שמתמקד ברישוי והשבחה בלבד. תיעוד המגבלות הנוכחיות בנוגע לפיצויים ותכנית לאיסוף נתוני אימון עתידיים. הגדרת קריטריונים להרחבה לפיצויים בגרסאות עתידיות. עדכון מטריקות הצלחה בהתאם למגבלות הגרסה הראשונה.",
|
||||||
@@ -396,7 +396,7 @@
|
|||||||
"updatedAt": "2026-04-02T21:01:45.879Z"
|
"updatedAt": "2026-04-02T21:01:45.879Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "61",
|
"id": 61,
|
||||||
"title": "בחינה מחדש של יעד 98% שיעור שינוי",
|
"title": "בחינה מחדש של יעד 98% שיעור שינוי",
|
||||||
"description": "הערכה מחדש של ריאליות יעד 98% בהתבסס על מחקר Endsley על התנהגות מומחים",
|
"description": "הערכה מחדש של ריאליות יעד 98% בהתבסס על מחקר Endsley על התנהגות מומחים",
|
||||||
"details": "ניתוח מחקרי על התנהגות מומחים ונטייתם לבצע שינויים. הגדרת יעד ריאלי יותר המתחשב בגורמים פסיכולוגיים. הצעת מדדי הצלחה חלופיים כמו שיעור שינויים משמעותיים או שביעות רצון המומחים. כולל הגדרת baseline מתוך נתונים היסטוריים אם קיימים.",
|
"details": "ניתוח מחקרי על התנהגות מומחים ונטייתם לבצע שינויים. הגדרת יעד ריאלי יותר המתחשב בגורמים פסיכולוגיים. הצעת מדדי הצלחה חלופיים כמו שיעור שינויים משמעותיים או שביעות רצון המומחים. כולל הגדרת baseline מתוך נתונים היסטוריים אם קיימים.",
|
||||||
@@ -408,7 +408,7 @@
|
|||||||
"updatedAt": "2026-04-02T21:02:13.446Z"
|
"updatedAt": "2026-04-02T21:02:13.446Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "62",
|
"id": 62,
|
||||||
"title": "הגדרת מנגנון לולאת למידה",
|
"title": "הגדרת מנגנון לולאת למידה",
|
||||||
"description": "פיתוח מנגנון עדכון המודל על בסיס פידבק מדפנה ומשתמשים",
|
"description": "פיתוח מנגנון עדכון המודל על בסיס פידבק מדפנה ומשתמשים",
|
||||||
"details": "הגדרת אסטרטגיית עדכון המודל: fine-tuning מול prompt engineering מול עדכון RAG. יישום מנגנון איסוף פידבק מובנה, עיבוד הנתונים לפורמט מתאים לאימון, ותהליך עדכון אוטומטי או חצי-אוטומטי. כולל מנגנון A/B testing לבדיקת שיפורים.",
|
"details": "הגדרת אסטרטגיית עדכון המודל: fine-tuning מול prompt engineering מול עדכון RAG. יישום מנגנון איסוף פידבק מובנה, עיבוד הנתונים לפורמט מתאים לאימון, ותהליך עדכון אוטומטי או חצי-אוטומטי. כולל מנגנון A/B testing לבדיקת שיפורים.",
|
||||||
@@ -423,7 +423,7 @@
|
|||||||
"updatedAt": "2026-04-02T21:02:32.651Z"
|
"updatedAt": "2026-04-02T21:02:32.651Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "63",
|
"id": 63,
|
||||||
"title": "הוספת הגנה מפני prompt injection",
|
"title": "הוספת הגנה מפני prompt injection",
|
||||||
"description": "יישום מנגנון הגנה מפני prompt injection ממסמכי מקור חיצוניים",
|
"description": "יישום מנגנון הגנה מפני prompt injection ממסמכי מקור חיצוניים",
|
||||||
"details": "פיתוח מנגנון סינון וסניטיזציה של מסמכי קלט לזיהוי ניסיונות prompt injection. יישום validation של תוכן המסמכים, הפרדה בין הוראות המערכת לתוכן המסמכים, ומנגנון flagging של מסמכים חשודים. כולל רשימה שחורה של דפוסים מסוכנים.",
|
"details": "פיתוח מנגנון סינון וסניטיזציה של מסמכי קלט לזיהוי ניסיונות prompt injection. יישום validation של תוכן המסמכים, הפרדה בין הוראות המערכת לתוכן המסמכים, ומנגנון flagging של מסמכים חשודים. כולל רשימה שחורה של דפוסים מסוכנים.",
|
||||||
@@ -437,7 +437,7 @@
|
|||||||
"updatedAt": "2026-04-02T21:02:49.768Z"
|
"updatedAt": "2026-04-02T21:02:49.768Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "64",
|
"id": 64,
|
||||||
"title": "הוספת מנגנון back-flows בתהליך",
|
"title": "הוספת מנגנון back-flows בתהליך",
|
||||||
"description": "יישום יכולת חזרה אחורה בתהליך לעריכת בלוקים קודמים או שינוי כיוון",
|
"description": "יישום יכולת חזרה אחורה בתהליך לעריכת בלוקים קודמים או שינוי כיוון",
|
||||||
"details": "פיתוח ממשק לחזרה לשלבים קודמים בתהליך. מנגנון לעריכת בלוקים שכבר הושלמו, עדכון אוטומטי של בלוקים תלויים, ומעקב אחר שינויים. כולל אזהרות למשתמש על השפעת שינויים על בלוקים אחרים ואפשרות לביטול פעולות.",
|
"details": "פיתוח ממשק לחזרה לשלבים קודמים בתהליך. מנגנון לעריכת בלוקים שכבר הושלמו, עדכון אוטומטי של בלוקים תלויים, ומעקב אחר שינויים. כולל אזהרות למשתמש על השפעת שינויים על בלוקים אחרים ואפשרות לביטול פעולות.",
|
||||||
@@ -451,7 +451,7 @@
|
|||||||
"updatedAt": "2026-04-02T21:01:07.801Z"
|
"updatedAt": "2026-04-02T21:01:07.801Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "65",
|
"id": 65,
|
||||||
"title": "הוספת שלב QA/ולידציה לפני שליחה לדפנה",
|
"title": "הוספת שלב QA/ולידציה לפני שליחה לדפנה",
|
||||||
"description": "יישום checklist אוטומטי ומנגנון QA לפני הפלט הסופי",
|
"description": "יישום checklist אוטומטי ומנגנון QA לפני הפלט הסופי",
|
||||||
"details": "פיתוח checklist אוטומטי שבודק שלמות כל הבלוקים, תקינות הפורמט, נוכחות כל הרכיבים הנדרשים, ועקביות פנימית. מנגנון וולידציה של ציטוטים והפניות, בדיקת איכות השפה, ואזהרות על בעיות פוטנציאליות. כולל דוח QA מפורט למשתמש.",
|
"details": "פיתוח checklist אוטומטי שבודק שלמות כל הבלוקים, תקינות הפורמט, נוכחות כל הרכיבים הנדרשים, ועקביות פנימית. מנגנון וולידציה של ציטוטים והפניות, בדיקת איכות השפה, ואזהרות על בעיות פוטנציאליות. כולל דוח QA מפורט למשתמש.",
|
||||||
@@ -466,7 +466,7 @@
|
|||||||
"updatedAt": "2026-04-02T21:03:09.658Z"
|
"updatedAt": "2026-04-02T21:03:09.658Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "66",
|
"id": 66,
|
||||||
"title": "יישום ניהול גרסאות של בלוקים",
|
"title": "יישום ניהול גרסאות של בלוקים",
|
||||||
"description": "פיתוח מערכת ניהול גרסאות לכל בלוק בנפרד",
|
"description": "פיתוח מערכת ניהול גרסאות לכל בלוק בנפרד",
|
||||||
"details": "יישום version control לכל בלוק בנפרד, שמירת היסטוריית שינויים, יכולת השוואה בין גרסאות, ואפשרות לחזרה לגרסה קודמת של בלוק ספציפי. כולל ממשק גרפי להצגת ההבדלים בין גרסאות ומטא-דאטה על כל שינוי (זמן, משתמש, סיבה).",
|
"details": "יישום version control לכל בלוק בנפרד, שמירת היסטוריית שינויים, יכולת השוואה בין גרסאות, ואפשרות לחזרה לגרסה קודמת של בלוק ספציפי. כולל ממשק גרפי להצגת ההבדלים בין גרסאות ומטא-דאטה על כל שינוי (זמן, משתמש, סיבה).",
|
||||||
@@ -480,7 +480,7 @@
|
|||||||
"updatedAt": "2026-04-02T21:04:33.961Z"
|
"updatedAt": "2026-04-02T21:04:33.961Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "67",
|
"id": 67,
|
||||||
"title": "טיפול באיחוד תיקים",
|
"title": "טיפול באיחוד תיקים",
|
||||||
"description": "פיתוח מנגנון לטיפול באיחוד תיקים כמו במקרה אריאלי 1078+1083",
|
"description": "פיתוח מנגנון לטיפול באיחוד תיקים כמו במקרה אריאלי 1078+1083",
|
||||||
"details": "יישום לוגיקה לזיהוי תיקים הקשורים זה לזה ומנגנון איחוד אוטומטי או חצי-אוטומטי. טיפול בחפיפות מידע, פתרון קונפליקטים, ושמירת קישוריות בין התיקים המאוחדים. כולל ממשק למשתמש לאישור ועריכת האיחוד המוצע.",
|
"details": "יישום לוגיקה לזיהוי תיקים הקשורים זה לזה ומנגנון איחוד אוטומטי או חצי-אוטומטי. טיפול בחפיפות מידע, פתרון קונפליקטים, ושמירת קישוריות בין התיקים המאוחדים. כולל ממשק למשתמש לאישור ועריכת האיחוד המוצע.",
|
||||||
@@ -495,7 +495,7 @@
|
|||||||
"updatedAt": "2026-04-02T21:04:33.964Z"
|
"updatedAt": "2026-04-02T21:04:33.964Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "68",
|
"id": 68,
|
||||||
"title": "תיקון LOA של סיעור מוחות",
|
"title": "תיקון LOA של סיעור מוחות",
|
||||||
"description": "תיקון רמת האוטומציה של סיעור מוחות מרמה ג' לרמה ב'",
|
"description": "תיקון רמת האוטומציה של סיעור מוחות מרמה ג' לרמה ב'",
|
||||||
"details": "עדכון הגדרת רמת האוטומציה (LOA) של תהליך סיעור המוחות מרמה ג' (אוטומציה מלאה) לרמה ב' (אוטומציה עם פיקוח אנושי). עדכון כל המסמכים והממשקים הרלוונטיים. הבטחת התאמה לרמת הביקורת הנדרשת.",
|
"details": "עדכון הגדרת רמת האוטומציה (LOA) של תהליך סיעור המוחות מרמה ג' (אוטומציה מלאה) לרמה ב' (אוטומציה עם פיקוח אנושי). עדכון כל המסמכים והממשקים הרלוונטיים. הבטחת התאמה לרמת הביקורת הנדרשת.",
|
||||||
@@ -507,7 +507,7 @@
|
|||||||
"updatedAt": "2026-04-02T21:04:33.967Z"
|
"updatedAt": "2026-04-02T21:04:33.967Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "69",
|
"id": 69,
|
||||||
"title": "הגדרת סיעור מוחות כאופציונלי",
|
"title": "הגדרת סיעור מוחות כאופציונלי",
|
||||||
"description": "שינוי הגדרת סיעור המוחות לאופציונלי גם במקרים שיש נימוק קיים",
|
"description": "שינוי הגדרת סיעור המוחות לאופציונלי גם במקרים שיש נימוק קיים",
|
||||||
"details": "עדכון הלוגיקה כך שסיעור מוחות יהיה אופציונלי בכל המקרים, כולל כאשר קיים נימוק בסיסי. הוספת אפשרות למשתמש לבחור האם להפעיל סיעור מוחות או לדלג עליו. עדכון ממשק המשתמש והדרישות בהתאם.",
|
"details": "עדכון הלוגיקה כך שסיעור מוחות יהיה אופציונלי בכל המקרים, כולל כאשר קיים נימוק בסיסי. הוספת אפשרות למשתמש לבחור האם להפעיל סיעור מוחות או לדלג עליו. עדכון ממשק המשתמש והדרישות בהתאם.",
|
||||||
@@ -521,7 +521,7 @@
|
|||||||
"updatedAt": "2026-04-02T21:04:33.969Z"
|
"updatedAt": "2026-04-02T21:04:33.969Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "70",
|
"id": 70,
|
||||||
"title": "הוספת ניטרליות מבנית",
|
"title": "הוספת ניטרליות מבנית",
|
||||||
"description": "הרחבת דרישות הניטרליות מלקסיקלית למבנית",
|
"description": "הרחבת דרישות הניטרליות מלקסיקלית למבנית",
|
||||||
"details": "הגדרת כללים לניטרליות מבנית בנוסף ללקסיקלית: סדר הצגת הטיעונים, אורך היחסי של סעיפים, מיקום המידע, ומבנה הפסיקה. פיתוח מנגנון בדיקה אוטומטית לזיהוי הטיה מבנית ואזהרות למשתמש. כולל הנחיות לכתיבה מאוזנת.",
|
"details": "הגדרת כללים לניטרליות מבנית בנוסף ללקסיקלית: סדר הצגת הטיעונים, אורך היחסי של סעיפים, מיקום המידע, ומבנה הפסיקה. פיתוח מנגנון בדיקה אוטומטית לזיהוי הטיה מבנית ואזהרות למשתמש. כולל הנחיות לכתיבה מאוזנת.",
|
||||||
@@ -535,7 +535,7 @@
|
|||||||
"updatedAt": "2026-04-02T21:04:33.973Z"
|
"updatedAt": "2026-04-02T21:04:33.973Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "71",
|
"id": 71,
|
||||||
"title": "מיפוי פרסורמן 4 stages",
|
"title": "מיפוי פרסורמן 4 stages",
|
||||||
"description": "הרחבת המיפוי מ-LOA בלבד לכלל 4 השלבים של מודל פרסורמן",
|
"description": "הרחבת המיפוי מ-LOA בלבד לכלל 4 השלבים של מודל פרסורמן",
|
||||||
"details": "מיפוי מלא של התהליך לפי 4 השלבים של פרסורמן: Information acquisition, Information analysis, Decision selection, Action implementation. הגדרת רמת האוטומציה לכל שלב בנפרד ולא רק LOA כללי. עדכון התיעוד והדרישות בהתאם.",
|
"details": "מיפוי מלא של התהליך לפי 4 השלבים של פרסורמן: Information acquisition, Information analysis, Decision selection, Action implementation. הגדרת רמת האוטומציה לכל שלב בנפרד ולא רק LOA כללי. עדכון התיעוד והדרישות בהתאם.",
|
||||||
@@ -549,7 +549,7 @@
|
|||||||
"updatedAt": "2026-04-02T21:04:33.976Z"
|
"updatedAt": "2026-04-02T21:04:33.976Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "72",
|
"id": 72,
|
||||||
"title": "הגדרת דרישות ביצועים per-block וסינכרוני/אסינכרוני",
|
"title": "הגדרת דרישות ביצועים per-block וסינכרוני/אסינכרוני",
|
||||||
"description": "הגדרת דרישות ביצועים מפורטות לכל בלוק ובחירה בין עיבוד סינכרוני לאסינכרוני",
|
"description": "הגדרת דרישות ביצועים מפורטות לכל בלוק ובחירה בין עיבוד סינכרוני לאסינכרוני",
|
||||||
"details": "הגדרת SLA ספציפי לכל בלוק: זמני תגובה מקסימליים, throughput נדרש, ושיעור זמינות. החלטה על ארכיטקטורת עיבוד: סינכרונית לבלוקים קריטיים, אסינכרונית לבלוקים כבדים. יישום מנגנון ניטור ביצועים ואזהרות על חריגה מהסטנדרטים.",
|
"details": "הגדרת SLA ספציפי לכל בלוק: זמני תגובה מקסימליים, throughput נדרש, ושיעור זמינות. החלטה על ארכיטקטורת עיבוד: סינכרונית לבלוקים קריטיים, אסינכרונית לבלוקים כבדים. יישום מנגנון ניטור ביצועים ואזהרות על חריגה מהסטנדרטים.",
|
||||||
@@ -563,7 +563,7 @@
|
|||||||
"updatedAt": "2026-04-02T21:04:33.980Z"
|
"updatedAt": "2026-04-02T21:04:33.980Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "73",
|
"id": 73,
|
||||||
"title": "הרחבת DB schema לתהליך מלא",
|
"title": "הרחבת DB schema לתהליך מלא",
|
||||||
"description": "הוספת שדות וטבלאות חסרים לתמיכה בתהליך המלא של כתיבת החלטות משפטיות",
|
"description": "הוספת שדות וטבלאות חסרים לתמיכה בתהליך המלא של כתיבת החלטות משפטיות",
|
||||||
"details": "בקובץ db.py:\n1. הוספת שדות לטבלת decisions:\n - direction_doc JSONB - לשמירת מסמך הכיוון\n - outcome_reasoning TEXT - לנימוק התוצאה\n2. הרחבת enum של status בטבלת cases ל-13 ערכים:\n ['new', 'uploading', 'processing', 'documents_ready', 'outcome_set', 'brainstorming', 'direction_approved', 'drafting', 'qa_review', 'drafted', 'exported', 'reviewed', 'final']\n3. יצירת טבלת qa_results חדשה:\n - id SERIAL PRIMARY KEY\n - case_number VARCHAR REFERENCES cases\n - validation_type VARCHAR\n - passed BOOLEAN\n - errors JSONB\n - created_at TIMESTAMP\n4. יישום כ-migration עם Alembic",
|
"details": "בקובץ db.py:\n1. הוספת שדות לטבלת decisions:\n - direction_doc JSONB - לשמירת מסמך הכיוון\n - outcome_reasoning TEXT - לנימוק התוצאה\n2. הרחבת enum של status בטבלת cases ל-13 ערכים:\n ['new', 'uploading', 'processing', 'documents_ready', 'outcome_set', 'brainstorming', 'direction_approved', 'drafting', 'qa_review', 'drafted', 'exported', 'reviewed', 'final']\n3. יצירת טבלת qa_results חדשה:\n - id SERIAL PRIMARY KEY\n - case_number VARCHAR REFERENCES cases\n - validation_type VARCHAR\n - passed BOOLEAN\n - errors JSONB\n - created_at TIMESTAMP\n4. יישום כ-migration עם Alembic",
|
||||||
@@ -575,7 +575,7 @@
|
|||||||
"updatedAt": "2026-04-03T08:54:55.256Z"
|
"updatedAt": "2026-04-03T08:54:55.256Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "74",
|
"id": 74,
|
||||||
"title": "הוספת 5 API endpoints חדשים ב-MCP server",
|
"title": "הוספת 5 API endpoints חדשים ב-MCP server",
|
||||||
"description": "יצירת endpoints חדשים לתמיכה בתהליך כתיבת ההחלטות",
|
"description": "יצירת endpoints חדשים לתמיכה בתהליך כתיבת ההחלטות",
|
||||||
"details": "בקובץ server.py או בקבצי API:\n1. POST /api/cases/{case_number}/outcome\n - קבלת: {outcome: string, reasoning: string}\n - שמירה ב-DB\n - עדכון סטטוס ל-outcome_set\n2. GET /api/cases/{case_number}/claims\n - החזרת טענות מחולצות מה-JSONB\n3. POST /api/cases/{case_number}/direction\n - קבלת מסמך כיוון כ-JSON\n - שמירה בשדה direction_doc\n - עדכון סטטוס ל-direction_approved\n4. POST /api/cases/{case_number}/qa\n - הרצת בדיקות QA\n - שמירה בטבלת qa_results\n - החזרת תוצאות\n5. POST /api/cases/{case_number}/learn\n - הפעלת לולאת למידה\n - עדכון מודלים/פרמטרים",
|
"details": "בקובץ server.py או בקבצי API:\n1. POST /api/cases/{case_number}/outcome\n - קבלת: {outcome: string, reasoning: string}\n - שמירה ב-DB\n - עדכון סטטוס ל-outcome_set\n2. GET /api/cases/{case_number}/claims\n - החזרת טענות מחולצות מה-JSONB\n3. POST /api/cases/{case_number}/direction\n - קבלת מסמך כיוון כ-JSON\n - שמירה בשדה direction_doc\n - עדכון סטטוס ל-direction_approved\n4. POST /api/cases/{case_number}/qa\n - הרצת בדיקות QA\n - שמירה בטבלת qa_results\n - החזרת תוצאות\n5. POST /api/cases/{case_number}/learn\n - הפעלת לולאת למידה\n - עדכון מודלים/פרמטרים",
|
||||||
@@ -589,7 +589,7 @@
|
|||||||
"updatedAt": "2026-04-03T08:55:56.839Z"
|
"updatedAt": "2026-04-03T08:55:56.839Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "75",
|
"id": 75,
|
||||||
"title": "הוספת 8 tools חדשים לפלאגין Paperclip",
|
"title": "הוספת 8 tools חדשים לפלאגין Paperclip",
|
||||||
"description": "הרחבת הפלאגין עם כלים חדשים לאינטראקציה עם המערכת המשפטית",
|
"description": "הרחבת הפלאגין עם כלים חדשים לאינטראקציה עם המערכת המשפטית",
|
||||||
"details": "1. בקובץ src/worker.ts - הוספת 8 tools:\n - legal_document_upload: העלאת מסמך\n - legal_document_list: רשימת מסמכים\n - legal_document_text: קריאת טקסט ממסמך\n - legal_search_case: חיפוש תיק\n - legal_find_similar: מציאת תקדימים\n - legal_set_outcome: הגדרת תוצאה\n - legal_get_claims: קבלת טענות\n - legal_style_guide: קבלת הנחיות סגנון\n\n2. בקובץ src/legal-api.ts - יישום 8 methods:\n ```typescript\n async uploadDocument(caseNumber: string, file: File) {...}\n async listDocuments(caseNumber: string) {...}\n async getDocumentText(docId: string) {...}\n async searchCase(query: string) {...}\n async findSimilar(caseNumber: string) {...}\n async setOutcome(caseNumber: string, outcome: string, reasoning: string) {...}\n async getClaims(caseNumber: string) {...}\n async getStyleGuide() {...}\n ```\n\n3. בקובץ plugin.json - עדכון manifest",
|
"details": "1. בקובץ src/worker.ts - הוספת 8 tools:\n - legal_document_upload: העלאת מסמך\n - legal_document_list: רשימת מסמכים\n - legal_document_text: קריאת טקסט ממסמך\n - legal_search_case: חיפוש תיק\n - legal_find_similar: מציאת תקדימים\n - legal_set_outcome: הגדרת תוצאה\n - legal_get_claims: קבלת טענות\n - legal_style_guide: קבלת הנחיות סגנון\n\n2. בקובץ src/legal-api.ts - יישום 8 methods:\n ```typescript\n async uploadDocument(caseNumber: string, file: File) {...}\n async listDocuments(caseNumber: string) {...}\n async getDocumentText(docId: string) {...}\n async searchCase(query: string) {...}\n async findSimilar(caseNumber: string) {...}\n async setOutcome(caseNumber: string, outcome: string, reasoning: string) {...}\n async getClaims(caseNumber: string) {...}\n async getStyleGuide() {...}\n ```\n\n3. בקובץ plugin.json - עדכון manifest",
|
||||||
@@ -603,7 +603,7 @@
|
|||||||
"updatedAt": "2026-04-03T08:59:27.838Z"
|
"updatedAt": "2026-04-03T08:59:27.838Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "76",
|
"id": 76,
|
||||||
"title": "שיפור status sync ב-Paperclip",
|
"title": "שיפור status sync ב-Paperclip",
|
||||||
"description": "מיפוי מלא של 13 סטטוסים והוספת comments מפורטים",
|
"description": "מיפוי מלא של 13 סטטוסים והוספת comments מפורטים",
|
||||||
"details": "1. עדכון מיפוי סטטוסים:\n ```javascript\n const statusMapping = {\n 'new': 'תיק חדש',\n 'uploading': 'העלאת מסמכים',\n 'processing': 'עיבוד מסמכים',\n 'documents_ready': 'מסמכים מוכנים',\n 'outcome_set': 'תוצאה הוגדרה',\n 'brainstorming': 'גיבוש כיוון',\n 'direction_approved': 'כיוון אושר',\n 'drafting': 'כתיבת החלטה',\n 'qa_review': 'בדיקת איכות',\n 'drafted': 'טיוטה מוכנה',\n 'exported': 'יוצאה ל-DOCX',\n 'reviewed': 'נבדקה ע\"י עו\"ד',\n 'final': 'סופית'\n }\n ```\n\n2. הוספת comments אוטומטיים ב-Paperclip:\n - בכל מעבר סטטוס\n - עם timestamp\n - עם פירוט הפעולה\n\n3. עדכון job sync-case-status",
|
"details": "1. עדכון מיפוי סטטוסים:\n ```javascript\n const statusMapping = {\n 'new': 'תיק חדש',\n 'uploading': 'העלאת מסמכים',\n 'processing': 'עיבוד מסמכים',\n 'documents_ready': 'מסמכים מוכנים',\n 'outcome_set': 'תוצאה הוגדרה',\n 'brainstorming': 'גיבוש כיוון',\n 'direction_approved': 'כיוון אושר',\n 'drafting': 'כתיבת החלטה',\n 'qa_review': 'בדיקת איכות',\n 'drafted': 'טיוטה מוכנה',\n 'exported': 'יוצאה ל-DOCX',\n 'reviewed': 'נבדקה ע\"י עו\"ד',\n 'final': 'סופית'\n }\n ```\n\n2. הוספת comments אוטומטיים ב-Paperclip:\n - בכל מעבר סטטוס\n - עם timestamp\n - עם פירוט הפעולה\n\n3. עדכון job sync-case-status",
|
||||||
@@ -617,7 +617,7 @@
|
|||||||
"updatedAt": "2026-04-03T09:00:19.243Z"
|
"updatedAt": "2026-04-03T09:00:19.243Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "77",
|
"id": 77,
|
||||||
"title": "כתיבת SOUL.md לסוכנים",
|
"title": "כתיבת SOUL.md לסוכנים",
|
||||||
"description": "יצירת קבצי הנחיות לסוכני AI בעברית",
|
"description": "יצירת קבצי הנחיות לסוכני AI בעברית",
|
||||||
"details": "1. CEO Agent SOUL.md:\n ```markdown\n # CEO Agent - סוכן מנהל\n \n ## תפקיד\n ניהול תהליך כתיבת החלטה משפטית מקצה לקצה\n \n ## הנחיות\n - עבוד בעברית תמיד\n - נהל את התהליך לפי 13 הסטטוסים\n - התרע לחיים במקרים: תקלה טכנית, החלטה מורכבת, חריגה מזמנים\n - וודא שכל שלב הושלם לפני מעבר לבא\n \n ## מיפוי סטטוסים\n [רשימת 13 סטטוסים עם הסבר לכל אחד]\n ```\n\n2. Case Analyst Agent SOUL.md:\n ```markdown\n # Case Analyst - סוכן מנתח\n \n ## תפקיד\n ניתוח מסמכים משפטיים וחילוץ מידע\n \n ## הנחיות\n - נתח מסמכים בעברית\n - חלץ טענות מרכזיות\n - זהה תקדימים רלוונטיים\n - סכם עובדות מהותיות\n ```",
|
"details": "1. CEO Agent SOUL.md:\n ```markdown\n # CEO Agent - סוכן מנהל\n \n ## תפקיד\n ניהול תהליך כתיבת החלטה משפטית מקצה לקצה\n \n ## הנחיות\n - עבוד בעברית תמיד\n - נהל את התהליך לפי 13 הסטטוסים\n - התרע לחיים במקרים: תקלה טכנית, החלטה מורכבת, חריגה מזמנים\n - וודא שכל שלב הושלם לפני מעבר לבא\n \n ## מיפוי סטטוסים\n [רשימת 13 סטטוסים עם הסבר לכל אחד]\n ```\n\n2. Case Analyst Agent SOUL.md:\n ```markdown\n # Case Analyst - סוכן מנתח\n \n ## תפקיד\n ניתוח מסמכים משפטיים וחילוץ מידע\n \n ## הנחיות\n - נתח מסמכים בעברית\n - חלץ טענות מרכזיות\n - זהה תקדימים רלוונטיים\n - סכם עובדות מהותיות\n ```",
|
||||||
@@ -629,7 +629,7 @@
|
|||||||
"updatedAt": "2026-04-03T08:57:14.984Z"
|
"updatedAt": "2026-04-03T08:57:14.984Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "78",
|
"id": 78,
|
||||||
"title": "יישום skill /brainstorm",
|
"title": "יישום skill /brainstorm",
|
||||||
"description": "יצירת skill לגיבוש כיוון ההחלטה בשיתוף עם המשתמש",
|
"description": "יצירת skill לגיבוש כיוון ההחלטה בשיתוף עם המשתמש",
|
||||||
"details": "בקובץ skills/brainstorm.ts:\n```typescript\nexport async function brainstorm(caseNumber: string) {\n // שלב 1: הצגת טענות מרכזיות\n const claims = await api.getClaims(caseNumber);\n displayClaims(claims);\n \n // שלב 2: הצעת 2-3 כיוונים\n const directions = generateDirections(claims);\n displayDirections(directions);\n \n // שלב 3: דיון אינטראקטיבי\n let approved = false;\n while (!approved) {\n const feedback = await getUserFeedback();\n if (feedback.type === 'approve') {\n approved = true;\n } else {\n directions = refineDirections(directions, feedback);\n }\n }\n \n // שלב 4: יצירת מסמך כיוון\n const directionDoc = {\n mainDirection: directions.selected,\n keyPoints: directions.keyPoints,\n precedents: directions.precedents,\n approvedBy: 'user',\n timestamp: new Date()\n };\n \n // שלב 5: שמירה ועדכון סטטוס\n await api.saveDirection(caseNumber, directionDoc);\n}\n```",
|
"details": "בקובץ skills/brainstorm.ts:\n```typescript\nexport async function brainstorm(caseNumber: string) {\n // שלב 1: הצגת טענות מרכזיות\n const claims = await api.getClaims(caseNumber);\n displayClaims(claims);\n \n // שלב 2: הצעת 2-3 כיוונים\n const directions = generateDirections(claims);\n displayDirections(directions);\n \n // שלב 3: דיון אינטראקטיבי\n let approved = false;\n while (!approved) {\n const feedback = await getUserFeedback();\n if (feedback.type === 'approve') {\n approved = true;\n } else {\n directions = refineDirections(directions, feedback);\n }\n }\n \n // שלב 4: יצירת מסמך כיוון\n const directionDoc = {\n mainDirection: directions.selected,\n keyPoints: directions.keyPoints,\n precedents: directions.precedents,\n approvedBy: 'user',\n timestamp: new Date()\n };\n \n // שלב 5: שמירה ועדכון סטטוס\n await api.saveDirection(caseNumber, directionDoc);\n}\n```",
|
||||||
@@ -643,7 +643,7 @@
|
|||||||
"updatedAt": "2026-04-03T10:16:24.667Z"
|
"updatedAt": "2026-04-03T10:16:24.667Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "79",
|
"id": 79,
|
||||||
"title": "שיפור skill /draft-decision לכתיבה בלוק-אחרי-בלוק",
|
"title": "שיפור skill /draft-decision לכתיבה בלוק-אחרי-בלוק",
|
||||||
"description": "שדרוג מ-stub לכתיבה מלאה עם 12 בלוקים",
|
"description": "שדרוג מ-stub לכתיבה מלאה עם 12 בלוקים",
|
||||||
"details": "בקובץ skills/draft-decision.ts:\n```typescript\nconst BLOCKS = [\n {id: 'ה', name: 'כותרת', temperature: 0.3},\n {id: 'ו', name: 'פתיח', temperature: 0.5},\n {id: 'ז', name: 'רקע', temperature: 0.4},\n {id: 'ח', name: 'טענות הצדדים', temperature: 0.3},\n {id: 'ט', name: 'תמצית', temperature: 0.6},\n {id: 'י', name: 'דיון והכרעה', temperature: 0.7, model: 'opus'},\n {id: 'יא', name: 'סוף דבר', temperature: 0.5}\n];\n\nexport async function draftDecision(caseNumber: string) {\n const direction = await api.getDirection(caseNumber);\n const lastBlock = await getLastCompletedBlock(caseNumber);\n \n for (let i = getBlockIndex(lastBlock) + 1; i < BLOCKS.length; i++) {\n const block = BLOCKS[i];\n \n // כתיבת בלוק\n const content = await writeBlock(block, {\n direction,\n previousBlocks: await getPreviousBlocks(caseNumber, i),\n temperature: block.temperature,\n model: block.model || 'default'\n });\n \n // שמירה מיידית\n await saveBlock(caseNumber, block.id, content);\n \n // בלוק י - CREAC + thinking\n if (block.id === 'י') {\n await applyCREAC(content);\n await addThinkingTags(content);\n }\n }\n}\n\n// Recovery function\nexport async function recoverDraft(caseNumber: string) {\n const lastBlock = await getLastCompletedBlock(caseNumber);\n return draftDecision(caseNumber); // ממשיך מאיפה שנפל\n}\n```",
|
"details": "בקובץ skills/draft-decision.ts:\n```typescript\nconst BLOCKS = [\n {id: 'ה', name: 'כותרת', temperature: 0.3},\n {id: 'ו', name: 'פתיח', temperature: 0.5},\n {id: 'ז', name: 'רקע', temperature: 0.4},\n {id: 'ח', name: 'טענות הצדדים', temperature: 0.3},\n {id: 'ט', name: 'תמצית', temperature: 0.6},\n {id: 'י', name: 'דיון והכרעה', temperature: 0.7, model: 'opus'},\n {id: 'יא', name: 'סוף דבר', temperature: 0.5}\n];\n\nexport async function draftDecision(caseNumber: string) {\n const direction = await api.getDirection(caseNumber);\n const lastBlock = await getLastCompletedBlock(caseNumber);\n \n for (let i = getBlockIndex(lastBlock) + 1; i < BLOCKS.length; i++) {\n const block = BLOCKS[i];\n \n // כתיבת בלוק\n const content = await writeBlock(block, {\n direction,\n previousBlocks: await getPreviousBlocks(caseNumber, i),\n temperature: block.temperature,\n model: block.model || 'default'\n });\n \n // שמירה מיידית\n await saveBlock(caseNumber, block.id, content);\n \n // בלוק י - CREAC + thinking\n if (block.id === 'י') {\n await applyCREAC(content);\n await addThinkingTags(content);\n }\n }\n}\n\n// Recovery function\nexport async function recoverDraft(caseNumber: string) {\n const lastBlock = await getLastCompletedBlock(caseNumber);\n return draftDecision(caseNumber); // ממשיך מאיפה שנפל\n}\n```",
|
||||||
@@ -658,7 +658,7 @@
|
|||||||
"updatedAt": "2026-04-03T10:16:24.670Z"
|
"updatedAt": "2026-04-03T10:16:24.670Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "80",
|
"id": 80,
|
||||||
"title": "יישום skill /qa-validate",
|
"title": "יישום skill /qa-validate",
|
||||||
"description": "בדיקות איכות אוטומטיות על ההחלטה",
|
"description": "בדיקות איכות אוטומטיות על ההחלטה",
|
||||||
"details": "בקובץ skills/qa-validate.ts:\n```typescript\nexport async function qaValidate(caseNumber: string) {\n const decision = await api.getDecision(caseNumber);\n const documents = await api.getDocuments(caseNumber);\n const claims = await api.getClaims(caseNumber);\n \n const checks = [\n {\n name: 'grounding_check',\n fn: () => validateGrounding(decision, documents),\n critical: true\n },\n {\n name: 'claims_coverage',\n fn: () => validateClaimsCoverage(decision, claims),\n critical: true\n },\n {\n name: 'neutral_background',\n fn: () => validateNeutrality(decision.background),\n critical: false\n },\n {\n name: 'weights_range',\n fn: () => validateWeightsInRange(decision),\n critical: true\n },\n {\n name: 'sequential_numbering',\n fn: () => validateNumbering(decision),\n critical: false\n },\n {\n name: 'definitions',\n fn: () => validateDefinitions(decision),\n critical: false\n }\n ];\n \n const results = [];\n let hasErrors = false;\n \n for (const check of checks) {\n const result = await check.fn();\n results.push({...result, name: check.name});\n if (!result.passed && check.critical) {\n hasErrors = true;\n }\n }\n \n // שמירת תוצאות\n await api.saveQAResults(caseNumber, results);\n \n // חסימת ייצוא אם יש שגיאות קריטיות\n if (hasErrors) {\n await api.blockExport(caseNumber);\n throw new Error('QA failed - export blocked');\n }\n \n return results;\n}\n```",
|
"details": "בקובץ skills/qa-validate.ts:\n```typescript\nexport async function qaValidate(caseNumber: string) {\n const decision = await api.getDecision(caseNumber);\n const documents = await api.getDocuments(caseNumber);\n const claims = await api.getClaims(caseNumber);\n \n const checks = [\n {\n name: 'grounding_check',\n fn: () => validateGrounding(decision, documents),\n critical: true\n },\n {\n name: 'claims_coverage',\n fn: () => validateClaimsCoverage(decision, claims),\n critical: true\n },\n {\n name: 'neutral_background',\n fn: () => validateNeutrality(decision.background),\n critical: false\n },\n {\n name: 'weights_range',\n fn: () => validateWeightsInRange(decision),\n critical: true\n },\n {\n name: 'sequential_numbering',\n fn: () => validateNumbering(decision),\n critical: false\n },\n {\n name: 'definitions',\n fn: () => validateDefinitions(decision),\n critical: false\n }\n ];\n \n const results = [];\n let hasErrors = false;\n \n for (const check of checks) {\n const result = await check.fn();\n results.push({...result, name: check.name});\n if (!result.passed && check.critical) {\n hasErrors = true;\n }\n }\n \n // שמירת תוצאות\n await api.saveQAResults(caseNumber, results);\n \n // חסימת ייצוא אם יש שגיאות קריטיות\n if (hasErrors) {\n await api.blockExport(caseNumber);\n throw new Error('QA failed - export blocked');\n }\n \n return results;\n}\n```",
|
||||||
@@ -672,7 +672,7 @@
|
|||||||
"updatedAt": "2026-04-03T10:16:24.673Z"
|
"updatedAt": "2026-04-03T10:16:24.673Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "81",
|
"id": 81,
|
||||||
"title": "אינטגרציה E2E וחיבור Paperclip events",
|
"title": "אינטגרציה E2E וחיבור Paperclip events",
|
||||||
"description": "חיבור מלא בין Paperclip ל-Claude Code עם trigger אוטומטי",
|
"description": "חיבור מלא בין Paperclip ל-Claude Code עם trigger אוטומטי",
|
||||||
"details": "1. חיבור Paperclip events:\n```javascript\n// בקובץ paperclip-integration.js\npaperclip.on('issue.comment.created', async (event) => {\n if (event.comment.includes('/draft')) {\n await claudeCode.trigger('draft-decision', {\n caseNumber: event.issue.number\n });\n }\n});\n```\n\n2. E2E test על תיק הכט:\n```javascript\ntest('full flow - Hecht case', async () => {\n // העלאת חומרים\n await uploadDocuments('hecht', ['doc1.pdf', 'doc2.pdf']);\n \n // הזנת תוצאה\n await setOutcome('hecht', 'rejected', 'אין עילה');\n \n // כתיבה\n await triggerDraft('hecht');\n await waitForStatus('drafted');\n \n // QA\n const qaResults = await runQA('hecht');\n expect(qaResults.passed).toBe(true);\n \n // ייצוא\n const docx = await exportToDocx('hecht');\n \n // השוואה\n const similarity = await compareToFinal(docx, 'hecht-final.docx');\n expect(similarity).toBeGreaterThan(0.9);\n});\n```",
|
"details": "1. חיבור Paperclip events:\n```javascript\n// בקובץ paperclip-integration.js\npaperclip.on('issue.comment.created', async (event) => {\n if (event.comment.includes('/draft')) {\n await claudeCode.trigger('draft-decision', {\n caseNumber: event.issue.number\n });\n }\n});\n```\n\n2. E2E test על תיק הכט:\n```javascript\ntest('full flow - Hecht case', async () => {\n // העלאת חומרים\n await uploadDocuments('hecht', ['doc1.pdf', 'doc2.pdf']);\n \n // הזנת תוצאה\n await setOutcome('hecht', 'rejected', 'אין עילה');\n \n // כתיבה\n await triggerDraft('hecht');\n await waitForStatus('drafted');\n \n // QA\n const qaResults = await runQA('hecht');\n expect(qaResults.passed).toBe(true);\n \n // ייצוא\n const docx = await exportToDocx('hecht');\n \n // השוואה\n const similarity = await compareToFinal(docx, 'hecht-final.docx');\n expect(similarity).toBeGreaterThan(0.9);\n});\n```",
|
||||||
@@ -691,7 +691,7 @@
|
|||||||
"updatedAt": "2026-04-03T10:19:26.776Z"
|
"updatedAt": "2026-04-03T10:19:26.776Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "82",
|
"id": 82,
|
||||||
"title": "מבחן הסמכה",
|
"title": "מבחן הסמכה",
|
||||||
"description": "בדיקת המערכת על תיק עם החלטה קיימת והשוואת איכות",
|
"description": "בדיקת המערכת על תיק עם החלטה קיימת והשוואת איכות",
|
||||||
"details": "שלב ב - בדיקה על תיק עם החלטה:\n```javascript\nexport async function certificationTest() {\n // בחירת תיק עם החלטה סופית\n const testCase = await selectTestCase();\n \n // הסתרת ההחלטה המקורית\n await hideOriginalDecision(testCase.number);\n \n // הרצת המערכת\n await runFullFlow(testCase.number);\n \n // השוואה\n const draft = await getDecision(testCase.number);\n const original = testCase.originalDecision;\n \n const comparison = {\n structure: compareStructure(draft, original),\n content: compareContent(draft, original),\n reasoning: compareReasoning(draft, original),\n outcome: compareOutcome(draft, original)\n };\n \n // חישוב ציון כולל\n const score = calculateScore(comparison);\n \n // בדיקת סף - 90%\n if (score < 0.9) {\n throw new Error(`Score ${score} is below threshold`);\n }\n \n return {score, comparison};\n}\n\n// שלב ג - תיק חי\nexport async function liveTest() {\n const liveCase = await getLiveCase();\n await runFullFlow(liveCase.number);\n \n // שליחה לדפנה לבדיקה\n await sendForReview('dafna@law.firm', liveCase.number);\n}\n```",
|
"details": "שלב ב - בדיקה על תיק עם החלטה:\n```javascript\nexport async function certificationTest() {\n // בחירת תיק עם החלטה סופית\n const testCase = await selectTestCase();\n \n // הסתרת ההחלטה המקורית\n await hideOriginalDecision(testCase.number);\n \n // הרצת המערכת\n await runFullFlow(testCase.number);\n \n // השוואה\n const draft = await getDecision(testCase.number);\n const original = testCase.originalDecision;\n \n const comparison = {\n structure: compareStructure(draft, original),\n content: compareContent(draft, original),\n reasoning: compareReasoning(draft, original),\n outcome: compareOutcome(draft, original)\n };\n \n // חישוב ציון כולל\n const score = calculateScore(comparison);\n \n // בדיקת סף - 90%\n if (score < 0.9) {\n throw new Error(`Score ${score} is below threshold`);\n }\n \n return {score, comparison};\n}\n\n// שלב ג - תיק חי\nexport async function liveTest() {\n const liveCase = await getLiveCase();\n await runFullFlow(liveCase.number);\n \n // שליחה לדפנה לבדיקה\n await sendForReview('dafna@law.firm', liveCase.number);\n}\n```",
|
||||||
@@ -703,16 +703,184 @@
|
|||||||
"status": "deferred",
|
"status": "deferred",
|
||||||
"subtasks": [],
|
"subtasks": [],
|
||||||
"updatedAt": "2026-04-03T10:19:26.779Z"
|
"updatedAt": "2026-04-03T10:19:26.779Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "83",
|
||||||
|
"title": "Phase 1 — Project setup (legal-ai UI rewrite)",
|
||||||
|
"description": "הקמת scaffold של Next.js עם TypeScript + Tailwind v4 + App Router ב-web-ui/. התקנת כל התלויות: @tanstack/react-query, @tanstack/react-table, react-hook-form, @hookform/resolvers, zod, lucide-react, react-dropzone, openapi-typescript. העברת design-system.css tokens (navy/gold/parchment, Heebo) ל-Tailwind theme דרך @theme ו-CSS variables. הגדרת RTL עברית עם Heebo via next/font/google. בניית AppShell עם navy header + gold rule + nav.",
|
||||||
|
"status": "in-progress",
|
||||||
|
"dependencies": [],
|
||||||
|
"priority": "high",
|
||||||
|
"details": "**השלמות (2026-04-11):**\n\n✅ **Scaffold:** Next.js 16.2.3 (חדש יותר מ-v15 שתוכנן), React 19.2.4, Tailwind v4, Turbopack.\n\n✅ **תלויות מותקנות** (`web-ui/package.json:11-21`):\n- @tanstack/react-query ^5.97.0\n- @tanstack/react-table ^8.21.3\n- react-hook-form ^7.72.1 + @hookform/resolvers ^5.2.2\n- zod ^4.3.6\n- lucide-react ^1.8.0\n- react-dropzone ^15.0.0\n- openapi-typescript ^7.13.0 (devDep)\n\n✅ **Design tokens** (`web-ui/src/app/globals.css:10-107`): Tailwind v4 @theme עם כל הצבעים (navy, cream, parchment, gold, ink, status colors), radii, shadows, fonts, dark mode preserved.\n\n✅ **RTL Hebrew** (`web-ui/src/app/layout.tsx:5-10, 23`): Heebo עם hebrew+latin subsets, `lang=\"he\" dir=\"rtl\"` on html.\n\n✅ **AppShell** (`web-ui/src/components/app-shell.tsx:29-70`): Navy header עם gold border-b-3, RTL nav, parchment body.\n\n✅ **Home page placeholder** (`web-ui/src/app/page.tsx`).\n\n✅ **Build:** `npm run build` עובר ב-3.8s, 0 errors, static.\n\n**נותר:** אישור ויזואלי של המשתמש עם `npm run dev`.\n\n**תוכנית מלאה:** `~/.claude/plans/joyful-marinating-sutton.md`",
|
||||||
|
"testStrategy": "1. `cd web-ui && npm run dev` — פתיחה ב-http://localhost:3000\n2. וידוא ויזואלי: Header navy עם gold rule, RTL rendering, פונט Heebo טעון\n3. השוואה ל-legal-ai.nautilus.marcusgroup.org — אותו מראה header\n4. בדיקת dark mode (toggle class על html)\n5. אישור סופי מהמשתמש",
|
||||||
|
"subtasks": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"title": "יצירת Next.js 16 scaffold עם TypeScript + Tailwind v4 + App Router",
|
||||||
|
"description": "הרצת create-next-app ב-web-ui/ עם App Router, TypeScript, Tailwind v4, ESLint",
|
||||||
|
"dependencies": [],
|
||||||
|
"details": "Next.js 16.2.3 (חדש יותר מ-v15), React 19.2.4, Tailwind v4, Turbopack. קבצים: web-ui/package.json, tsconfig.json, next.config.ts",
|
||||||
|
"status": "done",
|
||||||
|
"testStrategy": "npm run build succeeds"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"title": "התקנת כל התלויות הנדרשות",
|
||||||
|
"description": "npm install של @tanstack/react-query, @tanstack/react-table, react-hook-form, @hookform/resolvers, zod, lucide-react, react-dropzone, openapi-typescript",
|
||||||
|
"dependencies": [
|
||||||
|
1
|
||||||
|
],
|
||||||
|
"details": "ראה web-ui/package.json:11-21 לגרסאות המותקנות. כולל openapi-typescript כ-devDep לשלב 2.",
|
||||||
|
"status": "done",
|
||||||
|
"testStrategy": "npm ls shows all packages"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 3,
|
||||||
|
"title": "העברת design tokens ל-Tailwind v4 @theme",
|
||||||
|
"description": "פורט מלא של design-system.css ל-globals.css עם Tailwind v4 @theme syntax",
|
||||||
|
"dependencies": [
|
||||||
|
1
|
||||||
|
],
|
||||||
|
"details": "web-ui/src/app/globals.css:10-107 כולל כל הצבעים (navy, cream, parchment, gold, ink), status colors, radii, shadows, fonts, dark mode. CSS variables עובדים עם Tailwind classes.",
|
||||||
|
"status": "done",
|
||||||
|
"testStrategy": "Tailwind classes like bg-navy, text-gold work correctly"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 4,
|
||||||
|
"title": "הגדרת RTL Hebrew עם Heebo font",
|
||||||
|
"description": "next/font/google Heebo עם hebrew+latin, lang=he dir=rtl על html",
|
||||||
|
"dependencies": [
|
||||||
|
1
|
||||||
|
],
|
||||||
|
"details": "web-ui/src/app/layout.tsx:5-10 — Heebo עם weights 300-900, display swap. שורה 23: html lang=he dir=rtl.",
|
||||||
|
"status": "done",
|
||||||
|
"testStrategy": "Page renders RTL, Heebo font loaded"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 5,
|
||||||
|
"title": "בניית AppShell component עם navy header + gold rule",
|
||||||
|
"description": "רכיב shell עם header navy, gold border, RTL nav, parchment body",
|
||||||
|
"dependencies": [
|
||||||
|
3,
|
||||||
|
4
|
||||||
|
],
|
||||||
|
"details": "web-ui/src/components/app-shell.tsx:29-70 — Header עם bg-navy, border-b-3 border-gold, nav links (בית, העלאת מסמכים, אימון סגנון, מיומנויות, אבחון), main content area עם max-w-1400px.",
|
||||||
|
"status": "done",
|
||||||
|
"testStrategy": "Visual match to current header"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 6,
|
||||||
|
"title": "יצירת דף בית placeholder",
|
||||||
|
"description": "דף page.tsx עם AppShell ו-placeholder content",
|
||||||
|
"dependencies": [
|
||||||
|
5
|
||||||
|
],
|
||||||
|
"details": "web-ui/src/app/page.tsx:1-27 — דף בית עם כותרת 'עוזר משפטי', תיאור המערכת, gold gradient divider, כרטיס סטטוס.",
|
||||||
|
"status": "done",
|
||||||
|
"testStrategy": "npm run build succeeds (done: 3.8s, 0 errors)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 7,
|
||||||
|
"title": "אישור ויזואלי מהמשתמש — npm run dev",
|
||||||
|
"description": "הרצת dev server ואישור סופי שה-UI תואם לציפיות — header, RTL, fonts, colors",
|
||||||
|
"dependencies": [
|
||||||
|
6
|
||||||
|
],
|
||||||
|
"details": "המשתמש צריך להריץ 'cd web-ui && npm run dev' ולאשר שהכל נראה כמו legal-ai.nautilus.marcusgroup.org. בדיקת dark mode אופציונלית.",
|
||||||
|
"status": "pending",
|
||||||
|
"testStrategy": "User confirms visual parity with current site, RTL works, Heebo font loads"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 84,
|
||||||
|
"title": "Phase 2 — API client + generated TypeScript types",
|
||||||
|
"description": "Add npm run api:types script that runs openapi-typescript against FastAPI's /openapi.json -> src/lib/api/types.ts. Build lib/api/client.ts (typed fetch wrapper + TanStack Query client with default retry/staleTime). Create one lib/api/<domain>.ts per endpoint category (cases, upload, compose, training, system), each exporting typed useQuery/useMutation hooks. Build lib/sse.ts as EventSource -> Query cache adapter. Plan: ~/.claude/plans/joyful-marinating-sutton.md.",
|
||||||
|
"details": "See full plan at ~/.claude/plans/joyful-marinating-sutton.md for architecture, critical files, risks, and open questions. This task is phase 2 of 7 in the legal-ai UI rewrite from vanilla HTML to Next.js 15 + shadcn/ui.",
|
||||||
|
"testStrategy": "useCases() hook returns typed array from live FastAPI. TypeScript errors if backend endpoint changes without frontend update.",
|
||||||
|
"status": "pending",
|
||||||
|
"dependencies": [
|
||||||
|
"83"
|
||||||
|
],
|
||||||
|
"priority": "high",
|
||||||
|
"subtasks": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 85,
|
||||||
|
"title": "Phase 3 — Core read views (home, case detail, compose)",
|
||||||
|
"description": "Port the 3 highest-value screens. Use the frontend-design Claude Code skill to generate layout + composition, passing design tokens (navy/gold/parchment, Heebo), editorial voice, and typed API hooks. Use shadcn Card/Badge/Tabs/Sheet/ScrollArea as primitives. Port the custom donut chart into <DonutChart> component. TanStack Query staleTime:5000 for case detail replaces manual 5s polling. Plan: ~/.claude/plans/joyful-marinating-sutton.md.",
|
||||||
|
"details": "See full plan at ~/.claude/plans/joyful-marinating-sutton.md for architecture, critical files, risks, and open questions. This task is phase 3 of 7 in the legal-ai UI rewrite from vanilla HTML to Next.js 15 + shadcn/ui.",
|
||||||
|
"testStrategy": "Users can browse case list, open a case detail, and view the compose screen with live data from FastAPI. All 3 screens visually match the existing legal-ai identity.",
|
||||||
|
"status": "pending",
|
||||||
|
"dependencies": [
|
||||||
|
"84"
|
||||||
|
],
|
||||||
|
"priority": "high",
|
||||||
|
"subtasks": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 86,
|
||||||
|
"title": "Phase 4 — Forms and wizards (new case, upload, inline edits)",
|
||||||
|
"description": "Port new case wizard, bulk upload, inline forms on case detail. Use react-hook-form + zod with schemas in lib/schemas/<entity>.ts. Build shared <WizardShell> from shadcn Card + Progress + Tabs. Build <DropZone> (react-dropzone + shadcn). Integrate SSE for upload progress via lib/sse.ts. Plan: ~/.claude/plans/joyful-marinating-sutton.md.",
|
||||||
|
"details": "See full plan at ~/.claude/plans/joyful-marinating-sutton.md for architecture, critical files, risks, and open questions. This task is phase 4 of 7 in the legal-ai UI rewrite from vanilla HTML to Next.js 15 + shadcn/ui.",
|
||||||
|
"testStrategy": "Users can create a new case via the multi-step wizard (case appears in Gitea + Paperclip), upload documents with live SSE progress, and edit case fields inline.",
|
||||||
|
"status": "pending",
|
||||||
|
"dependencies": [
|
||||||
|
"85"
|
||||||
|
],
|
||||||
|
"priority": "medium",
|
||||||
|
"subtasks": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 87,
|
||||||
|
"title": "Phase 5 — Secondary screens (compare, training, style report, skills, diagnostics)",
|
||||||
|
"description": "Port the remaining 5 views. Use TanStack Table for training corpus and diagnostics lists. Port any charts/visualizations from current index.html. Plan: ~/.claude/plans/joyful-marinating-sutton.md.",
|
||||||
|
"details": "See full plan at ~/.claude/plans/joyful-marinating-sutton.md for architecture, critical files, risks, and open questions. This task is phase 5 of 7 in the legal-ai UI rewrite from vanilla HTML to Next.js 15 + shadcn/ui.",
|
||||||
|
"testStrategy": "Feature parity with old legal-ai/web/static/index.html across all 10 views.",
|
||||||
|
"status": "pending",
|
||||||
|
"dependencies": [
|
||||||
|
"86"
|
||||||
|
],
|
||||||
|
"priority": "medium",
|
||||||
|
"subtasks": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 88,
|
||||||
|
"title": "Phase 6 — Polish & testing",
|
||||||
|
"description": "Accessibility pass (keyboard nav, aria-label on RTL icons, focus trap in modals). Error boundaries + toast notifications for failed mutations. Loading states for every query. Cross-browser smoke test (Chrome, Firefox, Safari) + mobile device test. Document E2E smoke test script in web-ui/README.md. Plan: ~/.claude/plans/joyful-marinating-sutton.md.",
|
||||||
|
"details": "See full plan at ~/.claude/plans/joyful-marinating-sutton.md for architecture, critical files, risks, and open questions. This task is phase 6 of 7 in the legal-ai UI rewrite from vanilla HTML to Next.js 15 + shadcn/ui.",
|
||||||
|
"testStrategy": "Lighthouse a11y score > 90, all loading states visible, errors show toasts, README has documented smoke test steps.",
|
||||||
|
"status": "pending",
|
||||||
|
"dependencies": [
|
||||||
|
"87"
|
||||||
|
],
|
||||||
|
"priority": "medium",
|
||||||
|
"subtasks": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 89,
|
||||||
|
"title": "Phase 7 — Deployment & cutover",
|
||||||
|
"description": "Add multi-stage Dockerfile for web-ui/ (Node 20 build -> nginx serve of out/). Add web-ui as new app in Coolify project pointing to staging subdomain legal-ai-next.nautilus.marcusgroup.org. Run full smoke test against staging. Cutover: DNS flip legal-ai.nautilus.marcusgroup.org to new app, keep old on rollback subdomain for 1 week. Follow-up PR removes legal-ai/web/static/index.html + design-system.css once stable. Plan: ~/.claude/plans/joyful-marinating-sutton.md.",
|
||||||
|
"details": "See full plan at ~/.claude/plans/joyful-marinating-sutton.md for architecture, critical files, risks, and open questions. This task is phase 7 of 7 in the legal-ai UI rewrite from vanilla HTML to Next.js 15 + shadcn/ui.",
|
||||||
|
"testStrategy": "legal-ai.nautilus.marcusgroup.org serves the new Next.js UI in production. Old UI accessible on rollback subdomain for 7 days. SSE streams working through Coolify proxy.",
|
||||||
|
"status": "pending",
|
||||||
|
"dependencies": [
|
||||||
|
"88"
|
||||||
|
],
|
||||||
|
"priority": "medium",
|
||||||
|
"subtasks": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"lastModified": "2026-04-04T07:50:59.999Z",
|
"lastModified": "2026-04-11T13:22:53.609Z",
|
||||||
"taskCount": 51,
|
"taskCount": 58,
|
||||||
"completedCount": 49,
|
"completedCount": 49,
|
||||||
"tags": [
|
"tags": [
|
||||||
"master"
|
"master"
|
||||||
]
|
],
|
||||||
|
"created": "2026-04-11T13:29:05.147Z",
|
||||||
|
"description": "Tasks for master context"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
53
Dockerfile
53
Dockerfile
@@ -1,27 +1,40 @@
|
|||||||
FROM python:3.12-slim
|
# ══════════════════════════════════════════════════════════════
|
||||||
|
# Dockerfile — Next.js 16 web-ui (ui-rewrite branch only)
|
||||||
|
#
|
||||||
|
# This file REPLACES the FastAPI Dockerfile on this branch so that
|
||||||
|
# Coolify's default /Dockerfile lookup builds the new Next.js staging
|
||||||
|
# UI. The FastAPI Dockerfile lives on `main` and is unaffected.
|
||||||
|
#
|
||||||
|
# When the rewrite is merged to main, decide between:
|
||||||
|
# (a) keeping both via separate Dockerfiles + dockerfile_location config, or
|
||||||
|
# (b) a multi-stage Dockerfile that serves both, or
|
||||||
|
# (c) fully replacing FastAPI's StaticFiles with this Next.js front end.
|
||||||
|
# ══════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
FROM node:20-alpine AS deps
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
COPY web-ui/package.json web-ui/package-lock.json ./
|
||||||
|
RUN npm ci --no-audit --no-fund
|
||||||
|
|
||||||
# System deps for PyMuPDF and document processing
|
FROM node:20-alpine AS builder
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
WORKDIR /app
|
||||||
gcc libmupdf-dev libfreetype6-dev libharfbuzz-dev libjpeg62-turbo-dev \
|
COPY --from=deps /app/node_modules ./node_modules
|
||||||
libopenjp2-7-dev curl git && rm -rf /var/lib/apt/lists/* && \
|
COPY web-ui/ ./
|
||||||
git config --global init.defaultBranch main
|
ENV NEXT_TELEMETRY_DISABLED=1
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
# Copy Ezer Mishpati MCP server source
|
FROM node:20-alpine AS runner
|
||||||
COPY mcp-server/pyproject.toml /app/mcp-server/pyproject.toml
|
WORKDIR /app
|
||||||
COPY mcp-server/src/ /app/mcp-server/src/
|
ENV NODE_ENV=production
|
||||||
|
ENV NEXT_TELEMETRY_DISABLED=1
|
||||||
|
ENV PORT=3000
|
||||||
|
ENV HOSTNAME=0.0.0.0
|
||||||
|
|
||||||
# Install MCP server + web deps
|
# next.config.ts uses output: 'standalone', so we copy only the minimal runtime
|
||||||
RUN pip install --no-cache-dir /app/mcp-server && \
|
COPY --from=builder /app/public ./public
|
||||||
pip install --no-cache-dir fastapi uvicorn python-multipart
|
COPY --from=builder /app/.next/standalone ./
|
||||||
|
COPY --from=builder /app/.next/static ./.next/static
|
||||||
|
|
||||||
# Copy web app
|
EXPOSE 3000
|
||||||
COPY web/ /app/web/
|
|
||||||
|
|
||||||
ENV PYTHONPATH=/app/mcp-server/src
|
CMD ["node", "server.js"]
|
||||||
ENV DOTENV_PATH=/dev/null
|
|
||||||
|
|
||||||
EXPOSE 8080
|
|
||||||
|
|
||||||
CMD ["uvicorn", "web.app:app", "--host", "0.0.0.0", "--port", "8080"]
|
|
||||||
|
|||||||
41
web-ui/.gitignore
vendored
Normal file
41
web-ui/.gitignore
vendored
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
/node_modules
|
||||||
|
/.pnp
|
||||||
|
.pnp.*
|
||||||
|
.yarn/*
|
||||||
|
!.yarn/patches
|
||||||
|
!.yarn/plugins
|
||||||
|
!.yarn/releases
|
||||||
|
!.yarn/versions
|
||||||
|
|
||||||
|
# testing
|
||||||
|
/coverage
|
||||||
|
|
||||||
|
# next.js
|
||||||
|
/.next/
|
||||||
|
/out/
|
||||||
|
|
||||||
|
# production
|
||||||
|
/build
|
||||||
|
|
||||||
|
# misc
|
||||||
|
.DS_Store
|
||||||
|
*.pem
|
||||||
|
|
||||||
|
# debug
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
.pnpm-debug.log*
|
||||||
|
|
||||||
|
# env files (can opt-in for committing if needed)
|
||||||
|
.env*
|
||||||
|
|
||||||
|
# vercel
|
||||||
|
.vercel
|
||||||
|
|
||||||
|
# typescript
|
||||||
|
*.tsbuildinfo
|
||||||
|
next-env.d.ts
|
||||||
5
web-ui/AGENTS.md
Normal file
5
web-ui/AGENTS.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<!-- BEGIN:nextjs-agent-rules -->
|
||||||
|
# This is NOT the Next.js you know
|
||||||
|
|
||||||
|
This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` before writing any code. Heed deprecation notices.
|
||||||
|
<!-- END:nextjs-agent-rules -->
|
||||||
1
web-ui/CLAUDE.md
Normal file
1
web-ui/CLAUDE.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
@AGENTS.md
|
||||||
36
web-ui/README.md
Normal file
36
web-ui/README.md
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
First, run the development server:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run dev
|
||||||
|
# or
|
||||||
|
yarn dev
|
||||||
|
# or
|
||||||
|
pnpm dev
|
||||||
|
# or
|
||||||
|
bun dev
|
||||||
|
```
|
||||||
|
|
||||||
|
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
||||||
|
|
||||||
|
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
|
||||||
|
|
||||||
|
This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
|
||||||
|
|
||||||
|
## Learn More
|
||||||
|
|
||||||
|
To learn more about Next.js, take a look at the following resources:
|
||||||
|
|
||||||
|
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
|
||||||
|
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
|
||||||
|
|
||||||
|
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
|
||||||
|
|
||||||
|
## Deploy on Vercel
|
||||||
|
|
||||||
|
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
|
||||||
|
|
||||||
|
Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
|
||||||
18
web-ui/eslint.config.mjs
Normal file
18
web-ui/eslint.config.mjs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { defineConfig, globalIgnores } from "eslint/config";
|
||||||
|
import nextVitals from "eslint-config-next/core-web-vitals";
|
||||||
|
import nextTs from "eslint-config-next/typescript";
|
||||||
|
|
||||||
|
const eslintConfig = defineConfig([
|
||||||
|
...nextVitals,
|
||||||
|
...nextTs,
|
||||||
|
// Override default ignores of eslint-config-next.
|
||||||
|
globalIgnores([
|
||||||
|
// Default ignores of eslint-config-next:
|
||||||
|
".next/**",
|
||||||
|
"out/**",
|
||||||
|
"build/**",
|
||||||
|
"next-env.d.ts",
|
||||||
|
]),
|
||||||
|
]);
|
||||||
|
|
||||||
|
export default eslintConfig;
|
||||||
33
web-ui/next.config.ts
Normal file
33
web-ui/next.config.ts
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import type { NextConfig } from "next";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Staging config — proxies /api/* and /openapi.json to the production FastAPI
|
||||||
|
* at legal-ai.nautilus.marcusgroup.org. This lets the new Next.js UI call the
|
||||||
|
* existing backend without CORS and without running a second FastAPI instance.
|
||||||
|
*
|
||||||
|
* When the rewrite branch is cut over to production, set NEXT_PUBLIC_API_BASE_URL
|
||||||
|
* and/or move the FastAPI in front of this app via traefik routing.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const API_ORIGIN =
|
||||||
|
process.env.NEXT_PUBLIC_API_ORIGIN ??
|
||||||
|
"https://legal-ai.nautilus.marcusgroup.org";
|
||||||
|
|
||||||
|
const nextConfig: NextConfig = {
|
||||||
|
output: "standalone",
|
||||||
|
|
||||||
|
async rewrites() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
source: "/api/:path*",
|
||||||
|
destination: `${API_ORIGIN}/api/:path*`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
source: "/openapi.json",
|
||||||
|
destination: `${API_ORIGIN}/openapi.json`,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default nextConfig;
|
||||||
6969
web-ui/package-lock.json
generated
Normal file
6969
web-ui/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
34
web-ui/package.json
Normal file
34
web-ui/package.json
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"name": "web-ui",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"dev": "next dev",
|
||||||
|
"build": "next build",
|
||||||
|
"start": "next start",
|
||||||
|
"lint": "eslint"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@hookform/resolvers": "^5.2.2",
|
||||||
|
"@tanstack/react-query": "^5.97.0",
|
||||||
|
"@tanstack/react-table": "^8.21.3",
|
||||||
|
"lucide-react": "^1.8.0",
|
||||||
|
"next": "16.2.3",
|
||||||
|
"react": "19.2.4",
|
||||||
|
"react-dom": "19.2.4",
|
||||||
|
"react-dropzone": "^15.0.0",
|
||||||
|
"react-hook-form": "^7.72.1",
|
||||||
|
"zod": "^4.3.6"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@tailwindcss/postcss": "^4",
|
||||||
|
"@types/node": "^20",
|
||||||
|
"@types/react": "^19",
|
||||||
|
"@types/react-dom": "^19",
|
||||||
|
"eslint": "^9",
|
||||||
|
"eslint-config-next": "16.2.3",
|
||||||
|
"openapi-typescript": "^7.13.0",
|
||||||
|
"tailwindcss": "^4",
|
||||||
|
"typescript": "^5"
|
||||||
|
}
|
||||||
|
}
|
||||||
7
web-ui/postcss.config.mjs
Normal file
7
web-ui/postcss.config.mjs
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
const config = {
|
||||||
|
plugins: {
|
||||||
|
"@tailwindcss/postcss": {},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default config;
|
||||||
1
web-ui/public/file.svg
Normal file
1
web-ui/public/file.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg fill="none" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 13.5V5.41a1 1 0 0 0-.3-.7L9.8.29A1 1 0 0 0 9.08 0H1.5v13.5A2.5 2.5 0 0 0 4 16h8a2.5 2.5 0 0 0 2.5-2.5m-1.5 0v-7H8v-5H3v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1M9.5 5V2.12L12.38 5zM5.13 5h-.62v1.25h2.12V5zm-.62 3h7.12v1.25H4.5zm.62 3h-.62v1.25h7.12V11z" clip-rule="evenodd" fill="#666" fill-rule="evenodd"/></svg>
|
||||||
|
After Width: | Height: | Size: 391 B |
1
web-ui/public/globe.svg
Normal file
1
web-ui/public/globe.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g clip-path="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.27 14.1a6.5 6.5 0 0 0 3.67-3.45q-1.24.21-2.7.34-.31 1.83-.97 3.1M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.48-1.52a7 7 0 0 1-.96 0H7.5a4 4 0 0 1-.84-1.32q-.38-.89-.63-2.08a40 40 0 0 0 3.92 0q-.25 1.2-.63 2.08a4 4 0 0 1-.84 1.31zm2.94-4.76q1.66-.15 2.95-.43a7 7 0 0 0 0-2.58q-1.3-.27-2.95-.43a18 18 0 0 1 0 3.44m-1.27-3.54a17 17 0 0 1 0 3.64 39 39 0 0 1-4.3 0 17 17 0 0 1 0-3.64 39 39 0 0 1 4.3 0m1.1-1.17q1.45.13 2.69.34a6.5 6.5 0 0 0-3.67-3.44q.65 1.26.98 3.1M8.48 1.5l.01.02q.41.37.84 1.31.38.89.63 2.08a40 40 0 0 0-3.92 0q.25-1.2.63-2.08a4 4 0 0 1 .85-1.32 7 7 0 0 1 .96 0m-2.75.4a6.5 6.5 0 0 0-3.67 3.44 29 29 0 0 1 2.7-.34q.31-1.83.97-3.1M4.58 6.28q-1.66.16-2.95.43a7 7 0 0 0 0 2.58q1.3.27 2.95.43a18 18 0 0 1 0-3.44m.17 4.71q-1.45-.12-2.69-.34a6.5 6.5 0 0 0 3.67 3.44q-.65-1.27-.98-3.1" fill="#666"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h16v16H0z"/></clipPath></defs></svg>
|
||||||
|
After Width: | Height: | Size: 1.0 KiB |
1
web-ui/public/next.svg
Normal file
1
web-ui/public/next.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>
|
||||||
|
After Width: | Height: | Size: 1.3 KiB |
1
web-ui/public/vercel.svg
Normal file
1
web-ui/public/vercel.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1155 1000"><path d="m577.3 0 577.4 1000H0z" fill="#fff"/></svg>
|
||||||
|
After Width: | Height: | Size: 128 B |
1
web-ui/public/window.svg
Normal file
1
web-ui/public/window.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 2.5h13v10a1 1 0 0 1-1 1h-11a1 1 0 0 1-1-1zM0 1h16v11.5a2.5 2.5 0 0 1-2.5 2.5h-11A2.5 2.5 0 0 1 0 12.5zm3.75 4.5a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5M7 4.75a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0m1.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5" fill="#666"/></svg>
|
||||||
|
After Width: | Height: | Size: 385 B |
BIN
web-ui/src/app/favicon.ico
Normal file
BIN
web-ui/src/app/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
178
web-ui/src/app/globals.css
Normal file
178
web-ui/src/app/globals.css
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
@import "tailwindcss";
|
||||||
|
|
||||||
|
/* ══════════════════════════════════════════════════════════════
|
||||||
|
* Ezer Mishpati — Design Tokens (ported from legal-ai/web/static/design-system.css)
|
||||||
|
* Editorial/judicial aesthetic for a Hebrew RTL judicial tool.
|
||||||
|
* Palette: Navy + Cream + Gold.
|
||||||
|
* Typography: Heebo (loaded via next/font/google in layout.tsx).
|
||||||
|
* ══════════════════════════════════════════════════════════════ */
|
||||||
|
|
||||||
|
@theme {
|
||||||
|
/* ── Colors ─────────────────────────────────────────── */
|
||||||
|
--color-navy: #0f172a;
|
||||||
|
--color-navy-soft: #1e293b;
|
||||||
|
--color-navy-dim: #334155;
|
||||||
|
|
||||||
|
--color-cream: #f5f1e8;
|
||||||
|
--color-cream-deep: #ede8d8;
|
||||||
|
--color-parchment: #fbf8f0;
|
||||||
|
|
||||||
|
--color-gold: #a97d3a;
|
||||||
|
--color-gold-deep: #8b6428;
|
||||||
|
--color-gold-soft: #c89a56;
|
||||||
|
--color-gold-wash: #fdf6e8;
|
||||||
|
|
||||||
|
--color-ink: #1a1a2e;
|
||||||
|
--color-ink-soft: #3a3a52;
|
||||||
|
--color-ink-muted: #6b7280;
|
||||||
|
--color-ink-light: #9ca3af;
|
||||||
|
|
||||||
|
--color-rule: #e5dfd0;
|
||||||
|
--color-rule-soft: #f0ead8;
|
||||||
|
|
||||||
|
--color-surface: #ffffff;
|
||||||
|
--color-surface-raised: #fbf8f0;
|
||||||
|
--color-bg: #f5f1e8;
|
||||||
|
|
||||||
|
/* Status colors — tuned to the palette */
|
||||||
|
--color-success: #4a7c59;
|
||||||
|
--color-success-bg: #e8efe7;
|
||||||
|
--color-warn: #b8894a;
|
||||||
|
--color-warn-bg: #faf0dc;
|
||||||
|
--color-danger: #a54242;
|
||||||
|
--color-danger-bg: #f5e6e6;
|
||||||
|
--color-info: #4e6a8c;
|
||||||
|
--color-info-bg: #e6ecf3;
|
||||||
|
|
||||||
|
/* ── Typography — Heebo (loaded via next/font in layout.tsx) ─ */
|
||||||
|
--font-display: var(--font-heebo), -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
||||||
|
--font-body: var(--font-heebo), -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
||||||
|
--font-mono: ui-monospace, "Cascadia Code", "SF Mono", Menlo, monospace;
|
||||||
|
|
||||||
|
/* ── Radii ──────────────────────────────────────────── */
|
||||||
|
--radius-sm: 4px;
|
||||||
|
--radius: 6px;
|
||||||
|
--radius-md: 8px;
|
||||||
|
--radius-lg: 12px;
|
||||||
|
--radius-xl: 16px;
|
||||||
|
|
||||||
|
/* ── Shadows — soft, editorial ──────────────────────── */
|
||||||
|
--shadow-xs: 0 1px 2px rgba(15, 23, 42, 0.05);
|
||||||
|
--shadow-sm: 0 1px 3px rgba(15, 23, 42, 0.06), 0 1px 2px rgba(15, 23, 42, 0.04);
|
||||||
|
--shadow: 0 2px 6px rgba(15, 23, 42, 0.06), 0 1px 2px rgba(15, 23, 42, 0.04);
|
||||||
|
--shadow-md: 0 4px 12px rgba(15, 23, 42, 0.08), 0 2px 4px rgba(15, 23, 42, 0.04);
|
||||||
|
--shadow-lg: 0 10px 30px rgba(15, 23, 42, 0.12), 0 2px 6px rgba(15, 23, 42, 0.05);
|
||||||
|
|
||||||
|
/* ── Transitions ────────────────────────────────────── */
|
||||||
|
--ease-out: cubic-bezier(0.16, 1, 0.3, 1);
|
||||||
|
--ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Dark theme (class-based, toggled on <html> or <body>) ── */
|
||||||
|
:root.dark,
|
||||||
|
body.dark {
|
||||||
|
--color-navy: #f5f1e8;
|
||||||
|
--color-navy-soft: #e8e0c8;
|
||||||
|
--color-navy-dim: #c7bc9a;
|
||||||
|
|
||||||
|
--color-cream: #0a0f1c;
|
||||||
|
--color-cream-deep: #121a2e;
|
||||||
|
--color-parchment: #161f36;
|
||||||
|
|
||||||
|
--color-gold: #d4a55a;
|
||||||
|
--color-gold-deep: #e8bc6f;
|
||||||
|
--color-gold-soft: #c89a56;
|
||||||
|
--color-gold-wash: rgba(212, 165, 90, 0.08);
|
||||||
|
|
||||||
|
--color-ink: #f5f1e8;
|
||||||
|
--color-ink-soft: #d8d2c0;
|
||||||
|
--color-ink-muted: #9a9380;
|
||||||
|
--color-ink-light: #6a6458;
|
||||||
|
|
||||||
|
--color-rule: #2a3352;
|
||||||
|
--color-rule-soft: #1e2a45;
|
||||||
|
|
||||||
|
--color-surface: #141b2f;
|
||||||
|
--color-surface-raised: #1a2238;
|
||||||
|
--color-bg: #0a0f1c;
|
||||||
|
|
||||||
|
--color-success: #5a9a6a;
|
||||||
|
--color-success-bg: rgba(90, 154, 106, 0.12);
|
||||||
|
--color-warn: #c79956;
|
||||||
|
--color-warn-bg: rgba(199, 153, 86, 0.12);
|
||||||
|
--color-danger: #c16565;
|
||||||
|
--color-danger-bg: rgba(193, 101, 101, 0.12);
|
||||||
|
--color-info: #6d8bab;
|
||||||
|
--color-info-bg: rgba(109, 139, 171, 0.12);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Base overrides ──────────────────────────────────── */
|
||||||
|
|
||||||
|
html {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: var(--font-body);
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 0.95rem;
|
||||||
|
line-height: 1.65;
|
||||||
|
color: var(--color-ink);
|
||||||
|
background: var(--color-bg);
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
font-feature-settings: "kern", "liga", "clig", "calt";
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Display typography — headings use the same Heebo family but bolder */
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6 {
|
||||||
|
font-family: var(--font-display);
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 1.25;
|
||||||
|
color: var(--color-navy);
|
||||||
|
letter-spacing: -0.01em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 { font-size: 2.3rem; font-weight: 900; }
|
||||||
|
h2 { font-size: 1.8rem; }
|
||||||
|
h3 { font-size: 1.45rem; }
|
||||||
|
h4 { font-size: 1.2rem; }
|
||||||
|
h5 { font-size: 1.05rem; }
|
||||||
|
h6 { font-size: 0.95rem; }
|
||||||
|
|
||||||
|
/* Prose paragraphs — justify both sides for Hebrew legal text */
|
||||||
|
p.prose,
|
||||||
|
.prose p {
|
||||||
|
text-align: justify;
|
||||||
|
text-justify: inter-word;
|
||||||
|
hyphens: auto;
|
||||||
|
line-height: 1.65;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Links */
|
||||||
|
a {
|
||||||
|
color: var(--color-gold-deep);
|
||||||
|
text-decoration: none;
|
||||||
|
transition: color 120ms var(--ease-out);
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
color: var(--color-gold);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Focus rings — gold, subtle */
|
||||||
|
*:focus-visible {
|
||||||
|
outline: 2px solid var(--color-gold);
|
||||||
|
outline-offset: 2px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Selection */
|
||||||
|
::selection {
|
||||||
|
background: var(--color-gold-wash);
|
||||||
|
color: var(--color-navy);
|
||||||
|
}
|
||||||
27
web-ui/src/app/layout.tsx
Normal file
27
web-ui/src/app/layout.tsx
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import type { Metadata } from "next";
|
||||||
|
import { Heebo } from "next/font/google";
|
||||||
|
import "./globals.css";
|
||||||
|
|
||||||
|
const heebo = Heebo({
|
||||||
|
variable: "--font-heebo",
|
||||||
|
subsets: ["hebrew", "latin"],
|
||||||
|
weight: ["300", "400", "500", "600", "700", "800", "900"],
|
||||||
|
display: "swap",
|
||||||
|
});
|
||||||
|
|
||||||
|
export const metadata: Metadata = {
|
||||||
|
title: "עוזר משפטי — ניהול תיקים",
|
||||||
|
description: "מערכת סיוע בניסוח החלטות לוועדת ערר לתכנון ובנייה",
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function RootLayout({
|
||||||
|
children,
|
||||||
|
}: Readonly<{
|
||||||
|
children: React.ReactNode;
|
||||||
|
}>) {
|
||||||
|
return (
|
||||||
|
<html lang="he" dir="rtl" className={`${heebo.variable} h-full antialiased`}>
|
||||||
|
<body className="min-h-full flex flex-col">{children}</body>
|
||||||
|
</html>
|
||||||
|
);
|
||||||
|
}
|
||||||
27
web-ui/src/app/page.tsx
Normal file
27
web-ui/src/app/page.tsx
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import { AppShell } from "@/components/app-shell";
|
||||||
|
|
||||||
|
export default function HomePage() {
|
||||||
|
return (
|
||||||
|
<AppShell>
|
||||||
|
<section className="space-y-6">
|
||||||
|
<header className="space-y-2">
|
||||||
|
<h1 className="text-navy">עוזר משפטי</h1>
|
||||||
|
<p className="text-ink-muted text-base max-w-2xl">
|
||||||
|
מערכת סיוע בניסוח החלטות לוועדת ערר לתכנון ובנייה — ניהול תיקים, חיפוש
|
||||||
|
סמנטי, וכלי כתיבה לפי ארכיטקטורת 12 הבלוקים.
|
||||||
|
</p>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<hr className="border-0 h-[2px] bg-gradient-to-l from-transparent via-gold to-transparent" />
|
||||||
|
|
||||||
|
<div className="rounded-lg bg-surface shadow-sm p-6 border border-rule">
|
||||||
|
<p className="text-ink">
|
||||||
|
שלב 1 של תוכנית השדרוג הושלם: scaffold של Next.js 16, פורט של design
|
||||||
|
tokens ל-Tailwind v4, RTL עברית עם Heebo. הפאזות הבאות יביאו את 10
|
||||||
|
המסכים ל-parity עם ה-UI הקיים.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</AppShell>
|
||||||
|
);
|
||||||
|
}
|
||||||
71
web-ui/src/components/app-shell.tsx
Normal file
71
web-ui/src/components/app-shell.tsx
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
import type { ReactNode } from "react";
|
||||||
|
import Link from "next/link";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ezer Mishpati navigation shell.
|
||||||
|
*
|
||||||
|
* Editorial/judicial aesthetic:
|
||||||
|
* - Navy header with a gold hairline rule (border-b-3)
|
||||||
|
* - Parchment/cream body background (set on <body> via globals.css)
|
||||||
|
* - Hebrew RTL throughout (set on <html> in layout.tsx)
|
||||||
|
*
|
||||||
|
* Structure mirrors the current vanilla index.html header so that visual
|
||||||
|
* continuity is preserved while we migrate screen-by-screen.
|
||||||
|
*/
|
||||||
|
|
||||||
|
type NavItem = {
|
||||||
|
href: string;
|
||||||
|
label: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const NAV_ITEMS: NavItem[] = [
|
||||||
|
{ href: "/", label: "בית" },
|
||||||
|
{ href: "/upload", label: "העלאת מסמכים" },
|
||||||
|
{ href: "/training", label: "אימון סגנון" },
|
||||||
|
{ href: "/skills", label: "מיומנויות" },
|
||||||
|
{ href: "/diagnostics", label: "אבחון" },
|
||||||
|
];
|
||||||
|
|
||||||
|
export function AppShell({ children }: { children: ReactNode }) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<header
|
||||||
|
className="
|
||||||
|
relative z-10 flex items-center gap-4
|
||||||
|
px-10 py-[18px]
|
||||||
|
bg-navy text-parchment
|
||||||
|
border-b-[3px] border-gold
|
||||||
|
shadow-md
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<Link href="/" className="flex items-baseline gap-3 hover:text-parchment">
|
||||||
|
<span className="font-display text-[1.45rem] font-bold tracking-[0.02em] text-parchment">
|
||||||
|
עוזר משפטי
|
||||||
|
</span>
|
||||||
|
<span className="text-gold-soft text-sm font-medium">ניהול תיקים</span>
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
<nav className="me-auto flex items-center gap-1">
|
||||||
|
{NAV_ITEMS.map((item) => (
|
||||||
|
<Link
|
||||||
|
key={item.href}
|
||||||
|
href={item.href}
|
||||||
|
className="
|
||||||
|
px-3 py-1.5 rounded
|
||||||
|
text-sm text-parchment/80
|
||||||
|
transition-colors
|
||||||
|
hover:text-parchment hover:bg-navy-soft/60
|
||||||
|
"
|
||||||
|
>
|
||||||
|
{item.label}
|
||||||
|
</Link>
|
||||||
|
))}
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<main className="flex-1 w-full max-w-[1400px] mx-auto px-10 py-10">
|
||||||
|
{children}
|
||||||
|
</main>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
34
web-ui/tsconfig.json
Normal file
34
web-ui/tsconfig.json
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES2017",
|
||||||
|
"lib": ["dom", "dom.iterable", "esnext"],
|
||||||
|
"allowJs": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"strict": true,
|
||||||
|
"noEmit": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"module": "esnext",
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"jsx": "react-jsx",
|
||||||
|
"incremental": true,
|
||||||
|
"plugins": [
|
||||||
|
{
|
||||||
|
"name": "next"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"@/*": ["./src/*"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"next-env.d.ts",
|
||||||
|
"**/*.ts",
|
||||||
|
"**/*.tsx",
|
||||||
|
".next/types/**/*.ts",
|
||||||
|
".next/dev/types/**/*.ts",
|
||||||
|
"**/*.mts"
|
||||||
|
],
|
||||||
|
"exclude": ["node_modules"]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user