Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
d4e48a5
feat(updates): define TypeScript contracts and interfaces for changel…
Amlaach Oct 30, 2026
04bf233
feat(updates): add bilingual changelog dataset for current and histor…
Amlaach Oct 30, 2026
6fbd82c
feat(updates): create UpdatesStateManager for tracking seen versions …
Amlaach Oct 30, 2026
f15fa38
feat(i18n): register comprehensive Hebrew and English localization ke…
Amlaach Oct 30, 2026
f632a13
feat(ui): implement CategoryPill and VersionBadge UI components for u…
Amlaach Oct 30, 2026
98cbb1b
feat(ui): implement ChangelogEntryCard component with foldable catego…
Amlaach Oct 30, 2026
c5cea8f
feat(ui): build UpdatesDrawer component for side-panel browsing of ch…
Amlaach Oct 30, 2026
084599e
feat(ui): add search input and category filter chips to UpdatesDrawer
Amlaach Oct 30, 2026
5461762
feat(ui): implement MajorUpdateModal dialog for highlighting major re…
Amlaach Oct 30, 2026
455dc15
feat(ui): add feature showcase cards and action buttons to MajorUpdat…
Amlaach Oct 30, 2026
e103a57
feat(ui): create UpdatesBellButton with unread notification badge ind…
Amlaach Oct 30, 2026
49a00fb
feat(system-bar): integrate updates bell button and menu trigger in T…
Amlaach Oct 30, 2026
ef5e1ed
feat(menu): add 'What\'s New' entry to Quick Menu and register Comman…
Amlaach Oct 30, 2026
3732d39
feat(about): integrate changelog button and release notes link in Abo…
Amlaach Oct 30, 2026
1b7bdb0
feat(settings): connect SettingsModal updates tab with What's New drawer
Amlaach Oct 30, 2026
850ff67
feat(lifecycle): wire startup check to prompt major updates and signa…
Amlaach Oct 30, 2026
3727009
style(updates): add dedicated CSS styling and animations for drawer a…
Amlaach Oct 30, 2026
b254e50
test(updates): add unit tests for changelog registry and updates stat…
Amlaach Oct 30, 2026
3e7163c
test(updates): add integration tests for UI components and i18n key c…
Amlaach Oct 30, 2026
aaac5e4
docs(updates): document What's New architecture, changelog maintenanc…
Amlaach Oct 30, 2026
53e1d5d
feat(updates): add CHANGELOG.md as single source of truth with automa…
Amlaach Oct 30, 2026
c4106b4
chore: sync and merge upstream changes with What's New system
Amlaach Oct 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# TypesetOK Changelog

מקור האמת המרכזי לכל עדכוני התוכנה ויומן השינויים של TypesetOK.
המידע בקובץ זה נשאב באופן אוטומטי לחלוניות "מה חדש" ולמודאל הכרזות הגרסה בממשק התוכנה.

---

## [0.30.4] - 2026-10-30
- **Importance**: minor
- **Badge**: עברית: גרסה נוכחית | en: Current Version
- **Title**: עברית: עדכון שיפורים, טיפוגרפיה ותאימות מקלדת | en: Enhancements, Hebrew Typography & Keyboard Usability
- **Summary**: עברית: עדכון זה מביא תמיכה מלאה במשקלי גופן (Regular/Bold) בסרגל המבנה ובקנבס, שיפור במקשי קיצור במקלדת עברית ותיקוני יציבות. | en: This update brings font weight support (Regular/Bold) across inspector and canvas, Hebrew keyboard shortcut compatibility, and stability fixes.

