Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
eb5ad7b
feat(storage): wire encryption migration journal into production disa…
qnbs Aug 12, 2026
24a684e
feat(settings): wire disable/rotate UI and startup recovery for at-re…
qnbs Aug 12, 2026
0ddcb44
test(storage,settings): cover the disable/rotate migration and recove…
qnbs Aug 12, 2026
302de39
docs: mark Phase 4 (#338) encryption disable/rotate/recovery as shipped
qnbs Aug 12, 2026
12db949
i18n: add settings.privacy.* keys for the encryption disable/rotate/r…
qnbs Aug 12, 2026
1e67f4f
docs: update i18n key-count badge/table/prose to 2913 (was 2904)
qnbs Aug 12, 2026
097c455
chore(security): gitleaks allowlist for PASSPHRASE_SENTINEL_RECORD_KE…
qnbs Aug 12, 2026
423c115
fix(storage): 3 critical encryption-migration bugs found in PR review
qnbs Aug 12, 2026
8a84048
fix(encryption): address remaining PR #342 review findings
qnbs Aug 12, 2026
73f6754
fix(ci): resolve OSV and GitGuardian findings on PR #342's branch
qnbs Aug 12, 2026
4a89f2b
fix(i18n): translate the disable-encryption warning across all locales
qnbs Aug 12, 2026
b692c45
docs: document the extract-zip OSV ignore accepted-risk in AUDIT.md
qnbs Aug 12, 2026
8cd4989
merge: sync with feat/encryption-migration-phase4-b's correction-loop…
qnbs Aug 13, 2026
4b43e9e
fix: address 9 remaining CodeRabbit findings on PR #342
qnbs Aug 13, 2026
73263e9
merge: sync with feat/encryption-migration-phase4-b's remaining CodeR…
qnbs Aug 13, 2026
c5d700b
docs: sync README i18n key-count badges to 2914 (was stale at 2904)
qnbs Aug 13, 2026
22a0f4c
merge: sync with feat/encryption-migration-phase4-b's README metrics fix
qnbs Aug 13, 2026
aba4117
merge: reconcile with squash-merged main (PR #342 landed)
qnbs Aug 13, 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
18 changes: 9 additions & 9 deletions locales/ar/characters.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@
"characters.edit.relationships": "العلاقات",
"characters.editorTabsAriaLabel": "علامات تبويب محرّر الشخصية",
"characters.error.portraitFailed": "فشل توليد الصورة. حاول إضافة المزيد من التفاصيل إلى وصف المظهر.",
"characters.heuristic.appearance": "Describe how they present themselves — let their look hint at {{concept}}.",
"characters.heuristic.backstory": "Shaped by formative experiences, this character carries a past tied to {{concept}}.",
"characters.heuristic.characterArc": "They begin guarded and, through the story, are changed by {{concept}}.",
"characters.heuristic.flaws": "A weakness that complicates their goals.",
"characters.heuristic.motivation": "A core desire connected to {{concept}} drives their choices.",
"characters.heuristic.name": "New Character",
"characters.heuristic.personalityTraits": "Resourceful, guarded, determined.",
"characters.heuristic.relationships": "Note the key bonds and rivalries that define them.",
"characters.loading.profile": "جارٍ توليد ملف تعريف مفصّل...",
"characters.newCharacterName": "شخصية جديدة",
"characters.noCharacters": "لم تُنشأ شخصيات بعد.",
Expand All @@ -69,13 +77,5 @@
"characters.tabs.relationships": "العلاقات",
"characters.title": "ملفات الشخصيات",
"characters.uploadImage": "رفع صورة",
"characters.yourCharacters": "شخصياتك",
"characters.heuristic.name": "New Character",
"characters.heuristic.backstory": "Shaped by formative experiences, this character carries a past tied to {{concept}}.",
"characters.heuristic.motivation": "A core desire connected to {{concept}} drives their choices.",
"characters.heuristic.appearance": "Describe how they present themselves — let their look hint at {{concept}}.",
"characters.heuristic.personalityTraits": "Resourceful, guarded, determined.",
"characters.heuristic.flaws": "A weakness that complicates their goals.",
"characters.heuristic.characterArc": "They begin guarded and, through the story, are changed by {{concept}}.",
"characters.heuristic.relationships": "Note the key bonds and rivalries that define them."
"characters.yourCharacters": "شخصياتك"
}
46 changes: 23 additions & 23 deletions locales/ar/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@
"apiKey.test": "اختبار الاتصال",
"apiKey.testConnection": "اختبار اتصال API",
"apiKey.testing": "جارٍ الاختبار…",
"assisted.badge.label": "Assisted",
"assisted.badge.srLabel": "Assisted mode — generated without AI",
"assisted.enhance": "Enhance with AI",
"assisted.toast.description": "Used built-in assistance. Enhance with AI when a model is available.",
"assisted.toast.title": "AI unavailable",
"charGraph.characters": "الشخصيات",
"charGraph.noCharacters": "لا توجد شخصيات بعد",
"charGraph.noCharactersHint": "أضف شخصيات في عرض الشخصيات لتصوّر علاقاتها هنا.",
Expand Down Expand Up @@ -170,6 +175,8 @@
"error.db.unknown": "خطأ غير معروف أثناء الوصول إلى قاعدة البيانات.",
"error.deepLink.title": "Failed to open project file",
"error.deepLink.unknown": "Unknown error",
"error.fallback.generic": "AI is unavailable — used built-in assistance.",
"error.fallback.offline": "You're offline — used built-in assistance.",
"error.fileImportError": "خطأ في استيراد الملف",
"error.mic.denied": "تم رفض الوصول إلى الميكروفون. يرجى منح الإذن في إعدادات متصفّحك.",
"error.mic.generic": "خطأ في التعرّف على الكلام: {{error}}",
Expand Down Expand Up @@ -266,6 +273,16 @@
"palette.voice.listeningLive": "الإدخال الصوتي نشط",
"palette.voice.start": "بدء البحث الصوتي",
"palette.voice.stop": "إيقاف البحث الصوتي",
"plotBoard.heuristic.complicate.description": "Add an obstacle or reveal that forces a change of plan.",
"plotBoard.heuristic.complicate.rationale": "A fresh complication tests the characters and opens new threads.",
"plotBoard.heuristic.complicate.title": "Introduce a complication",
"plotBoard.heuristic.escalate.description": "Increase the pressure on your protagonist so the next choice costs more.",
"plotBoard.heuristic.escalate.rationale": "Escalation keeps momentum when the middle sags.",
"plotBoard.heuristic.escalate.title": "Raise the stakes",
"plotBoard.heuristic.position": "Right after the selected scene",
"plotBoard.heuristic.reverse.description": "Flip an expectation — an ally falters, a win turns sour, or a hidden truth surfaces.",
"plotBoard.heuristic.reverse.rationale": "Reversals refresh tension and deepen the arc.",
"plotBoard.heuristic.reverse.title": "Add a reversal",
"preview.controls.ariaLabel": "ضوابط المعاينة",
"preview.controls.decreaseFontSize": "تصغير حجم الخط",
"preview.controls.exitFullscreen": "الخروج من ملء الشاشة",
Expand Down Expand Up @@ -333,10 +350,6 @@
"proforge.progress.awaitingReviewHint": "⚠️ This stage is awaiting your review. Click the stage button above to review items.",
"proforge.progress.completedStages": "Completed Stages",
"proforge.progress.currentStatus": "Current Status",
"proforge.progress.overall": "Overall progress",
"proforge.progress.preparing": "Preparing…",
"proforge.progress.stageOfTotal": "Stage {{current}} of {{total}}",
"proforge.progress.percentComplete": "{{percent}}% complete",
"proforge.progress.itemsCount": "{{count}} items",
"proforge.progress.metric.aiCalls": "AI Calls",
"proforge.progress.metric.duration": "Duration",
Expand All @@ -347,7 +360,11 @@
"proforge.progress.metric.totalTime": "Total Time",
"proforge.progress.metric.totalTokens": "Total Tokens",
"proforge.progress.noneRunning": "No pipeline running.",
"proforge.progress.overall": "Overall progress",
"proforge.progress.percentComplete": "{{percent}}% complete",
"proforge.progress.preparing": "Preparing…",
"proforge.progress.stageDetails": "Stage Details: {{stage}}",
"proforge.progress.stageOfTotal": "Stage {{current}} of {{total}}",
"proforge.progress.statusLabel": "Status",
"proforge.progress.totals": "Pipeline Totals",
"proforge.review.accept": "Accept",
Expand Down Expand Up @@ -661,9 +678,9 @@
"vc.title": "سجلّ الإصدارات",
"vc.words": "كلمات",
"voice.cancelSpeech": "إلغاء النطق",
"voice.feedback.confidence": "الثقة {{percent}}%",
"voice.modeChip.commands": "أوامر",
"voice.modeChip.dictation": "إملاء",
"voice.feedback.confidence": "الثقة {{percent}}%",
"voice.panelLabel": "التحكم الصوتي",
"voice.permissionDenied": "تم رفض الوصول إلى الميكروفون. يرجى السماح بالوصول إلى الميكروفون في إعدادات متصفّحك لاستخدام الميزات الصوتية.",
"voice.startDictation": "بدء الإملاء",
Expand All @@ -676,22 +693,5 @@
"voice.stopDictation": "إيقاف الإملاء",
"voice.stopListening": "إيقاف الاستماع",
"worlds.emptyState.description": "ابنِ الأماكن والقواعد والتواريخ التي تعيش فيها قصتك. ابدأ بموقع.",
"worlds.emptyState.title": "العالم بانتظارك",
"error.fallback.generic": "AI is unavailable — used built-in assistance.",
"error.fallback.offline": "You're offline — used built-in assistance.",
"assisted.badge.label": "Assisted",
"assisted.badge.srLabel": "Assisted mode — generated without AI",
"assisted.toast.title": "AI unavailable",
"assisted.toast.description": "Used built-in assistance. Enhance with AI when a model is available.",
"assisted.enhance": "Enhance with AI",
"plotBoard.heuristic.position": "Right after the selected scene",
"plotBoard.heuristic.escalate.title": "Raise the stakes",
"plotBoard.heuristic.escalate.description": "Increase the pressure on your protagonist so the next choice costs more.",
"plotBoard.heuristic.escalate.rationale": "Escalation keeps momentum when the middle sags.",
"plotBoard.heuristic.complicate.title": "Introduce a complication",
"plotBoard.heuristic.complicate.description": "Add an obstacle or reveal that forces a change of plan.",
"plotBoard.heuristic.complicate.rationale": "A fresh complication tests the characters and opens new threads.",
"plotBoard.heuristic.reverse.title": "Add a reversal",
"plotBoard.heuristic.reverse.description": "Flip an expectation — an ally falters, a win turns sour, or a hidden truth surfaces.",
"plotBoard.heuristic.reverse.rationale": "Reversals refresh tension and deepen the arc."
"worlds.emptyState.title": "العالم بانتظارك"
}
36 changes: 18 additions & 18 deletions locales/ar/outline.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,23 @@
"outline.deleteConfirm": "هل أنت متأكد من حذف قسم المخطط هذا؟",
"outline.description": "صِف فكرة قصتك ودع الذكاء الاصطناعي ينشئ لك مخططًا منظّمًا قابلًا للتحرير.",
"outline.error.generationFailed": "فشل توليد المحتوى. يرجى المحاولة مرة أخرى.",
"outline.heuristic.beat.climax.desc": "The central conflict comes to a head in the story's defining confrontation.",
"outline.heuristic.beat.climax.title": "Climax",
"outline.heuristic.beat.complications.desc": "Setbacks and conflicts deepen; the path forward narrows.",
"outline.heuristic.beat.complications.title": "Complications",
"outline.heuristic.beat.incitingIncident.desc": "The event that sets the story in motion: {{idea}}.",
"outline.heuristic.beat.incitingIncident.title": "Inciting Incident",
"outline.heuristic.beat.midpoint.desc": "A turning point shifts the direction of the story and raises the stakes.",
"outline.heuristic.beat.midpoint.title": "Midpoint",
"outline.heuristic.beat.resolution.desc": "Loose ends are tied up and a new status quo emerges.",
"outline.heuristic.beat.resolution.title": "Resolution",
"outline.heuristic.beat.risingAction.desc": "Complications escalate and the stakes grow as the characters pursue their goal.",
"outline.heuristic.beat.risingAction.title": "Rising Action",
"outline.heuristic.beat.setup.desc": "Introduce the world and the main characters, and establish the status quo before everything changes.",
"outline.heuristic.beat.setup.title": "Setup",
"outline.heuristic.beat.twist.desc": "An unexpected revelation upends what the characters believed to be true.",
"outline.heuristic.beat.twist.title": "Twist",
"outline.heuristic.fallbackIdea": "the central idea",
"outline.idea.generateButton": "توليد المخطط",
"outline.idea.genreLabel": "النوع الأدبي",
"outline.idea.genrePlaceholder": "مثل: خيال علمي، فانتازيا، غموض",
Expand All @@ -42,22 +59,5 @@
"outline.result.title": "مخطط تفاعلي",
"outline.result.twistTooltip": "منعطف حبكة مُولَّد بالذكاء الاصطناعي",
"outline.selectSection": "Select section '{{title}}'",
"outline.title": "مُولِّد مخطط القصة بالذكاء الاصطناعي",
"outline.heuristic.fallbackIdea": "the central idea",
"outline.heuristic.beat.setup.title": "Setup",
"outline.heuristic.beat.setup.desc": "Introduce the world and the main characters, and establish the status quo before everything changes.",
"outline.heuristic.beat.incitingIncident.title": "Inciting Incident",
"outline.heuristic.beat.incitingIncident.desc": "The event that sets the story in motion: {{idea}}.",
"outline.heuristic.beat.risingAction.title": "Rising Action",
"outline.heuristic.beat.risingAction.desc": "Complications escalate and the stakes grow as the characters pursue their goal.",
"outline.heuristic.beat.midpoint.title": "Midpoint",
"outline.heuristic.beat.midpoint.desc": "A turning point shifts the direction of the story and raises the stakes.",
"outline.heuristic.beat.complications.title": "Complications",
"outline.heuristic.beat.complications.desc": "Setbacks and conflicts deepen; the path forward narrows.",
"outline.heuristic.beat.twist.title": "Twist",
"outline.heuristic.beat.twist.desc": "An unexpected revelation upends what the characters believed to be true.",
"outline.heuristic.beat.climax.title": "Climax",
"outline.heuristic.beat.climax.desc": "The central conflict comes to a head in the story's defining confrontation.",
"outline.heuristic.beat.resolution.title": "Resolution",
"outline.heuristic.beat.resolution.desc": "Loose ends are tied up and a new status quo emerges."
"outline.title": "مُولِّد مخطط القصة بالذكاء الاصطناعي"
}
2 changes: 1 addition & 1 deletion locales/ar/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -673,7 +673,7 @@
"settings.privacy.encryptionCurrentPassphrase": "عبارة المرور الحالية",
"settings.privacy.encryptionDisableAction": "تعطيل",
"settings.privacy.encryptionDisableButton": "تعطيل التشفير",
"settings.privacy.encryptionDisableConfirm": "تعطيل التشفير",
"settings.privacy.encryptionDisableConfirm": "سيؤدي هذا إلى فك تشفير جميع بياناتك وإيقاف التشفير أثناء التخزين. ستبقى بياناتك على هذا الجهاز، لكنها لن تكون محمية بعد الآن بعبارة مرور.",
"settings.privacy.encryptionDisableFailed": "Could not disable encryption. Please try again.",
"settings.privacy.encryptionDisabledStatus": "التشفير أثناء السكون مُعطَّل",
"settings.privacy.encryptionEnabled": "تشفير بيانات المشروع أثناء السكون",
Expand Down
12 changes: 6 additions & 6 deletions locales/ar/worlds.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@
"worlds.edit.notes": "ملاحظات",
"worlds.editorTabsAriaLabel": "علامات تبويب محرّر العالم",
"worlds.error.imageFailed": "فشل توليد صورة الأجواء. حاول إضافة المزيد من التفاصيل إلى وصف العالم أو تحقّق من اتصالك.",
"worlds.heuristic.culture": "Describe the peoples, beliefs, and daily life shaped by {{concept}}.",
"worlds.heuristic.description": "A world defined by its central premise: {{concept}}.",
"worlds.heuristic.geography": "Outline the major regions, climates, and natural features of {{concept}}.",
"worlds.heuristic.magicSystem": "Define the rules, costs, and limits of power in {{concept}}.",
"worlds.heuristic.name": "New World",
"worlds.loading.profile": "جارٍ توليد ملف تعريف مفصّل للعالم...",
"worlds.newWorldName": "عالم جديد",
"worlds.noWorlds": "لم تُنشأ عوالم بعد.",
Expand All @@ -50,10 +55,5 @@
"worlds.tabs.timeline": "التاريخ والخط الزمني",
"worlds.title": "أطلس العالم",
"worlds.uploadImage": "رفع صورة",
"worlds.yourWorlds": "عوالمك",
"worlds.heuristic.name": "New World",
"worlds.heuristic.description": "A world defined by its central premise: {{concept}}.",
"worlds.heuristic.geography": "Outline the major regions, climates, and natural features of {{concept}}.",
"worlds.heuristic.magicSystem": "Define the rules, costs, and limits of power in {{concept}}.",
"worlds.heuristic.culture": "Describe the peoples, beliefs, and daily life shaped by {{concept}}."
"worlds.yourWorlds": "عوالمك"
}
36 changes: 18 additions & 18 deletions locales/ar/writer.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,20 @@
"writer.focusMode.enterLabel": "وضع التركيز",
"writer.focusMode.exit": "الخروج من وضع التركيز",
"writer.focusMode.exitLabel": "إنهاء التركيز",
"writer.grammar.addToDictionary": "Add to dictionary",
"writer.grammar.apply": "Apply",
"writer.grammar.checkButton": "Check this scene",
"writer.grammar.checking": "Checking…",
"writer.grammar.disabled": "Enable LanguageTool in Settings → Connections to check this scene.",
"writer.grammar.error": "The LanguageTool server returned an error.",
"writer.grammar.ignore": "Ignore",
"writer.grammar.issuesFound": "{{count}} issues found",
"writer.grammar.noIssues": "No issues found.",
"writer.grammar.noSuggestions": "No suggestions",
"writer.grammar.offline": "Couldn't reach the LanguageTool server. Is it running?",
"writer.grammar.selectScene": "Select a scene to check.",
"writer.grammar.title": "Grammar & Spelling",
"writer.grammar.unsupported": "Grammar check isn't available for this language.",
"writer.imagePrompt.description": "يولّد موجّهًا محسّنًا لـ DALL·E 3 ‏/ Midjourney من المشهد الحالي أو النص المحدّد.",
"writer.imagePrompt.note": "يعمل الموجّه المُولَّد مباشرة في DALL·E 3 و Midjourney.",
"writer.imagePrompt.tip": "نصيحة: حدّد قسمًا نصيًا محدّدًا للحصول على موجّه مشهد مركّز.",
Expand Down Expand Up @@ -52,12 +66,10 @@
"writer.studio.controls.tones.poetic": "أكثر شاعرية",
"writer.studio.controls.tones.suspenseful": "أكثر تشويقًا",
"writer.studio.description": "مؤلّفك المشارك بالذكاء الاصطناعي. ولّد وحسّن وعصف الأفكار بسياق المشروع الكامل.",
"writer.studio.rag.chunkScore": "الصلة {{score}}",
"writer.studio.rag.chunksBadge": "تم العثور على {{count}} مقطعًا من القصة",
"writer.studio.rag.chunksHint": "مقتطفات ذات صلة من مخطوطتك — المزيد من المقاطع يعني سياقًا أغنى للذكاء الاصطناعي",
"writer.studio.rag.inspectorLabel": "السياق المُسترجَع",
"writer.studio.rag.chunkScore": "الصلة {{score}}",
"writer.studio.tokens.badge": "~{{count}} رمز",
"writer.studio.tokens.hint": "عدد الرموز التقريبي المُستخدَم في آخر طلب للذكاء الاصطناعي",
"writer.studio.rag.useContext": "اسحب من قصتي",
"writer.studio.result.insert": "إدراج",
"writer.studio.result.next": "التالي",
Expand All @@ -67,6 +79,8 @@
"writer.studio.result.retry": "إعادة المحاولة",
"writer.studio.result.title": "مسوّدة الذكاء الاصطناعي",
"writer.studio.title": "استوديو الكتابة بالذكاء الاصطناعي",
"writer.studio.tokens.badge": "~{{count}} رمز",
"writer.studio.tokens.hint": "عدد الرموز التقريبي المُستخدَم في آخر طلب للذكاء الاصطناعي",
"writer.studio.tools.brainstorm.contextLabel": "سياق العصف الذهني (اختياري)",
"writer.studio.tools.brainstorm.contextPlaceholder": "قدّم موقفًا موجزًا، أو سيستخدم الذكاء الاصطناعي قسم المخطوطة الحالي.",
"writer.studio.tools.brainstorm.title": "عصف الأفكار",
Expand Down Expand Up @@ -98,19 +112,5 @@
"writer.tts.start": "قراءة بصوت عالٍ",
"writer.tts.stop": "إيقاف القراءة",
"writer.versionControl.label": "الإصدارات",
"writer.versionControl.tooltip": "التحكم بالإصدارات (الفروع واللقطات)",
"writer.grammar.title": "Grammar & Spelling",
"writer.grammar.checkButton": "Check this scene",
"writer.grammar.checking": "Checking…",
"writer.grammar.issuesFound": "{{count}} issues found",
"writer.grammar.noIssues": "No issues found.",
"writer.grammar.selectScene": "Select a scene to check.",
"writer.grammar.unsupported": "Grammar check isn't available for this language.",
"writer.grammar.disabled": "Enable LanguageTool in Settings → Connections to check this scene.",
"writer.grammar.offline": "Couldn't reach the LanguageTool server. Is it running?",
"writer.grammar.error": "The LanguageTool server returned an error.",
"writer.grammar.apply": "Apply",
"writer.grammar.ignore": "Ignore",
"writer.grammar.addToDictionary": "Add to dictionary",
"writer.grammar.noSuggestions": "No suggestions"
"writer.versionControl.tooltip": "التحكم بالإصدارات (الفروع واللقطات)"
}
Loading
Loading