diff --git a/.changeset/8329-ai-build-empty-state-v1-boundary.md b/.changeset/8329-ai-build-empty-state-v1-boundary.md new file mode 100644 index 000000000..dfeb8cd5e --- /dev/null +++ b/.changeset/8329-ai-build-empty-state-v1-boundary.md @@ -0,0 +1,22 @@ +--- +'@object-ui/i18n': patch +'@object-ui/app-shell': patch +--- + +AI 搭建入口的空状态不再承诺 v1 拒绝的东西(objectui#8329)。 + +`console.ai.empty.build.description` 和 `console.ai.empty.editApp.description` +原本告诉用户「描述一个应用或流程 —— 我会起草对象、界面和自动化」。cloud 的 v1 +创作边界(ADR-0112)不含流程、动作、定时,模型会明确拒绝这类请求,所以这是入口 +处对用户做的一个会被打回的承诺。它是这个家族里最后一处 —— 起始 chip 的措辞 +(cloud#1984)和模型收尾的「后续你可以」(cloud#2022)已经修过。 + +⚠️ **十个语言包每一个都有自己翻译好的违规版本**,全部一并修正;组件里两处硬编码 +`defaultValue` 兜底也同步更新,否则任一语言包丢 key 时旧承诺会静默回归。 + +未改动的是**手工**路径的文案(`home.build.subtitle`、Studio 落地页、导入时运行 +已有自动化、打包自动化运维、marketplace 分类)—— Studio 确实能建流程,那些承诺 +是真的。判据是「v1 的 AI 创作边界」,不是「automation 这个词」。 + +回滚:ADR-0112 v2 加回流程/动作时,这两句与 chip 文案同一行回滚;测试里的 +`RETIRED` 映射存了十个语言包的原句。 diff --git a/packages/app-shell/src/console/ai/AiChatPage.tsx b/packages/app-shell/src/console/ai/AiChatPage.tsx index b659675e3..75ec2dc38 100644 --- a/packages/app-shell/src/console/ai/AiChatPage.tsx +++ b/packages/app-shell/src/console/ai/AiChatPage.tsx @@ -350,7 +350,7 @@ export function agentEmptyState( : t('console.ai.empty.editApp.titleGeneric', { defaultValue: 'Edit this app' }), description: t('console.ai.empty.editApp.description', { defaultValue: - 'What would you like to change? I’ll modify this app in place — add a field, object, view or automation, or adjust what’s already there.', + 'What would you like to change? I’ll modify this app in place — add a field, object, view or dashboard, or adjust what’s already there.', }), }; } @@ -358,7 +358,7 @@ export function agentEmptyState( title: t('console.ai.empty.build.title', { defaultValue: 'Build with AI' }), description: t('console.ai.empty.build.description', { defaultValue: - 'Describe an app or workflow in plain language — I draft the objects, screens and automations, then you review and publish.', + 'Describe an app in plain language — I draft the objects, screens and sample data, then you review and publish.', }), }; } diff --git a/packages/i18n/src/__tests__/makerEmptyState-v1-scope-8329.test.ts b/packages/i18n/src/__tests__/makerEmptyState-v1-scope-8329.test.ts new file mode 100644 index 000000000..4d15faf53 --- /dev/null +++ b/packages/i18n/src/__tests__/makerEmptyState-v1-scope-8329.test.ts @@ -0,0 +1,231 @@ +/** + * ObjectUI + * Copyright (c) 2024-present ObjectStack Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** + * objectui#8329 — the maker's EMPTY-STATE prose, third and last member of the + * ADR-0112 v1 boundary family on the build surface: + * + * 1. the five from-scratch start chips — cloud#1984 / objectui#7710 + * 2. the four edit-mode start chips — objectui#7709 + * 3. the model's own closing suggestions— cloud#2020 / cloud#2022 + * 4. ⬅ THIS: the two sentences ABOVE all of them + * + * `agentEmptyState()` renders a title and a description under the build + * surface's heading. The description is the FIRST sentence a new user reads on + * that page, and both variants were promising capabilities v1 refuses: + * + * build.description 'Describe an app or workflow in plain language — I draft + * the objects, screens and automations, …' + * editApp.description '… add a field, object, view or automation, …' + * + * v1 has no flows, actions or schedules (`V1_METADATA_TYPES` in cloud + * `service-ai-studio/src/authoring-whitelist.ts`), so a user who took either + * sentence at its word was refused outright — and unlike a chip, this one is + * read before anything else on the screen. Both now name only what v1 builds. + * + * Same three-part shape as the 1984 / 7709 suites, and part 3 is what keeps the + * other two honest: + * + * 1. Every shipped pack defines both descriptions, non-empty. + * 2. Neither description in any pack uses vocabulary that promises autonomous + * behaviour, scanned with that pack's OWN banned list — an English-only + * scan would have declared the five non-Latin packs clean without reading a + * character of them (AGENTS.md i18n forensics rule). This is not + * hypothetical here: all ten packs shipped a translated violation, so the + * issue's premise that "only en and zh have this key" was wrong. + * 3. A NON-VACUITY control: each pack's banned list is re-run against the two + * sentences that pack actually shipped before this card, and must flag both. + * + * ⚠️ Scope note — this suite guards the AI-AUTHORING promise, not the word + * "automation". The platform's manual automation surfaces are real and are + * deliberately NOT covered: `home.build.subtitle` (its card opens Studio, which + * genuinely authors flows), `engine.studio.landing.description`, + * `dataImport.optRunAutomations`, `packagedAutomation.*`, the marketplace + * `automation` category, and the approvals / flow-runner groups. + * + * REVERT the wording (and relax this suite) when ADR-0112 v2 re-adds flows and + * actions — same line of the roadmap as the chips. RETIRED below is where each + * pack's automation sentence is kept. + */ +import { describe, it, expect } from 'vitest'; +import { builtInLocales } from '../locales'; + +type LocaleCode = keyof typeof builtInLocales; +const LANGS = Object.keys(builtInLocales) as LocaleCode[]; + +/** The two descriptions `agentEmptyState()` can render on the build surface. */ +const VARIANTS = ['build', 'editApp'] as const; +type Variant = (typeof VARIANTS)[number]; + +/** The pack's empty-state block, reached through the shape the call site reads. */ +const emptyOf = (lang: LocaleCode) => + ( + builtInLocales[lang] as { + console?: { + ai?: { empty?: Record }; + }; + } + ).console?.ai?.empty; + +const descriptionOf = (lang: LocaleCode, v: Variant) => emptyOf(lang)?.[v]?.description; + +/** + * Vocabulary that promises the product will ACT on its own. The automation half + * is the `makerStartChips-v1-scope-1984` / `makerEditChips-v1-scope-7709` list + * verbatim — one v1 boundary, three families reading it. Added here: the + * "workflow" noun each pack used in the RETIRED build sentence, which the chip + * lists did not all need (`流程` for zh, whose chip wording said `流转`). + * + * Stems, not whole words, and substring matching with no ASCII word classes — + * five of the ten packs are non-Latin and CJK has no word boundaries. + */ +const BANNED: Record = { + en: ['alert', 'remind', 'notif', 'automat', 'workflow', 'trigger', 'schedule', 'approv'], + zh: ['提醒', '预警', '警报', '自动', '流转', '流程', '工作流', '通知', '触发', '定时', '审批'], + de: ['automat', 'erinner', 'warnung', 'alarm', 'benachrichtig', 'workflow', 'auslös', 'ablauf', 'freigabe', 'genehmig'], + fr: ['automat', 'alerte', 'rappel', 'notifi', 'workflow', 'flux', 'déclench', 'approbation', 'approuv'], + es: ['automat', 'alerta', 'recordar', 'recordatorio', 'notifi', 'flujo', 'disparador', 'aprob'], + pt: ['automa', 'alerta', 'lembr', 'notifi', 'fluxo', 'gatilho', 'aprova'], + ru: ['автомат', 'оповещ', 'уведомл', 'напомин', 'триггер', 'процесс', 'поток', 'согласован', 'утвержд'], + ja: ['自動', '通知', 'アラート', 'リマイン', 'ワークフロー', 'フロー', 'トリガー', '承認'], + ko: ['자동', '알림', '알람', '워크플로', '흐름', '트리거', '승인'], + ar: ['أتمتة', 'مؤتمت', 'تنبيه', 'إشعار', 'تذكير', 'سير عمل', 'موافقة', 'اعتماد'], +}; + +/** Every banned term this text hits, lower-cased for the case-insensitive scripts. */ +function bannedHits(lang: LocaleCode, text: string): string[] { + const haystack = text.toLocaleLowerCase(lang === 'zh' ? 'zh' : undefined); + return BANNED[lang].filter((term) => haystack.includes(term.toLocaleLowerCase())); +} + +/** + * The two sentences each pack shipped BEFORE this card. Kept as the control + * sample AND as the record of what ADR-0112 v2 restores — not as a fixture to + * revert to today. + */ +const RETIRED: Record> = { + en: { + build: 'Describe an app or workflow in plain language — I draft the objects, screens and automations, then you review and publish.', + editApp: 'What would you like to change? I’ll modify this app in place — add a field, object, view or automation, or adjust what’s already there.', + }, + zh: { + build: '用自然语言描述一个应用或流程 —— 我会起草对象、界面和自动化,随后你审阅并发布。', + editApp: '想改点什么?我会就地修改这个应用 —— 加字段、对象、视图或自动化,或调整已有内容。', + }, + de: { + build: 'Beschreiben Sie eine App oder einen Workflow in einfachen Worten — ich entwerfe die Objekte, Bildschirme und Automatisierungen, dann prüfen und veröffentlichen Sie.', + editApp: 'Was möchten Sie ändern? Ich passe diese App direkt an — ein Feld, Objekt, eine Ansicht oder Automatisierung hinzufügen oder Vorhandenes anpassen.', + }, + fr: { + build: 'Décrivez une application ou un flux de travail en langage courant — je rédige les objets, les écrans et les automatisations, puis vous vérifiez et publiez.', + editApp: "Que souhaitez-vous changer ? Je modifie cette application sur place — ajouter un champ, un objet, une vue ou une automatisation, ou ajuster l'existant.", + }, + es: { + build: 'Describa una aplicación o un flujo de trabajo en lenguaje natural — yo redacto los objetos, las pantallas y las automatizaciones, y luego usted revisa y publica.', + editApp: '¿Qué desea cambiar? Modifico esta aplicación sobre la marcha — añadir un campo, un objeto, una vista o una automatización, o ajustar lo que ya existe.', + }, + pt: { + build: 'Descreva um aplicativo ou fluxo de trabalho em linguagem simples — eu rascunho os objetos, telas e automações, e então você revisa e publica.', + editApp: 'O que você quer mudar? Eu altero este aplicativo no lugar — adicionar um campo, objeto, visão ou automação, ou ajustar o que já existe.', + }, + ru: { + build: 'Опишите приложение или процесс обычными словами — я подготовлю объекты, экраны и автоматизации, а вы проверите и опубликуете.', + editApp: 'Что нужно изменить? Я изменю это приложение на месте — добавлю поле, объект, представление или автоматизацию либо скорректирую существующее.', + }, + ja: { + build: 'アプリやワークフローを普通の言葉で説明してください — オブジェクト、画面、自動化を下書きしますので、確認して公開してください。', + editApp: '何を変更しますか?このアプリをその場で変更します — 項目、オブジェクト、ビュー、自動化の追加や、既存部分の調整ができます。', + }, + ko: { + build: '앱이나 워크플로를 일상 언어로 설명해 주세요 — 객체, 화면, 자동화를 초안으로 만들어 드리면 검토 후 게시하시면 됩니다.', + editApp: '무엇을 바꿀까요? 이 앱을 그 자리에서 수정합니다 — 필드, 객체, 뷰, 자동화를 추가하거나 기존 내용을 조정할 수 있습니다.', + }, + ar: { + build: 'صف تطبيقًا أو سير عمل بلغة بسيطة — سأعدّ مسودة الكائنات والشاشات والأتمتة، ثم تراجعها وتنشرها.', + editApp: 'ما الذي تريد تغييره؟ سأعدّل هذا التطبيق في مكانه — إضافة حقل أو كائن أو عرض أو أتمتة، أو تعديل ما هو موجود.', + }, +}; + +describe('maker empty state — every shipped pack carries both descriptions (objectui#8329)', () => { + it('covers all ten built-in packs', () => { + expect(LANGS).toHaveLength(10); + }); + + it.each(LANGS)('%s defines a non-empty description for both variants', (lang) => { + const block = emptyOf(lang); + expect(block, `${lang} has no console.ai.empty block`).toBeTruthy(); + for (const v of VARIANTS) { + const d = descriptionOf(lang, v); + expect(typeof d, `${lang}.empty.${v}.description`).toBe('string'); + expect(d!.trim().length, `${lang}.empty.${v}.description is empty`).toBeGreaterThan(0); + } + }); + + it.each(LANGS)('%s still carries the titles the two variants render', (lang) => { + // The fix touched descriptions only; a pack that lost a title would fall + // back to the English defaultValue without any test noticing. + const block = emptyOf(lang)!; + expect(block.build?.title?.trim()).toBeTruthy(); + expect(block.editApp?.title?.trim()).toBeTruthy(); + }); +}); + +describe('maker empty state — neither description promises autonomous behaviour (objectui#8329)', () => { + it.each(LANGS)("%s: neither description uses that pack's automation vocabulary", (lang) => { + for (const v of VARIANTS) { + const d = descriptionOf(lang, v)!; + expect(bannedHits(lang, d), `${lang}.empty.${v}.description: "${d}"`).toEqual([]); + } + }); + + it.each(LANGS)('%s: the banned list still flags BOTH sentences this pack retired', (lang) => { + // Non-vacuity. A green run above means nothing unless this is green too — + // and it must flag both variants, not just the louder `build` one. + for (const v of VARIANTS) { + const retired = RETIRED[lang][v]; + expect( + bannedHits(lang, retired).length, + `${lang} control (${v}): "${retired}"`, + ).toBeGreaterThan(0); + } + }); + + it.each(LANGS)('%s: the description actually changed from what it retired', (lang) => { + // Guards the reverse mistake of a pack being "fixed" by copying its own old + // string back in during a merge. + for (const v of VARIANTS) { + expect(descriptionOf(lang, v), `${lang}.${v}`).not.toBe(RETIRED[lang][v]); + } + }); +}); + +describe('maker empty state — the replacement names v1 capabilities (objectui#8329)', () => { + it('en/zh build: offers an app (not a workflow) and sample data', () => { + const en = descriptionOf('en', 'build')!; + expect(en).toMatch(/describe an app/i); + expect(en).toContain('sample data'); + + const zh = descriptionOf('zh', 'build')!; + expect(zh).toContain('示例数据'); + expect(zh).not.toContain('或流程'); + }); + + it('en/zh editApp: offers a dashboard in the slot automation used to hold', () => { + expect(descriptionOf('en', 'editApp')!).toContain('dashboard'); + expect(descriptionOf('zh', 'editApp')!).toContain('仪表盘'); + }); + + it('en editApp keeps the in-place framing its own unit test asserts', () => { + // `packages/app-shell/src/console/ai/__tests__/editModeEmptyState.test.ts` + // matches /change/i and /in place/i against the defaultValue; the pack and + // that fallback must not drift apart. + const en = descriptionOf('en', 'editApp')!; + expect(en).toMatch(/change/i); + expect(en).toMatch(/in place/i); + }); +}); diff --git a/packages/i18n/src/locales/ar.ts b/packages/i18n/src/locales/ar.ts index 9683b8d8f..537ef4ce8 100644 --- a/packages/i18n/src/locales/ar.ts +++ b/packages/i18n/src/locales/ar.ts @@ -1574,7 +1574,7 @@ const ar = { empty: { build: { title: "الإنشاء بالذكاء الاصطناعي", - description: "صف تطبيقًا أو سير عمل بلغة بسيطة — سأعدّ مسودة الكائنات والشاشات والأتمتة، ثم تراجعها وتنشرها.", + description: "صف تطبيقًا بلغة بسيطة — سأعدّ مسودة الكائنات والشاشات والبيانات النموذجية، ثم تراجعها وتنشرها.", }, ask: { title: "اسأل بياناتك", @@ -1583,7 +1583,7 @@ const ar = { editApp: { title: "تحرير «{{app}}»", titleGeneric: "تحرير هذا التطبيق", - description: "ما الذي تريد تغييره؟ سأعدّل هذا التطبيق في مكانه — إضافة حقل أو كائن أو عرض أو أتمتة، أو تعديل ما هو موجود.", + description: "ما الذي تريد تغييره؟ سأعدّل هذا التطبيق في مكانه — إضافة حقل أو كائن أو عرض أو لوحة معلومات، أو تعديل ما هو موجود.", }, }, clearConversation: "مسح", diff --git a/packages/i18n/src/locales/de.ts b/packages/i18n/src/locales/de.ts index 87eacc684..1db3a1dcf 100644 --- a/packages/i18n/src/locales/de.ts +++ b/packages/i18n/src/locales/de.ts @@ -1567,7 +1567,7 @@ const de = { empty: { build: { title: "Mit KI erstellen", - description: "Beschreiben Sie eine App oder einen Workflow in einfachen Worten — ich entwerfe die Objekte, Bildschirme und Automatisierungen, dann prüfen und veröffentlichen Sie.", + description: "Beschreiben Sie eine App in einfachen Worten — ich entwerfe die Objekte, Bildschirme und Beispieldaten, dann prüfen und veröffentlichen Sie.", }, ask: { title: "Ihre Daten fragen", @@ -1576,7 +1576,7 @@ const de = { editApp: { title: "„{{app}}“ wird bearbeitet", titleGeneric: "Diese App bearbeiten", - description: "Was möchten Sie ändern? Ich passe diese App direkt an — ein Feld, Objekt, eine Ansicht oder Automatisierung hinzufügen oder Vorhandenes anpassen.", + description: "Was möchten Sie ändern? Ich passe diese App direkt an — ein Feld, Objekt, eine Ansicht oder ein Dashboard hinzufügen oder Vorhandenes anpassen.", }, }, clearConversation: "Leeren", diff --git a/packages/i18n/src/locales/en.ts b/packages/i18n/src/locales/en.ts index 6230c13a9..e70f092bf 100644 --- a/packages/i18n/src/locales/en.ts +++ b/packages/i18n/src/locales/en.ts @@ -1897,11 +1897,34 @@ const en = { emptyDescription: 'Ask anything — the assistant has access to your current app context.', switchAssistant: 'Switch assistant', chooseAgent: 'Choose assistant…', + // objectui#8329 — the maker's empty-state prose, and the FIRST sentence a + // new user reads on the build surface (it sits above the start chips). + // Same ADR-0112 v1 boundary the chips answer to (cloud#1984 / + // objectui#7709 for the starters, cloud#2022 for the model's own closing + // suggestions): these two descriptions are the product PROMISING, so they + // may only name what v1 BUILDS — objects, fields, views, pages, + // dashboards, sample data, apps and navigation. `build.description` used + // to offer "an app or workflow … objects, screens and automations" and + // `editApp.description` "… view or automation"; v1 has no flows, actions + // or schedules, so a user who took either at its word was refused + // outright — the worst possible answer to the first line on the page. + // + // NOT the same thing as the platform's manual automation surfaces, which + // are real and stay as they are: `home.build.subtitle` (that card opens + // Studio, which does author flows), `engine.studio.landing.description`, + // `dataImport.optRunAutomations`, `packagedAutomation.*` and the + // marketplace `automation` category. The boundary is v1 AI AUTHORING, not + // the word "automation". + // + // REVERT both sentences when ADR-0112 v2 re-adds flows and actions — same + // line of the version roadmap as the chips. Every pack's wording is + // guarded, in its own script, by + // `packages/i18n/src/__tests__/makerEmptyState-v1-scope-8329.test.ts`. empty: { build: { title: 'Build with AI', description: - 'Describe an app or workflow in plain language — I draft the objects, screens and automations, then you review and publish.', + 'Describe an app in plain language — I draft the objects, screens and sample data, then you review and publish.', }, ask: { title: 'Ask your data', @@ -1912,7 +1935,7 @@ const en = { title: 'Editing “{{app}}”', titleGeneric: 'Edit this app', description: - 'What would you like to change? I’ll modify this app in place — add a field, object, view or automation, or adjust what’s already there.', + 'What would you like to change? I’ll modify this app in place — add a field, object, view or dashboard, or adjust what’s already there.', }, }, clearConversation: 'Clear', diff --git a/packages/i18n/src/locales/es.ts b/packages/i18n/src/locales/es.ts index da9488174..ab0b85f78 100644 --- a/packages/i18n/src/locales/es.ts +++ b/packages/i18n/src/locales/es.ts @@ -1571,7 +1571,7 @@ const es = { empty: { build: { title: "Crear con IA", - description: "Describa una aplicación o un flujo de trabajo en lenguaje natural — yo redacto los objetos, las pantallas y las automatizaciones, y luego usted revisa y publica.", + description: "Describa una aplicación en lenguaje natural — yo redacto los objetos, las pantallas y los datos de ejemplo, y luego usted revisa y publica.", }, ask: { title: "Pregunte a sus datos", @@ -1580,7 +1580,7 @@ const es = { editApp: { title: "Editando «{{app}}»", titleGeneric: "Editar esta aplicación", - description: "¿Qué desea cambiar? Modifico esta aplicación sobre la marcha — añadir un campo, un objeto, una vista o una automatización, o ajustar lo que ya existe.", + description: "¿Qué desea cambiar? Modifico esta aplicación sobre la marcha — añadir un campo, un objeto, una vista o un panel, o ajustar lo que ya existe.", }, }, clearConversation: "Borrar", diff --git a/packages/i18n/src/locales/fr.ts b/packages/i18n/src/locales/fr.ts index 22fcb57b0..d2fac6e87 100644 --- a/packages/i18n/src/locales/fr.ts +++ b/packages/i18n/src/locales/fr.ts @@ -1569,7 +1569,7 @@ const fr = { empty: { build: { title: "Créer avec l'IA", - description: "Décrivez une application ou un flux de travail en langage courant — je rédige les objets, les écrans et les automatisations, puis vous vérifiez et publiez.", + description: "Décrivez une application en langage courant — je rédige les objets, les écrans et les données d'exemple, puis vous vérifiez et publiez.", }, ask: { title: "Interroger vos données", @@ -1578,7 +1578,7 @@ const fr = { editApp: { title: "Modification de « {{app}} »", titleGeneric: "Modifier cette application", - description: "Que souhaitez-vous changer ? Je modifie cette application sur place — ajouter un champ, un objet, une vue ou une automatisation, ou ajuster l'existant.", + description: "Que souhaitez-vous changer ? Je modifie cette application sur place — ajouter un champ, un objet, une vue ou un tableau de bord, ou ajuster l'existant.", }, }, clearConversation: "Effacer", diff --git a/packages/i18n/src/locales/ja.ts b/packages/i18n/src/locales/ja.ts index 79b0d48c7..032b5cdfc 100644 --- a/packages/i18n/src/locales/ja.ts +++ b/packages/i18n/src/locales/ja.ts @@ -1569,7 +1569,7 @@ const ja = { empty: { build: { title: "AI でビルド", - description: "アプリやワークフローを普通の言葉で説明してください — オブジェクト、画面、自動化を下書きしますので、確認して公開してください。", + description: "アプリを普通の言葉で説明してください — オブジェクト、画面、サンプルデータを下書きしますので、確認して公開してください。", }, ask: { title: "データに質問", @@ -1578,7 +1578,7 @@ const ja = { editApp: { title: "「{{app}}」を編集中", titleGeneric: "このアプリを編集", - description: "何を変更しますか?このアプリをその場で変更します — 項目、オブジェクト、ビュー、自動化の追加や、既存部分の調整ができます。", + description: "何を変更しますか?このアプリをその場で変更します — 項目、オブジェクト、ビュー、ダッシュボードの追加や、既存部分の調整ができます。", }, }, clearConversation: "クリア", diff --git a/packages/i18n/src/locales/ko.ts b/packages/i18n/src/locales/ko.ts index 0fe88a663..3dfffaa3d 100644 --- a/packages/i18n/src/locales/ko.ts +++ b/packages/i18n/src/locales/ko.ts @@ -1567,7 +1567,7 @@ const ko = { empty: { build: { title: "AI로 빌드", - description: "앱이나 워크플로를 일상 언어로 설명해 주세요 — 객체, 화면, 자동화를 초안으로 만들어 드리면 검토 후 게시하시면 됩니다.", + description: "앱을 일상 언어로 설명해 주세요 — 객체, 화면, 샘플 데이터를 초안으로 만들어 드리면 검토 후 게시하시면 됩니다.", }, ask: { title: "데이터에 질문하기", @@ -1576,7 +1576,7 @@ const ko = { editApp: { title: "“{{app}}” 편집 중", titleGeneric: "이 앱 편집", - description: "무엇을 바꿀까요? 이 앱을 그 자리에서 수정합니다 — 필드, 객체, 뷰, 자동화를 추가하거나 기존 내용을 조정할 수 있습니다.", + description: "무엇을 바꿀까요? 이 앱을 그 자리에서 수정합니다 — 필드, 객체, 뷰, 대시보드를 추가하거나 기존 내용을 조정할 수 있습니다.", }, }, clearConversation: "지우기", diff --git a/packages/i18n/src/locales/pt.ts b/packages/i18n/src/locales/pt.ts index f22cdfaad..576916869 100644 --- a/packages/i18n/src/locales/pt.ts +++ b/packages/i18n/src/locales/pt.ts @@ -1566,7 +1566,7 @@ const pt = { empty: { build: { title: "Criar com IA", - description: "Descreva um aplicativo ou fluxo de trabalho em linguagem simples — eu rascunho os objetos, telas e automações, e então você revisa e publica.", + description: "Descreva um aplicativo em linguagem simples — eu rascunho os objetos, telas e dados de exemplo, e então você revisa e publica.", }, ask: { title: "Pergunte aos seus dados", @@ -1575,7 +1575,7 @@ const pt = { editApp: { title: "Editando “{{app}}”", titleGeneric: "Editar este aplicativo", - description: "O que você quer mudar? Eu altero este aplicativo no lugar — adicionar um campo, objeto, visão ou automação, ou ajustar o que já existe.", + description: "O que você quer mudar? Eu altero este aplicativo no lugar — adicionar um campo, objeto, visão ou painel, ou ajustar o que já existe.", }, }, clearConversation: "Limpar", diff --git a/packages/i18n/src/locales/ru.ts b/packages/i18n/src/locales/ru.ts index 2e94010e1..566e884e0 100644 --- a/packages/i18n/src/locales/ru.ts +++ b/packages/i18n/src/locales/ru.ts @@ -1579,7 +1579,7 @@ const ru = { empty: { build: { title: "Создать с помощью ИИ", - description: "Опишите приложение или процесс обычными словами — я подготовлю объекты, экраны и автоматизации, а вы проверите и опубликуете.", + description: "Опишите приложение обычными словами — я подготовлю объекты, экраны и демонстрационные данные, а вы проверите и опубликуете.", }, ask: { title: "Спросите свои данные", @@ -1588,7 +1588,7 @@ const ru = { editApp: { title: "Редактирование «{{app}}»", titleGeneric: "Редактировать это приложение", - description: "Что нужно изменить? Я изменю это приложение на месте — добавлю поле, объект, представление или автоматизацию либо скорректирую существующее.", + description: "Что нужно изменить? Я изменю это приложение на месте — добавлю поле, объект, представление или дашборд либо скорректирую существующее.", }, }, clearConversation: "Очистить", diff --git a/packages/i18n/src/locales/zh.ts b/packages/i18n/src/locales/zh.ts index ecc37648a..425d0e6f6 100644 --- a/packages/i18n/src/locales/zh.ts +++ b/packages/i18n/src/locales/zh.ts @@ -1727,7 +1727,7 @@ const zh = { empty: { build: { title: '用 AI 搭建', - description: '用自然语言描述一个应用或流程 —— 我会起草对象、界面和自动化,随后你审阅并发布。', + description: '用自然语言描述一个应用 —— 我会起草对象、界面和示例数据,随后你审阅并发布。', }, ask: { title: '向你的数据提问', @@ -1736,7 +1736,7 @@ const zh = { editApp: { title: '正在编辑「{{app}}」', titleGeneric: '编辑此应用', - description: '想改点什么?我会就地修改这个应用 —— 加字段、对象、视图或自动化,或调整已有内容。', + description: '想改点什么?我会就地修改这个应用 —— 加字段、对象、视图或仪表盘,或调整已有内容。', }, }, clearConversation: '清空',