### Changes
- [typography] עברית: תמיכה מובנית במשקלי גופן (Bold 700 / Regular 400) בגופנים עבריים ושימורם בייצוא | en: Native font weight support (Bold 700 / Regular 400) for Hebrew fonts with faithful export retention
- [improvements] עברית: תאימות פלטת הפקודות (Ctrl+K) למקלדת עברית עם המקש "ל" ללא צורך בהחלפת שפה | en: Hebrew keyboard layout compatibility for Command Palette (Ctrl+K / Ctrl+ל)
- [fixes] עברית: מניעת השתלטות של מקש הסלאש ("/") בזמן הקלדה חופשית בעורך הטקסט | en: Prevented slash key ("/") from hijacking story editor typing
- [performance] עברית: ייעול מנגנון הרינדור של מסגרות הטקסט בקנבס בצפיפויות מסך גבוהות | en: Optimized canvas text frame rendering on high DPI displays

---

## [0.30.0] - 2026-10-15
- **Importance**: major
- **Badge**: עברית: עדכון גדול | en: Major Release
- **Title**: עברית: שחרור גרסה ראשית: מנוע עימוד רב-תזרימי ותקני דפוס מקצועיים | en: Major Release: Multi-Flow Layout Engine & Professional Pre-Press
- **Summary**: עברית: קפיצת מדרגה משמעותית לתוכנת TypesetOK עם מנוע Rust Native מהיר, יישור עברי תלת-שכבתי, ייצוא ISO PDF/X-1a ומגן שמות קדושים. | en: A massive milestone for TypesetOK featuring a Rust Native engine, 3-tier Hebrew justification, ISO PDF/X-1a pre-press export, and holy name protection.

