feat: publication IA (magazine/brief/essay) + fixes critique
Some checks failed
CI / Lint, Unit Tests & Build (push) Failing after 1m22s
CI / Deploy production (on server) (push) Has been skipped

Publication IA:
- 4 templates (magazine, brief, essay, simple) avec CSS riche
- Rewrite IA (article/exercises/tutorial/reference/mixed)
- Modération avec timeout 12s + fallback safe
- Quotas publish_enhance par tier (basic=2, pro=15, business=100)
- Détection contenu stale (hash)
- Migration DB publishedContent/publishedTemplate/publishedSourceHash

Fixes:
- cheerio v1.2: Element -> AnyNode (domhandler), decodeEntities cast
- _isShared ajouté au type Note (champ virtuel serveur)
- callout colors PDF export: extraction fonction pure testable
- admin/published: guard note.userId null
- Cmd+S fonctionne en mode dialog (pas seulement fullPage)

i18n:
- 23 clés publish* traduites dans les 15 locales
- Extension Web Clipper: 13 locales mise à jour

Tests:
- callout-colors.test.ts (6 tests)
- note-visible-in-view.test.ts (5 tests)
- entitlements.test.ts + byok-entitlements.test.ts: mock usageLog + unstubAllEnvs
- 199/199 tests passent

Tracker: user-stories.md sync avec sprint-status.yaml
This commit is contained in:
Antigravity
2026-06-28 07:32:57 +00:00
parent 902fe95a69
commit 96e7902f01
169 changed files with 5382 additions and 1527 deletions

View File

@@ -197,7 +197,7 @@ const FR: LangDict = {
hero_badge: "Augmenté par l'Intelligence Artificielle",
hero_title_1: "Votre second cerveau,",
hero_title_italic: "enfin amplifié.",
hero_desc: "Momento n'est pas qu'une simple application de notes. C'est un écosystème intelligent qui connecte, analyse et développe vos idées en temps réel grâce à 6 types d'agents IA et une recherche sémantique de pointe.",
hero_desc: "Memento n'est pas qu'une simple application de notes. C'est un écosystème intelligent qui connecte, analyse et développe vos idées en temps réel grâce à 6 types d'agents IA et une recherche sémantique de pointe.",
hero_cta_start: "S'inscrire maintenant",
hero_cta_features: "Voir les fonctionnalités",
@@ -210,7 +210,7 @@ const FR: LangDict = {
features_badge: "Capacités IA",
features_title_1: "Une intelligence fluide,",
features_title_2: "intégrée à chaque mot.",
features_subtitle: "Momento orchestre vos idées grâce à une architecture multi-fournisseurs.",
features_subtitle: "Memento orchestre vos idées grâce à une architecture multi-fournisseurs.",
f1_title: "Recherche Sémantique",
f1_desc: "Ne cherchez plus par mots-clés. Trouvez par concept. Notre moteur hybride Vector + FTS comprend l'intention derrière vos notes.",
@@ -261,7 +261,7 @@ const FR: LangDict = {
price_popular: "Le plus populaire",
price_free_name: "Basic",
price_free_price: "Gratuit",
price_free_desc: "Pour découvrir la magie de Momento.",
price_free_desc: "Pour découvrir la magie de Memento.",
price_pro_name: "Pro",
price_pro_price: "9,90€",
price_pro_desc: "Pour les consultants et créateurs exigeants.",
@@ -285,7 +285,7 @@ const FR: LangDict = {
byok_badge: "Technologie Cloud Ouverte",
byok_title: "La stratégie BYOK",
byok_desc: "Vous possédez déjà des clés API OpenAI, Anthropic ou Google ? Connectez-les directement à Momento. Utilisez l'IA sans limites de crédits imposées, en payant uniquement ce que vous consommez chez votre fournisseur favori.",
byok_desc: "Vous possédez déjà des clés API OpenAI, Anthropic ou Google ? Connectez-les directement à Memento. Utilisez l'IA sans limites de crédits imposées, en payant uniquement ce que vous consommez chez votre fournisseur favori.",
byok_col1_title: "Pas de lock-in",
byok_col1_desc: "Changez de fournisseur en 1 clic.",
byok_col2_title: "Coûts optimisés",
@@ -294,10 +294,10 @@ const FR: LangDict = {
final_cta_title: "Prêt à libérer votre",
final_cta_title_italic: "plein potentiel ?",
final_cta_desc: "Rejoignez des milliers de chercheurs, designers et penseurs qui utilisent déjà Momento pour construire leur futur.",
final_cta_button: "Lancer Momento",
final_cta_desc: "Rejoignez des milliers de chercheurs, designers et penseurs qui utilisent déjà Memento pour construire leur futur.",
final_cta_button: "Lancer Memento",
eco_badge: "Écosystème Momento",
eco_badge: "Écosystème Memento",
eco_title_1: "Traduisez vos documents.",
eco_title_2: "Formatage préservé.",
eco_desc: "Le seul traducteur qui préserve les graphiques, tables des matières, formes et en-têtes — exactement tels qu'ils étaient. Prolongez l'intelligence de vos notes à l'international.",
@@ -352,7 +352,7 @@ const EN: LangDict = {
hero_badge: "Amplified by Artificial Intelligence",
hero_title_1: "Your second brain,",
hero_title_italic: "finally amplified.",
hero_desc: "Momento is not just a typical note-taking tool. It is an intelligent ecosystem that connects, analyzes, and scales your thoughts in real time with 6 autonomous AI agents and vector semantic search.",
hero_desc: "Memento is not just a typical note-taking tool. It is an intelligent ecosystem that connects, analyzes, and scales your thoughts in real time with 6 autonomous AI agents and vector semantic search.",
hero_cta_start: "Sign Up Now",
hero_cta_features: "View Features",
@@ -365,7 +365,7 @@ const EN: LangDict = {
features_badge: "AI Capabilities",
features_title_1: "Fluid intelligence,",
features_title_2: "integrated into every word.",
features_subtitle: "Momento orchestrates your thoughts through a multi-provider landscape.",
features_subtitle: "Memento orchestrates your thoughts through a multi-provider landscape.",
f1_title: "Semantic Search",
f1_desc: "Stop searching by keywords. Retrieve by concept. Our hybrid Vector + FTS engine understands the core semantic context behind your logs.",
@@ -416,7 +416,7 @@ const EN: LangDict = {
price_popular: "Most Popular",
price_free_name: "Basic",
price_free_price: "Free",
price_free_desc: "Get started with the foundational magic of Momento.",
price_free_desc: "Get started with the foundational magic of Memento.",
price_pro_name: "Pro",
price_pro_price: "$9.90",
price_pro_desc: "For consultants, writers, and advanced researchers.",
@@ -449,10 +449,10 @@ const EN: LangDict = {
final_cta_title: "Ready to expand your",
final_cta_title_italic: "second organic brain?",
final_cta_desc: "Join thousands of academics, product architects, and minimalist designers scaling their insights with Momento.",
final_cta_button: "Launch Momento",
final_cta_desc: "Join thousands of academics, product architects, and minimalist designers scaling their insights with Memento.",
final_cta_button: "Launch Memento",
eco_badge: "Momento Ecosystem",
eco_badge: "Memento Ecosystem",
eco_title_1: "Local document translation.",
eco_title_2: "Format intact.",
eco_desc: "The only translator preserving graphs, nested hierarchies, vectors, alignments, and titles exactly as you drew them. Take your local notes globally.",
@@ -507,7 +507,7 @@ const JA: LangDict = {
hero_badge: "人工知能による拡張済システム",
hero_title_1: "あなたの第二の脳を、",
hero_title_italic: "ついに具現化する。",
hero_desc: "Momentoモメントは単なるメモ帳ではありません。6体の専門AIエージェント、ハイブリッドベクトル検索を搭載し、リアルタイムで知識の接続、整理、展開を実行する知能エコシステムです。",
hero_desc: "Mementoモメントは単なるメモ帳ではありません。6体の専門AIエージェント、ハイブリッドベクトル検索を搭載し、リアルタイムで知識の接続、整理、展開を実行する知能エコシステムです。",
hero_cta_start: "無料で体験する",
hero_cta_features: "機能一覧を見る",
@@ -520,7 +520,7 @@ const JA: LangDict = {
features_badge: "先進AI性能",
features_title_1: "記述に完全に融合する、",
features_title_2: "インテリジェンス。",
features_subtitle: "Momentoは、複数のLLMプロバイダを容易に構成可能な適応性を備えています。",
features_subtitle: "Mementoは、複数のLLMプロバイダを容易に構成可能な適応性を備えています。",
f1_title: "セマンティック意味検索",
f1_desc: "単なるキーワード検索はもう不要。記述された文脈、概念そのものを捉えて、過去の関連メモを一瞬で検索します。",
@@ -571,7 +571,7 @@ const JA: LangDict = {
price_popular: "人気プラン",
price_free_name: "ベーシック",
price_free_price: "無料",
price_free_desc: "Momentoの見事な基礎機能をすぐにお試しいただけます。",
price_free_desc: "Mementoの見事な基礎機能をすぐにお試しいただけます。",
price_pro_name: "プロ",
price_pro_price: "¥1,480",
price_pro_desc: "ライター、学習者、研究者、コンサルタントの方へ最適。",
@@ -595,7 +595,7 @@ const JA: LangDict = {
byok_badge: "オープン構想",
byok_title: "APIキー持ち込みBYOK",
byok_desc: "OpenAI、Anthropic、Googleなどの既存APIキーをお持ちですかMomentoに直接バインドすれば、従量課金のみで任意の極限モデルを完全に制限なしで無制限にご利用いただけます。",
byok_desc: "OpenAI、Anthropic、Googleなどの既存APIキーをお持ちですかMementoに直接バインドすれば、従量課金のみで任意の極限モデルを完全に制限なしで無制限にご利用いただけます。",
byok_col1_title: "ロックイン縛りゼロ",
byok_col1_desc: "好みのプロバイダやエンジンへ一瞬でコンフィグを切り替えられます。",
byok_col2_title: "中抜きマージン排除",
@@ -604,10 +604,10 @@ const JA: LangDict = {
final_cta_title: "あなたの第二の有機的な脳を",
final_cta_title_italic: "今すぐ起動させましょう。",
final_cta_desc: "最先端デザインと人工知能を極限まで融合させたMomento。すでに数千人のアカデミアやデザイナーが思考のスケールを始めています。",
final_cta_button: "Momentoを起動する",
final_cta_desc: "最先端デザインと人工知能を極限まで融合させたMemento。すでに数千人のアカデミアやデザイナーが思考のスケールを始めています。",
final_cta_button: "Mementoを起動する",
eco_badge: "Momentoエコシステム",
eco_badge: "Mementoエコシステム",
eco_title_1: "ドキュメントローカル翻訳。",
eco_title_2: "完璧な構造維持。",
eco_desc: "グラフ、入れ子、アライメント、レイアウト、タイトル座標のすべてを完璧に保持したまま、言語領域を変換します。アイデアを瞬時にグローバルへ。",
@@ -693,7 +693,7 @@ export const LandingPage: React.FC<LandingPageProps> = ({ onEnter, onLogin, onRe
carnet: "Database & Books",
date: "26 Oct 2024",
tags: ["Relational", "Rollup", "Blocks"],
content: `# H2 Relation and Rollup\n\nCe document démontre la puissance du modèle relationnel de Momento.\n\n## 1. Modèle Relationnel\nVous pouvez lier des auteurs à leurs œuvres pour comptabiliser dynamiquement les entrées grâce à notre système de Rollups sémantiques.`,
content: `# H2 Relation and Rollup\n\nCe document démontre la puissance du modèle relationnel de Memento.\n\n## 1. Modèle Relationnel\nVous pouvez lier des auteurs à leurs œuvres pour comptabiliser dynamiquement les entrées grâce à notre système de Rollups sémantiques.`,
stats: { words: 124, lines: 18, equations: 1, graphs: 4, images: 3 }
},
{
@@ -702,7 +702,7 @@ export const LandingPage: React.FC<LandingPageProps> = ({ onEnter, onLogin, onRe
carnet: "Mathematical & Geometrical",
date: "24 Oct 2024",
tags: ["LaTeX", "Gantt", "Flowcharts"],
content: `# Block-Style Math & Formulas\n\nMomento supporte les équations complexes de type LaTeX et les diagrammes sémantiques directement intégrés sous forme de blocs.\n\n$$\\Phi = \\frac{1 + \\sqrt{5}}{2}$$\n\n$$\\Delta Carbon = E_{béton} - E_{CLT} = 410 \\text{ kg } CO_2/m^3$$`,
content: `# Block-Style Math & Formulas\n\nMemento supporte les équations complexes de type LaTeX et les diagrammes sémantiques directement intégrés sous forme de blocs.\n\n$$\\Phi = \\frac{1 + \\sqrt{5}}{2}$$\n\n$$\\Delta Carbon = E_{béton} - E_{CLT} = 410 \\text{ kg } CO_2/m^3$$`,
stats: { words: 91, lines: 12, equations: 2, graphs: 4, images: 1 }
},
{
@@ -855,7 +855,7 @@ export const LandingPage: React.FC<LandingPageProps> = ({ onEnter, onLogin, onRe
<div className="w-10 h-10 bg-ink flex items-center justify-center rounded-xl shadow-lg rotate-3 group hover:rotate-0 transition-transform cursor-pointer">
<span className="text-paper font-serif text-2xl font-bold">M</span>
</div>
<span className="font-serif text-2xl font-medium tracking-tight">Momento</span>
<span className="font-serif text-2xl font-medium tracking-tight">Memento</span>
</div>
<div className="hidden lg:flex items-center gap-10">
@@ -1383,10 +1383,10 @@ export const LandingPage: React.FC<LandingPageProps> = ({ onEnter, onLogin, onRe
</button>
<p className="text-stone-605">
{lang === 'fr'
? "Momento intègre des équations mathématiques pures et des diagrammes sémantiques ou Gantt de manière entièrement nativisée sous forme de blocs WYSIWYG."
? "Memento intègre des équations mathématiques pures et des diagrammes sémantiques ou Gantt de manière entièrement nativisée sous forme de blocs WYSIWYG."
: lang === 'ja'
? "Momentoは本格的なLaTeX数式および概念関係フローチャートをWYSIWYGブロックとして極めて滑らかに表示・調整可能です。"
: "Momento integrates highly stylized Mathematical LaTeX formulas and semantic/Gantt flowcharts directly as interactive WYSIWYG blocks."}
? "Mementoは本格的なLaTeX数式および概念関係フローチャートをWYSIWYGブロックとして極めて滑らかに表示・調整可能です。"
: "Memento integrates highly stylized Mathematical LaTeX formulas and semantic/Gantt flowcharts directly as interactive WYSIWYG blocks."}
</p>
</div>
)}
@@ -1475,9 +1475,9 @@ export const LandingPage: React.FC<LandingPageProps> = ({ onEnter, onLogin, onRe
</button>
<p className="text-stone-605">
{lang === 'fr'
? "Le noyau de Momento est conçu pour gérer d'immenses documents textuels (plus d'un million de mots) avec une latence quasi nulle en virtualisant les sous-structures."
? "Le noyau de Memento est conçu pour gérer d'immenses documents textuels (plus d'un million de mots) avec une latence quasi nulle en virtualisant les sous-structures."
: lang === 'ja'
? "Momentoの超高速仮想ドキュメントレンダリングは、合計100万語を越える膨大な書籍や論文データベースでも、表示遅延なく高速に動作・ブロック分割制御可能です。"
? "Mementoの超高速仮想ドキュメントレンダリングは、合計100万語を越える膨大な書籍や論文データベースでも、表示遅延なく高速に動作・ブロック分割制御可能です。"
: "Its lightweight framework allows seamlessly displaying and editing files sizing up to 1,000,000 words without single-frame drops thanks to block virtualization."}
</p>
</div>
@@ -1544,10 +1544,10 @@ export const LandingPage: React.FC<LandingPageProps> = ({ onEnter, onLogin, onRe
Markdown
</div>
{activeDemoIdx === 0 && (
`# H2 Relation and Rollup\n\nCe document démontre la puissance du modèle relationnel de Momento.\n\n## 1. Modèle Relationnel\nLier des auteurs à leurs œuvres pour comptabiliser dynamiquement.\n\n[DATABASE id="authors-works" view="table"]\n\n## Template\nTemplates can access values via syntax: .action { .field }`
`# H2 Relation and Rollup\n\nCe document démontre la puissance du modèle relationnel de Memento.\n\n## 1. Modèle Relationnel\nLier des auteurs à leurs œuvres pour comptabiliser dynamiquement.\n\n[DATABASE id="authors-works" view="table"]\n\n## Template\nTemplates can access values via syntax: .action { .field }`
)}
{activeDemoIdx === 1 && (
`# Block-Style Math & Formulas\n\nMomento supporte LaTeX.\n\n$$ \\Phi = \\frac{1 + \\sqrt{5}}{2} $$\n\n$$ \\Delta Carbon = E_béton - E_CLT = 410 $$`
`# Block-Style Math & Formulas\n\nMemento supporte LaTeX.\n\n$$ \\Phi = \\frac{1 + \\sqrt{5}}{2} $$\n\n$$ \\Delta Carbon = E_béton - E_CLT = 410 $$`
)}
{activeDemoIdx === 2 && (
`# Large Document Virtualization\n\nLe moteur supporte de longs documents.\n\n## Zoom-In de bloc\nIsoler un bloc spécifique pour se concentrer.`
@@ -1566,7 +1566,7 @@ export const LandingPage: React.FC<LandingPageProps> = ({ onEnter, onLogin, onRe
{editorMode === 'html' && (
<div className="space-y-2.5 font-mono text-[9px]">
<div className="bg-slate-50 border p-3 rounded-lg text-emerald-800 space-y-2 select-all leading-snug">
<div>{`<!-- Momento Symmetrical DOM Tree map -->`}</div>
<div>{`<!-- Memento Symmetrical DOM Tree map -->`}</div>
<div>{`<div class="note-container font-serif" id="momento-doc-${activeDemoIdx}">`}</div>
<div className="pl-3">{`<h2 class="title text-lg border-b">${activeDemoIdx === -1 ? "Synthèse" : realNotes[activeDemoIdx].title}</h2>`}</div>
<div className="pl-3">{`<div class="section-meta flex text-[8px] uppercase">`}</div>
@@ -2385,7 +2385,7 @@ export const LandingPage: React.FC<LandingPageProps> = ({ onEnter, onLogin, onRe
<div className="w-8 h-8 bg-ink flex items-center justify-center rounded-lg">
<span className="text-paper font-serif text-lg font-bold">M</span>
</div>
<span className="font-serif text-xl font-medium tracking-tight">Momento</span>
<span className="font-serif text-xl font-medium tracking-tight">Memento</span>
</div>
<p className="text-sm text-concrete font-light max-w-xs leading-relaxed">{t('footer_desc')}</p>
</div>