### Highlights
- [rust-engine] icon: sparkle | badge: עברית: מהיר פי 10, en: 10x Faster
- Title: עברית: מנוע עימוד Rust מקורי | en: Native Rust Layout Engine
- Description: עברית: ליבת עימוד דטרמיניסטית וסופר-מהירה המבצעת שבירת שורות אופטימלית בשיטת Knuth-Plass על פני פסקאות עבריות שלמות. | en: Blazing fast deterministic layout engine running Knuth-Plass paragraph breaking across full Hebrew texts.
- [hebrew-justifier] icon: typography | badge: עברית: דיוק טיפוגרפי, en: Typographic Precision
- Title: עברית: יישור עברי מסורתי תלת-שכבתי | en: 3-Tier Traditional Hebrew Justifier
- Description: עברית: שילוב עדין של רווחי מילים גמישים, מתיחת אותיות רפויות (אהלתר"ם) וריווח בין-אותי מיקרומטרי ללא צורך במקפים מכוערים. | en: Harmonious blending of word spacing, wide Hebrew letter dilation, and micro letter-spacing.
- [pdf-x-export] icon: export | badge: עברית: תקן דפוס, en: Print Standard
- Title: עברית: ייצוא תקני ISO PDF/X-1a ו-PDF/X-4 | en: ISO PDF/X-1a & PDF/X-4 Pre-Press
- Description: עברית: הפקת קבצים מוכנים ישירות להדפסת אופסט ודפוס דיגיטלי מסחרי, עם הפרדת צבעים מלאה של 100% K לטקסט חד ונקי. | en: Production-ready PDF export for offset & digital printing, strict 100% pure black channel separation.
- [sacred-text-shield] icon: check | badge: עברית: מסורת ישראל, en: Traditional Rules
- Title: עברית: קדושת הטקסט ונרמול קנוני | en: Sacred Text Shield & Canonical Normalization
- Description: עברית: מניעת שבירת שמות קדושים בכללי No-Break קפדניים, סנכרון גימטריה עברית לעמודים ונרמול סדר ניקוד וטעמים. | en: Strict no-break protection for divine names, Hebrew gematria page numbering, and canonical niqqud normalization.

### Changes
- [features] עברית: מבנה עמוד רב-תזרימי מלא עבור דפי גמרא (מרכז, רש"י, תוספות, הערות) ומקראות גדולות | en: Full multi-flow page architecture for Talmud pages and rabbinic commentaries
- [features] עברית: ייצוא PDF/X-1a תקני עם פרופילי צבע Fogra 39 ו-ISO Coated v2 | en: Compliant ISO PDF/X-1a export with Fogra 39 and ISO Coated v2 profiles
- [typography] עברית: אלגוריתם מתיחת אותיות עבריות רפויות וריווח מילים גמיש | en: Hebrew dilated letter expansion and elastic word space distribution
- [improvements] עברית: ניהול פרויקטים ומסך פתיחה חדש עם תבניות מהירות לספרים, עלונים וקונטרסים | en: Project manager and fresh welcome dashboard with quick templates for books and booklets
- [fixes] עברית: תיקון חישוב גבולות עמודים בצמדי עמודים (Spreads) בספרים מימין לשמאל | en: Fixed page spread layout calculation for right-to-left Hebrew books

---

## [0.29.0] - 2026-09-20
- **Importance**: minor
- **Badge**: עברית: תוספים ועריכה | en: Plugins & Editing
- **Title**: עברית: מערכת תוספים מודולרית ועורך טקסט משולב | en: Modular Plugin System & Integrated Story Editor
- **Summary**: עברית: הוספת סביבת הרחבות מבודדת ומאובטחת לתוספים ב-TypeScript/JavaScript, לצד עורך טקסט רציף (Story Editor) עם חיפוש והחלפה. | en: Introduced an isolated plugin architecture for TypeScript/JavaScript extensions alongside a split Story Editor.

### Changes
- [features] עברית: מנוע פלאגינים מאובטח (PluginEngine) עם הרשאות מוגדרות והידור בזמן ריצה | en: Hardened plugin sandbox engine with strict permission boundaries and runtime compilation
- [features] עברית: עורך טקסט משולב בתצוגת Split View עם ספירת מילים חיה לכל תזרים | en: Integrated Story Editor with split view and live word counts per flow
- [improvements] עברית: ייבוא ישיר של קובצי Word (.docx), Markdown (.md) וטקסט רציף | en: Direct import pipeline for Word (.docx), Markdown (.md), and plain text
- [fixes] עברית: שיפור מנגנון שמירה אוטומטית ומניעת איבוד שינויים בעת יציאה | en: Enhanced auto-save safety checks and unsaved change prevention on quit
1 change: 1 addition & 0 deletions PROJECT.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ TypesetOK הינה תוכנת DTP (עימוד וסדר דפוס) שולחנית
| 19| License & Dependency Notice Audit | Complete license audit, dependency notices, and copyright headers | M5 | Survey / R5 |
| 20| E2E Testing Suite (Tiers 1-4) | Comprehensive opaque-box test suite across 4 tiers derived from requirements | E2E-Track | Dual Track |
| 21| 100% E2E Pass & Adversarial Hardening | Pass 100% E2E test suite + Tier 5 adversarial testing & verification | M6 (Final) | Dual Track |
| 22| Bilingual What's New System | Side drawer for minor updates, popup dialog for major updates, unread bell indicator, and full Hebrew/English changelog | M6 | Feature Track |

---

Expand Down
106 changes: 106 additions & 0 deletions docs/WHATS_NEW_SYSTEM.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# מערכת "מה חדש" ויומן עדכונים (What's New & Changelog System)

מערכת מודרנית, דו-לשונית (עברית ואנגלית) לניהול וחשיפת חידושים ועדכונים למשתמשי TypesetOK.

---

## 🎯 עקרונות חוויית המשתמש (UX Principles)

1. **עדכונים גדולים (Major Releases):**
- קופץ חלון פופ-אפ ייעודי (`MajorUpdateModal`) באופן אוטומטי בעליית התוכנה בפעם הראשונה לאחר העדכון.
- החלון מעוצב כ-Hero Showcase חגיגי, עם כרטיסיות גריד המדגישות את גולת הכותרת של התכונות החדשות.
- כולל תיבת סימון "אל תציג חלון זה שוב עבור גרסה זו", כפתור "לכל העדכונים והשינויים" (שפותח ישירות את החלונית המלאה), וכפתור סגירה ("הבנתי, תודה!").

2. **עדכונים קטנים (Minor & Patch Releases):**
- **אינם מטרידים את המשתמש בפופ-אפ חודרני!**
- מוצגים בחלונית צד ייעודית (`UpdatesDrawer`) הנפתחת בצורה אלגנטית ומאפשרת שיטוט נוח, סינון וחיפוש.
- בסרגל המערכת העליון (`TopSystemBar`) מופיע כפתור פעמון/sparkle עם נקודת התראה כתומה פועמת (`tok-updates-unread-dot`) כשיש עדכון חדש שטרם נקרא. פתיחת החלונית מסמנת את העדכון כנצפה ומעלימה את האינדיקטור.

3. **דו-לשוניות מלאה (Full Bilingual RTL/LTR Support):**
- כל הממשק, הכרטיסיות, התגיות, הסינונים והטקסטים מוגדרים במלואם הן בעברית והן באנגלית.
- מעבר שפה באפליקציה (עברית ↔ אנגלית) מעדכן באופן מיידי את החלונית והפופ-אפ ואת כיווניות הגלישה והאנימציות (RTL מימין, LTR משמאל).

---

## 🏛️ מבנה הקוד והארכיטקטורה

המערכת בנויה ממודולים מופרדים ונקיים תחת `packages/tok-ui/src/`:

```
packages/tok-ui/src/
├── updates/
│ ├── types.ts # טיפוסי נתונים, סכמות ChangelogEntry, UpdateImportance, ChangeCategory
│ ├── changelogData.ts # מאגר נתוני הגרסאות ההיסטוריות והנוכחיות בעברית ובאנגלית
│ ├── updatesManager.ts # שירות סטייט מרכזי: semver comparison, localStorage, unread tracking
│ ├── updatePills.ts # רכיבי UI קטנים: תגיות קטגוריה ובאדג'י גרסה
│ ├── ChangelogEntryCard.ts # כרטיס גרסה מפורט עבור רשימת העדכונים
│ └── UpdatesBellButton.ts # כפתור פעמון סרגל עליון עם אינדיקטור unread חי
├── components/
│ ├── UpdatesDrawer.ts # חלונית צד (Side Drawer) לעיון מלא, סינון צ'יפים וחיפוש
│ └── MajorUpdateModal.ts # פופ-אפ מודאלי להכרזה על שחרור גרסה ראשית
```

---

## 🚀 מחזור חיים בעליית התוכנה (Startup Lifecycle)

בעת פתיחת התוכנה (`TypesetOkApp.init`):
1. נקראת גרסת התוכנה הנוכחית (`getAppVersion`).
2. `UpdatesStateManager` משווה את הגרסה הנוכחית מול `lastSeenMajorVersion` ו-`lastSeenVersion` השמורים ב-`localStorage`:
- **אם הגרסה היא `major`** וטרם הוצגה ולא נדחתה: נקראת `openMajorUpdate(version)` ומוצג הפופ-אפ.
- **אם הגרסה היא `minor` / `patch`**: הפופ-אפ **לא** קופץ; כפתור הפעמון בסרגל העליון מדליק אינדיקטור עדכון ומזמין את המשתמש לעיין בחלונית בשעות הפנאי.

---

## 📝 כיצד להוסיף גרסה חדשה (Adding a New Release)

כדי לתעד גרסה חדשה, עורכים את `packages/tok-ui/src/updates/changelogData.ts` ומוסיפים רשומה בראש המערך `CHANGELOG_ENTRIES`:

```typescript
{
version: '0.31.0',
releaseDate: '2026-11-15',
importance: 'major', // או 'minor' / 'patch'
title: {
he: 'כותרת העדכון בעברית',
en: 'Update Title in English'
},
summary: {
he: 'תקציר השינויים בעברית...',
en: 'English summary of the changes...'
},
badge: {
he: 'עדכון גדול',
en: 'Major Release'
},
// שדה highlights חובה בגרסאות major:
highlights: [
{
id: 'feature-id',
title: { he: 'שם היכולת', en: 'Feature Name' },
description: { he: 'תיאור מפורט', en: 'Detailed description' },
icon: 'sparkle', // שם אייקון מתוך IconName
badge: { he: 'חדש', en: 'New' }
}
],
changes: [
{
category: 'features', // 'features' | 'improvements' | 'fixes' | 'typography' | 'performance'
text: { he: 'פירוט השינוי בעברית', en: 'English change description' },
tag: { he: 'תכונה חדשה', en: 'New Feature' }
}
]
}
```

---

## 🔍 פקודות בדיקה (Automated Tests)

המערכת מגובה ב-13 בדיקות יחידה ואינטגרציה ב-`test/whats_new_system.test.mjs`, הפועלות כחלק מסוויטת הבדיקות הרשמית של הפרויקט (`npm test`):
- שלמות מאגר הגרסאות ושדות חובה דו-לשוניים.
- דטרמיניסטיות השוואת Semver.
- לוגיקת החלטה בין פופ-אפ (Major) לחלונית (Minor).
- תקינות סינונים וחיפוש.
- כיסוי מפתחות i18n בעברית ובאנגלית.
- אינטגרציית רכיבי ה-UI (סרגל עליון, תפריטים, Command Palette).
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@
],
"scripts": {
"build:ts": "tsc --build",
"sync:changelog": "node scripts/sync-changelog.mjs",
"bundle:ui": "node scripts/bundle-ui.mjs",
"lint": "tsc --build",
"build": "npm run build:ts && npm run bundle:ui",
"package:desktop": "node scripts/build-desktop-bundle.mjs",
"package:installer": "node scripts/build-installer.mjs",
"test": "node --test test/frontend.test.mjs test/milestone_features.test.mjs test/story_editor.test.mjs test/outcome_validation.test.mjs test/importer.test.mjs test/lifecycle_flow.test.mjs test/geometric_fidelity.test.mjs test/phase3_integration.test.mjs test/issue20_regression.test.mjs",
"test": "node --test test/frontend.test.mjs test/milestone_features.test.mjs test/story_editor.test.mjs test/outcome_validation.test.mjs test/importer.test.mjs test/lifecycle_flow.test.mjs test/geometric_fidelity.test.mjs test/phase3_integration.test.mjs test/issue20_regression.test.mjs test/whats_new_system.test.mjs",
"start": "electron packages/tok-electron/dist/main.js",
"perf:startup": "node scripts/measure-startup.mjs"
},
Expand Down
67 changes: 66 additions & 1 deletion packages/tok-ui/src/app.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { getAppVersion } from './appInfo';
import { TopSystemBar } from './components/TopSystemBar';
import { StructureBar } from './components/StructureBar';
import { ContextualInspector } from './components/ContextualInspector';
Expand All @@ -9,6 +10,9 @@ import { ExportDialog, ExportOptions } from './components/ExportDialog';
import { WelcomeModal, addRecentProject, updateProjectClosedTime } from './components/WelcomeModal';
import { SettingsModal } from './components/SettingsModal';
import { AboutModal } from './components/AboutModal';
import { UpdatesDrawer } from './components/UpdatesDrawer';
import { MajorUpdateModal } from './components/MajorUpdateModal';
import { UpdatesStateManager } from './updates/updatesManager';
import { UserGuideModal } from './components/UserGuideModal';
import { TextStatsModal } from './components/TextStatsModal';
import { ImportTemplateModal } from './components/ImportTemplateModal';
Expand Down Expand Up @@ -136,6 +140,8 @@ export class TypesetOkApp {
private welcomeModalInstance?: WelcomeModal;
private settingsModalInstance?: SettingsModal;
private aboutModalInstance?: AboutModal;
private updatesDrawerInstance?: UpdatesDrawer;
private majorUpdateModalInstance?: MajorUpdateModal;
private exportDialogInstance?: ExportDialog;
private userGuideModalInstance?: UserGuideModal;
private textStatsModalInstance?: TextStatsModal;
Expand Down Expand Up @@ -266,6 +272,7 @@ export class TypesetOkApp {
onOpenProjects: () => this.welcomeModal.show(),
onOpenSettings: () => this.settingsModal.show(),
onOpenAbout: () => this.aboutModal.show(),
onOpenWhatsNew: () => this.openWhatsNew(),
onUndo: () => this.runEditCommand('undo'),
onRedo: () => this.runEditCommand('redo'),
onRenameDocument: (newTitle) => this.renameDocument(newTitle)
Expand Down Expand Up @@ -533,6 +540,11 @@ export class TypesetOkApp {
this.pluginEngine.loadPlugins().catch(console.error);
});

// 8b. Check for major updates popup on startup
runWhenIdle(() => {
this.checkStartupUpdatesPrompt();
});

// 8. Initialize default multi-flow document state
this.activeFlowId = 'gemara';
this.storyEditor.loadStory(this.documentState.flows.gemara);
Expand Down Expand Up @@ -874,6 +886,7 @@ export class TypesetOkApp {
if (guide === 'baseline' && current.baseline !== visible) this.canvas.toggleBaselineGuide();
},
getZoom: () => this.canvas.getZoom(),
onOpenWhatsNew: () => this.openWhatsNew(),
setZoom: (z) => {
this.canvas.setZoom(z);
this.statusBar.updateStats({ zoom: z });
Expand All @@ -890,7 +903,8 @@ export class TypesetOkApp {
onClose: () => {
if (!this.hasOpenDocument) this.welcomeModal.show();
},
onCheckUpdates: () => this.settingsModal.show('updates')
onCheckUpdates: () => this.settingsModal.show('updates'),
onOpenWhatsNew: () => this.openWhatsNew()
});
this.root.appendChild(this.aboutModalInstance.element);
}
Expand Down Expand Up @@ -1644,10 +1658,61 @@ export class TypesetOkApp {
public openAbout(): void {
this.aboutModal.show();
}
public get updatesDrawer(): UpdatesDrawer {
if (!this.updatesDrawerInstance) {
this.updatesDrawerInstance = new UpdatesDrawer({
onClose: () => {},
onCheckUpdates: () => this.settingsModal.show('updates'),
onOpenSettings: () => this.settingsModal.show('updates')
});
this.root.appendChild(this.updatesDrawerInstance.element);
}
return this.updatesDrawerInstance;
}

public get majorUpdateModal(): MajorUpdateModal {
if (!this.majorUpdateModalInstance) {
this.majorUpdateModalInstance = new MajorUpdateModal({
onClose: () => {},
onExploreAll: () => this.updatesDrawer.show()
});
this.root.appendChild(this.majorUpdateModalInstance.element);
}
return this.majorUpdateModalInstance;
}

public openWhatsNew(version?: string): void {
this.updatesDrawer.show(version);
}

public openMajorUpdate(version?: string): void {
this.majorUpdateModal.show(version);
}

private checkStartupUpdatesPrompt(): void {
const updatesManager = UpdatesStateManager.getInstance();
getAppVersion().then((ver: string) => {
const version = ver || updatesManager.getLatestEntry()?.version;
if (version && updatesManager.shouldPromptMajorUpdate(version)) {
this.openMajorUpdate(version);
}
}).catch((e: any) => {
console.warn('[UPDATES] Startup check error:', e);
});
}


/** Built-in palette commands in the current UI language (page & layout modifying only). */
private buildCommands(): PaletteItem[] {
return [
{
id: 'cmd-whats-new',
icon: 'sparkle',
category: t('sidebarAbout'),
title: t('commandPaletteWhatsNew'),
subtitle: t('whatsNewSubtitle'),
action: () => this.handleSystemAction('open-whats-new')
},
{
id: 'cmd-full-justify',
icon: 'alignJustify',
Expand Down
Loading
Loading