FN-6890: rename documents navigation to artifacts
Rename the user-facing Documents destination to Artifacts across dashboard navigation. - Update header, sidebar, mobile, right-dock, and view title labels to say Artifacts while preserving the existing documents route identifiers. - Refresh localized app strings and generated i18n types for the renamed label. - Adjust dashboard and i18n coverage tests to assert the Artifacts label across navigation surfaces. Files changed: docs/dashboard-guide.md | 10 ++--- .../app/__tests__/tablet-header-controls.test.tsx | 12 +++--- .../dashboard/app/components/DocumentsView.tsx | 3 +- packages/dashboard/app/components/Header.tsx | 10 +++-- .../dashboard/app/components/LeftSidebarNav.tsx | 6 ++- packages/dashboard/app/components/MobileNavBar.tsx | 3 +- .../components/__tests__/DocumentsView.test.tsx | 1 + .../app/components/__tests__/Header.test.tsx | 10 ++--- .../components/__tests__/LeftSidebarNav.test.tsx | 2 + .../app/components/__tests__/MobileNavBar.test.tsx | 11 ++++++ .../app/components/__tests__/RightDock.test.tsx | 3 +- .../__tests__/overflowViewRegistry.test.tsx | 6 ++- .../app/components/overflowViewRegistry.tsx | 6 ++- packages/i18n/locales/en/app.json | 6 +-- packages/i18n/locales/es/app.json | 6 +-- packages/i18n/locales/fr/app.json | 6 +-- packages/i18n/locales/ko/app.json | 6 +-- packages/i18n/locales/zh-CN/app.json | 6 +-- packages/i18n/locales/zh-TW/app.json | 6 +-- .../i18n/src/__tests__/i18n-gate-coverage.test.ts | 24 ++++++++++++ packages/i18n/src/resources.d.ts | 45 +++++++++++++++++++--- 21 files changed, 139 insertions(+), 49 deletions(-) Fusion-Task-Id: FN-6890 Fusion-Task-Lineage: 7a50dc24-3278-4cdf-8e4c-fd8cc5c3c40d
This commit is contained in:
@@ -23,7 +23,7 @@ Task Detail modal opens from onboarding, activity log, and task-to-task navigati
|
||||
|
||||
**Left Sidebar Navigation** is enabled by default for desktop/tablet project screens, moving project navigation out of the Header and into a persistent left sidebar. To opt out, open **Settings → Experimental Features** and turn **Left Sidebar Navigation** off (`leftSidebarNav: false`).
|
||||
|
||||
When enabled on desktop or tablet project screens, the sidebar contains the primary destinations (Board, List, Agents, Command Center, Missions, Chat, Documents, Mailbox, and plugin primary views), selected auxiliary destinations as regular entries (Research, Insights, Skills, Memory, Stash Recovery, Evals, Goals, Dev Server, and plugin overflow views when their flags/plugins are enabled), and a footer with the collapse toggle directly above the Settings button. Secrets and Todos are intentionally not listed in the left sidebar; use the Right Dock for those auxiliary views on desktop/tablet. The Header retains the Fusion brand and project selector, keeps its non-navigation controls, and hides the view-toggle row and **More views** trigger so there is only one canonical primary navigation surface.
|
||||
When enabled on desktop or tablet project screens, the sidebar contains the primary destinations (Board, List, Agents, Command Center, Missions, Chat, Artifacts, Mailbox, and plugin primary views), selected auxiliary destinations as regular entries (Research, Insights, Skills, Memory, Stash Recovery, Evals, Goals, Dev Server, and plugin overflow views when their flags/plugins are enabled), and a footer with the collapse toggle directly above the Settings button. Secrets and Todos are intentionally not listed in the left sidebar; use the Right Dock for those auxiliary views on desktop/tablet. The Header retains the Fusion brand and project selector, keeps its non-navigation controls, and hides the view-toggle row and **More views** trigger so there is only one canonical primary navigation surface.
|
||||
|
||||
While the sidebar is active on desktop/tablet project screens, Board and List workflow controls move into the Header slot that replaces the hidden view toggle. Board and List share one workflow dropdown: each workflow row includes an inline edit action, and a persistent **New workflow** action remains at the bottom of the dropdown while the workflow list scrolls. The standalone workflow row above the board/list content is removed in this mode. When the flag is off, outside project screens, or on mobile, workflow controls remain inline with the same consolidated dropdown.
|
||||
|
||||
@@ -471,9 +471,9 @@ You may also see matching run-audit events in logs, including `pull:fast-forward
|
||||
Goal run-audit metadata is IDs-only (`goalIds` + counts/tool fields) and never includes goal titles/descriptions/prompt text.
|
||||
For per-run aggregation, `GET /api/agents/:id/runs/:runId/cited-goals` returns `{ runId, taskId?, injectedGoalIds, retrievedGoalIds, citedGoalIds }`.
|
||||
|
||||
## Documents View
|
||||
## Artifacts View
|
||||
|
||||
Documents view aggregates task documents, project markdown files, and registered artifacts.
|
||||
Artifacts view aggregates task documents, project markdown files, and registered artifacts.
|
||||
|
||||
Features:
|
||||
|
||||
@@ -486,7 +486,7 @@ Features:
|
||||
- Toggle between raw text and rendered markdown using the **Markdown/Plain** button
|
||||
- Highlight text in raw or rendered project-file previews, choose **Add comment**, and send the file path, selected snippet, and your comment to the **New Task** dialog
|
||||
|
||||

|
||||

|
||||
|
||||
## Reports View
|
||||
|
||||
@@ -508,7 +508,7 @@ For plugin internals (registration, API routes, rendering/export pipeline), see
|
||||
|
||||
### Markdown Rendering
|
||||
|
||||
Documents view supports toggling between raw text and formatted markdown when viewing document content:
|
||||
Artifacts view supports toggling between raw text and formatted markdown when viewing document content:
|
||||
|
||||
- **Raw mode** (default): Shows markdown syntax as plain text (e.g., `**bold**`)
|
||||
- **Markdown mode**: Renders markdown with proper formatting (e.g., **bold**, headings, lists, tables)
|
||||
|
||||
@@ -88,28 +88,28 @@ describe("tablet header controls", () => {
|
||||
expect(screen.getByTitle("List view")).toBeDefined();
|
||||
expect(screen.getByTitle("Agents view")).toBeDefined();
|
||||
expect(screen.getByTestId("view-toggle-command-center")).toBeDefined();
|
||||
expect(screen.queryByTitle("Documents view")).toBeNull();
|
||||
expect(screen.queryByTitle("Artifacts view")).toBeNull();
|
||||
// Skills and Insights are NOT inline (they're in overflow)
|
||||
expect(screen.queryByTitle("Skills view")).toBeNull();
|
||||
expect(screen.queryByTitle("Roadmaps view")).toBeNull();
|
||||
expect(screen.queryByTitle("Insights view")).toBeNull();
|
||||
});
|
||||
|
||||
it("places tablet Command Center inline immediately after Agents and Documents only in overflow", () => {
|
||||
it("places tablet Command Center inline immediately after Agents and Artifacts only in overflow", () => {
|
||||
renderTabletHeader({ onChangeView: noop, showAgentsTab: true });
|
||||
|
||||
expect(screen.getByTestId("view-toggle-command-center").previousElementSibling).toBe(screen.getByTitle("Agents view"));
|
||||
expect(screen.queryByTitle("Documents view")).toBeNull();
|
||||
expect(screen.queryByTitle("Artifacts view")).toBeNull();
|
||||
|
||||
fireEvent.click(screen.getByTestId("view-toggle-overflow-trigger"));
|
||||
expect(screen.getByTestId("view-overflow-documents")).toBeDefined();
|
||||
expect(screen.getByTestId("view-overflow-documents")).toHaveTextContent("Artifacts view");
|
||||
expect(screen.queryByTestId("view-overflow-command-center")).toBeNull();
|
||||
});
|
||||
|
||||
it("keeps desktop Documents and Command Center inline without Command Center overflow", () => {
|
||||
it("keeps desktop Artifacts and Command Center inline without Command Center overflow", () => {
|
||||
renderDesktopHeader({ onChangeView: noop, showAgentsTab: true });
|
||||
|
||||
expect(screen.getByTitle("Documents view")).toBeDefined();
|
||||
expect(screen.getByTitle("Artifacts view")).toBeDefined();
|
||||
expect(screen.getByTestId("view-toggle-command-center")).toBeDefined();
|
||||
expect(screen.getByTestId("view-toggle-command-center").previousElementSibling).toBe(screen.getByTitle("Agents view"));
|
||||
|
||||
|
||||
@@ -507,7 +507,8 @@ export function DocumentsView({ projectId, addToast, onOpenDetail, onSendSelecti
|
||||
<div className="documents-view-title-row">
|
||||
<h2 className="documents-view-title">
|
||||
<FileText size={20} />
|
||||
{t("documents.title", "Documents")}
|
||||
{/* FNXC:Navigation 2026-06-21-18:25: FN-6890 renames the top-level Documents view header to Artifacts without changing internal task-document tabs or artifact sub-tabs. */}
|
||||
{t("documents.title", "Artifacts")}
|
||||
</h2>
|
||||
<span className="documents-view-count">
|
||||
{t("documents.resultCount", "{{count}} result{{plural}}", { count: activeCount, plural: activeCount !== 1 ? "s" : "" })}
|
||||
|
||||
@@ -1061,11 +1061,15 @@ export function Header({
|
||||
)}
|
||||
</button>
|
||||
{!isTablet && (
|
||||
/*
|
||||
FNXC:Navigation 2026-06-21-18:25:
|
||||
The top-level documents destination now displays as Artifacts (FN-6890), but the documents route id remains stable for navigation and tests.
|
||||
*/
|
||||
<button
|
||||
className={`view-toggle-btn${view === "documents" ? " active" : ""}`}
|
||||
onClick={() => onChangeView("documents")}
|
||||
title={t("header.documentsView", "Documents view")}
|
||||
aria-label={t("header.documentsView", "Documents view")}
|
||||
title={t("header.documentsView", "Artifacts view")}
|
||||
aria-label={t("header.documentsView", "Artifacts view")}
|
||||
aria-pressed={view === "documents"}
|
||||
>
|
||||
<FileText size={16} />
|
||||
@@ -1263,7 +1267,7 @@ export function Header({
|
||||
data-testid="view-overflow-documents"
|
||||
>
|
||||
<FileText size={14} />
|
||||
<span>{t("header.documentsView", "Documents view")}</span>
|
||||
<span>{t("header.documentsView", "Artifacts view")}</span>
|
||||
</button>
|
||||
)}
|
||||
{experimentalFeatures?.devServerView && (
|
||||
|
||||
@@ -288,7 +288,11 @@ export function LeftSidebarNav({
|
||||
},
|
||||
{
|
||||
id: "documents",
|
||||
label: t("nav.documents", "Documents"),
|
||||
/*
|
||||
FNXC:Navigation 2026-06-21-18:25:
|
||||
FN-6890 renames the top-level Documents label to Artifacts while preserving the documents view id and sidebar-nav-documents test id.
|
||||
*/
|
||||
label: t("nav.documents", "Artifacts"),
|
||||
view: "documents",
|
||||
isActive: view === "documents",
|
||||
icon: FileText,
|
||||
|
||||
@@ -670,7 +670,8 @@ export function MobileNavBar({
|
||||
onClick={() => handleMoreAction(() => onChangeView("documents"))}
|
||||
>
|
||||
<FileText />
|
||||
<span>{t("nav.documents", "Documents")}</span>
|
||||
{/* FNXC:Navigation 2026-06-21-18:25: FN-6890 changes only the displayed top-level label to Artifacts; mobile-more-item-documents and the documents view id stay stable. */}
|
||||
<span>{t("nav.documents", "Artifacts")}</span>
|
||||
</button>
|
||||
|
||||
{experimentalFeatures?.evalsView && (
|
||||
|
||||
@@ -215,6 +215,7 @@ describe("DocumentsView", () => {
|
||||
it("renders project files tab with markdown file list", () => {
|
||||
render(<DocumentsView addToast={addToast} onOpenDetail={onOpenDetail} />);
|
||||
|
||||
expect(screen.getByRole("heading", { name: "Artifacts" })).toBeInTheDocument();
|
||||
expect(screen.getByRole("tab", { name: /show project markdown files/i })).toHaveAttribute("aria-selected", "true");
|
||||
expect(screen.getByRole("button", { name: "Open README.md" })).toBeInTheDocument();
|
||||
expect(screen.getByRole("button", { name: "Open docs/guide.md" })).toBeInTheDocument();
|
||||
|
||||
@@ -386,10 +386,10 @@ describe("Header", () => {
|
||||
expect(screen.getByTestId("view-toggle-overflow-trigger")).toBeDefined();
|
||||
});
|
||||
|
||||
it("keeps desktop Documents and Command Center inline without Command Center overflow", () => {
|
||||
it("keeps desktop Artifacts and Command Center inline without Command Center overflow", () => {
|
||||
renderHeader({ onChangeView: noop, showAgentsTab: true }, "desktop");
|
||||
|
||||
expect(screen.getByTitle("Documents view")).toBeInTheDocument();
|
||||
expect(screen.getByTitle("Artifacts view")).toBeInTheDocument();
|
||||
const agentsButton = screen.getByTitle("Agents view");
|
||||
const commandCenterButton = screen.getByTestId("view-toggle-command-center");
|
||||
expect(commandCenterButton.previousElementSibling).toBe(agentsButton);
|
||||
@@ -399,16 +399,16 @@ describe("Header", () => {
|
||||
expect(screen.queryByTestId("view-overflow-documents")).toBeNull();
|
||||
});
|
||||
|
||||
it("promotes Command Center after Agents and moves Documents to overflow on tablet", () => {
|
||||
it("promotes Command Center after Agents and moves Artifacts to overflow on tablet", () => {
|
||||
renderHeader({ onChangeView: noop, showAgentsTab: true }, "tablet");
|
||||
|
||||
const agentsButton = screen.getByTitle("Agents view");
|
||||
const commandCenterButton = screen.getByTestId("view-toggle-command-center");
|
||||
expect(commandCenterButton.previousElementSibling).toBe(agentsButton);
|
||||
expect(screen.queryByTitle("Documents view")).toBeNull();
|
||||
expect(screen.queryByTitle("Artifacts view")).toBeNull();
|
||||
|
||||
fireEvent.click(screen.getByTestId("view-toggle-overflow-trigger"));
|
||||
expect(screen.getByTestId("view-overflow-documents")).toBeInTheDocument();
|
||||
expect(screen.getByTestId("view-overflow-documents")).toHaveTextContent("Artifacts view");
|
||||
expect(screen.queryByTestId("view-overflow-command-center")).toBeNull();
|
||||
});
|
||||
|
||||
|
||||
@@ -147,6 +147,8 @@ describe("LeftSidebarNav", () => {
|
||||
expect(screen.getByTestId(testId)).toBeDefined();
|
||||
}
|
||||
|
||||
expect(screen.getByTestId("sidebar-nav-documents")).toHaveTextContent("Artifacts");
|
||||
|
||||
const sidebar = screen.getByTestId("left-sidebar-nav");
|
||||
const footer = screen.getByTestId("sidebar-nav-settings").closest(".left-sidebar-nav__footer");
|
||||
expect(footer).not.toBeNull();
|
||||
|
||||
@@ -272,6 +272,17 @@ describe("MobileNavBar", () => {
|
||||
expect(screen.getByTestId("mobile-nav-tab-more")).toHaveClass("mobile-nav-tab--active");
|
||||
});
|
||||
|
||||
it("shows Artifacts in More and routes to the stable documents view", () => {
|
||||
const props = createDefaultProps();
|
||||
render(<MobileNavBar {...props} />);
|
||||
|
||||
fireEvent.click(screen.getByTestId("mobile-nav-tab-more"));
|
||||
expect(screen.getByTestId("mobile-more-item-documents")).toHaveTextContent("Artifacts");
|
||||
fireEvent.click(screen.getByTestId("mobile-more-item-documents"));
|
||||
|
||||
expect(props.onChangeView).toHaveBeenCalledWith("documents");
|
||||
});
|
||||
|
||||
it("shows secrets in More and routes to secrets view", () => {
|
||||
const props = createDefaultProps();
|
||||
render(<MobileNavBar {...props} />);
|
||||
|
||||
@@ -77,7 +77,8 @@ describe("RightDock", () => {
|
||||
);
|
||||
|
||||
expect(screen.getByTestId("right-dock-tab-files")).toBeInTheDocument();
|
||||
expect(screen.getByTestId("right-dock-tab-documents")).toBeInTheDocument();
|
||||
expect(screen.getByTestId("right-dock-tab-documents")).toHaveAttribute("aria-label", "Artifacts");
|
||||
expect(screen.getByTestId("right-dock-tab-documents")).toHaveAttribute("title", "Artifacts");
|
||||
expect(screen.getByTestId("right-dock-tab-secrets")).toBeInTheDocument();
|
||||
expect(screen.getByTestId("right-dock-tab-stash-recovery")).toBeInTheDocument();
|
||||
expect(screen.queryByTestId("right-dock-tab-research")).toBeNull();
|
||||
|
||||
@@ -3,10 +3,12 @@ import { getVisibleOverflowViewEntries, STATIC_OVERFLOW_VIEW_ENTRIES } from "../
|
||||
import type { PluginDashboardViewEntry } from "../../api";
|
||||
|
||||
describe("overflowViewRegistry", () => {
|
||||
it("keeps Files as the default first entry and Documents visible without a viewport gate", () => {
|
||||
it("keeps Files as the default first entry and Artifacts visible without a viewport gate", () => {
|
||||
const entries = getVisibleOverflowViewEntries();
|
||||
expect(entries[0]?.key).toBe("files");
|
||||
expect(entries.some((entry) => entry.key === "documents")).toBe(true);
|
||||
const documentsEntry = entries.find((entry) => entry.key === "documents");
|
||||
expect(documentsEntry?.label).toBe("Artifacts");
|
||||
expect(documentsEntry?.testId).toBe("right-dock-tab-documents");
|
||||
});
|
||||
|
||||
it("matches Header feature gates for flag-controlled overflow destinations", () => {
|
||||
|
||||
@@ -140,7 +140,11 @@ export const STATIC_OVERFLOW_VIEW_ENTRIES: readonly OverflowViewEntry[] = [
|
||||
},
|
||||
{
|
||||
key: "documents",
|
||||
label: "Documents",
|
||||
/*
|
||||
FNXC:Navigation 2026-06-21-18:25:
|
||||
Top-level Documents was renamed to Artifacts for FN-6890; keep the documents key, route, and test id stable while changing only the displayed label.
|
||||
*/
|
||||
label: "Artifacts",
|
||||
icon: FileText,
|
||||
testId: "right-dock-tab-documents",
|
||||
render: (props) => wrapOverflowView(
|
||||
|
||||
@@ -2192,7 +2192,7 @@
|
||||
"switchToPlainText": "Switch to plain text",
|
||||
"taskDocuments": "task documents",
|
||||
"taskDocumentsTab": "Task Documents",
|
||||
"title": "Documents",
|
||||
"title": "Artifacts",
|
||||
"untitled": "Untitled",
|
||||
"artifacts": "artifacts",
|
||||
"artifactsCreatedBy": "Artifacts are created by agents, users, and system tools.",
|
||||
@@ -2857,7 +2857,7 @@
|
||||
"commandCenterView": "Command Center",
|
||||
"createTaskWithPlanning": "Create a task with AI planning",
|
||||
"devServerView": "Dev Server",
|
||||
"documentsView": "Documents view",
|
||||
"documentsView": "Artifacts view",
|
||||
"engineOptions": "Engine options",
|
||||
"evalsView": "Evals",
|
||||
"fusionLogo": "Fusion logo",
|
||||
@@ -3934,7 +3934,7 @@
|
||||
"collapseSidebar": "Collapse sidebar",
|
||||
"commandCenter": "Command Center",
|
||||
"devServer": "Dev Server",
|
||||
"documents": "Documents",
|
||||
"documents": "Artifacts",
|
||||
"evals": "Evals",
|
||||
"expandSidebar": "Expand sidebar",
|
||||
"files": "Files",
|
||||
|
||||
@@ -2192,7 +2192,7 @@
|
||||
"switchToPlainText": "Cambiar a texto sin formato",
|
||||
"taskDocuments": "documentos de tareas",
|
||||
"taskDocumentsTab": "Documentos de tareas",
|
||||
"title": "Documentos",
|
||||
"title": "Artefactos",
|
||||
"untitled": "Sin título",
|
||||
"artifacts": "artifacts",
|
||||
"artifactsCreatedBy": "Artifacts are created by agents, users, and system tools.",
|
||||
@@ -2857,7 +2857,7 @@
|
||||
"commandCenterView": "",
|
||||
"createTaskWithPlanning": "Crear tarea con planificación IA",
|
||||
"devServerView": "Servidor de desarrollo",
|
||||
"documentsView": "Vista documentos",
|
||||
"documentsView": "Vista de artefactos",
|
||||
"engineOptions": "Opciones del motor",
|
||||
"evalsView": "Evaluaciones",
|
||||
"fusionLogo": "",
|
||||
@@ -3934,7 +3934,7 @@
|
||||
"collapseSidebar": "",
|
||||
"commandCenter": "",
|
||||
"devServer": "Servidor de desarrollo",
|
||||
"documents": "Documentos",
|
||||
"documents": "Artefactos",
|
||||
"evals": "Evaluaciones",
|
||||
"expandSidebar": "",
|
||||
"files": "Archivos",
|
||||
|
||||
@@ -2192,7 +2192,7 @@
|
||||
"switchToPlainText": "Passer en texte brut",
|
||||
"taskDocuments": "documents des tâches",
|
||||
"taskDocumentsTab": "Documents des tâches",
|
||||
"title": "Documents",
|
||||
"title": "Artefacts",
|
||||
"untitled": "Sans titre",
|
||||
"artifacts": "artifacts",
|
||||
"artifactsCreatedBy": "Artifacts are created by agents, users, and system tools.",
|
||||
@@ -2857,7 +2857,7 @@
|
||||
"commandCenterView": "",
|
||||
"createTaskWithPlanning": "Créer une tâche avec la planification IA",
|
||||
"devServerView": "Serveur de développement",
|
||||
"documentsView": "Vue documents",
|
||||
"documentsView": "Vue des artefacts",
|
||||
"engineOptions": "Options du moteur",
|
||||
"evalsView": "Évaluations",
|
||||
"fusionLogo": "",
|
||||
@@ -3934,7 +3934,7 @@
|
||||
"collapseSidebar": "",
|
||||
"commandCenter": "",
|
||||
"devServer": "Serveur de dev",
|
||||
"documents": "Documents",
|
||||
"documents": "Artefacts",
|
||||
"evals": "Évaluations",
|
||||
"expandSidebar": "",
|
||||
"files": "Fichiers",
|
||||
|
||||
@@ -2192,7 +2192,7 @@
|
||||
"switchToPlainText": "일반 텍스트로 전환",
|
||||
"taskDocuments": "작업 문서",
|
||||
"taskDocumentsTab": "작업 문서",
|
||||
"title": "문서",
|
||||
"title": "아티팩트",
|
||||
"untitled": "제목 없음",
|
||||
"artifacts": "artifacts",
|
||||
"artifactsCreatedBy": "Artifacts are created by agents, users, and system tools.",
|
||||
@@ -2857,7 +2857,7 @@
|
||||
"commandCenterView": "",
|
||||
"createTaskWithPlanning": "AI 계획으로 작업 생성",
|
||||
"devServerView": "개발 서버",
|
||||
"documentsView": "문서 보기",
|
||||
"documentsView": "아티팩트 보기",
|
||||
"engineOptions": "엔진 옵션",
|
||||
"evalsView": "평가",
|
||||
"fusionLogo": "",
|
||||
@@ -3934,7 +3934,7 @@
|
||||
"collapseSidebar": "",
|
||||
"commandCenter": "",
|
||||
"devServer": "개발 서버",
|
||||
"documents": "문서",
|
||||
"documents": "아티팩트",
|
||||
"evals": "평가",
|
||||
"expandSidebar": "",
|
||||
"files": "파일",
|
||||
|
||||
@@ -2192,7 +2192,7 @@
|
||||
"switchToPlainText": "切换到纯文本",
|
||||
"taskDocuments": "任务文档",
|
||||
"taskDocumentsTab": "任务文档",
|
||||
"title": "文档",
|
||||
"title": "制品",
|
||||
"untitled": "未命名",
|
||||
"artifacts": "artifacts",
|
||||
"artifactsCreatedBy": "Artifacts are created by agents, users, and system tools.",
|
||||
@@ -2857,7 +2857,7 @@
|
||||
"commandCenterView": "",
|
||||
"createTaskWithPlanning": "使用 AI 规划创建任务",
|
||||
"devServerView": "开发服务器",
|
||||
"documentsView": "文档视图",
|
||||
"documentsView": "制品视图",
|
||||
"engineOptions": "引擎选项",
|
||||
"evalsView": "评估",
|
||||
"fusionLogo": "",
|
||||
@@ -3934,7 +3934,7 @@
|
||||
"collapseSidebar": "",
|
||||
"commandCenter": "",
|
||||
"devServer": "开发服务器",
|
||||
"documents": "文档",
|
||||
"documents": "制品",
|
||||
"evals": "评估",
|
||||
"expandSidebar": "",
|
||||
"files": "文件",
|
||||
|
||||
@@ -2192,7 +2192,7 @@
|
||||
"switchToPlainText": "切換至純文字",
|
||||
"taskDocuments": "工作文件",
|
||||
"taskDocumentsTab": "工作文件",
|
||||
"title": "文件",
|
||||
"title": "產物",
|
||||
"untitled": "未命名",
|
||||
"artifacts": "artifacts",
|
||||
"artifactsCreatedBy": "Artifacts are created by agents, users, and system tools.",
|
||||
@@ -2857,7 +2857,7 @@
|
||||
"commandCenterView": "",
|
||||
"createTaskWithPlanning": "使用 AI 規劃建立任務",
|
||||
"devServerView": "開發伺服器",
|
||||
"documentsView": "文件檢視",
|
||||
"documentsView": "產物檢視",
|
||||
"engineOptions": "引擎選項",
|
||||
"evalsView": "評估",
|
||||
"fusionLogo": "",
|
||||
@@ -3934,7 +3934,7 @@
|
||||
"collapseSidebar": "",
|
||||
"commandCenter": "",
|
||||
"devServer": "開發伺服器",
|
||||
"documents": "文件",
|
||||
"documents": "產物",
|
||||
"evals": "評估",
|
||||
"expandSidebar": "",
|
||||
"files": "檔案",
|
||||
|
||||
@@ -42,6 +42,16 @@ function readCatalogs(locale: Locale): NamespaceCatalogs {
|
||||
return Object.fromEntries(namespaces.all.map((namespace) => [namespace, readCatalog(locale, namespace)]));
|
||||
}
|
||||
|
||||
function getStringAtPath(catalog: CatalogObject, path: string): string | undefined {
|
||||
const value = path.split(".").reduce<unknown>((current, part) => {
|
||||
if (current && typeof current === "object" && part in current) {
|
||||
return (current as Record<string, unknown>)[part];
|
||||
}
|
||||
return undefined;
|
||||
}, catalog);
|
||||
return typeof value === "string" ? value : undefined;
|
||||
}
|
||||
|
||||
describe("i18n gate regression coverage", () => {
|
||||
it("keeps dashboard source files under the hardcoded-string lint gate", () => {
|
||||
expect(config.lint?.ignore).toEqual(expectedNonShippingLintIgnores);
|
||||
@@ -62,4 +72,18 @@ describe("i18n gate regression coverage", () => {
|
||||
expect(findParityViolations(enCatalogs, readCatalogs(locale), { locale })).toEqual([]);
|
||||
}
|
||||
});
|
||||
|
||||
it("keeps the top-level documents destination renamed to Artifacts while preserving keys", () => {
|
||||
const enApp = readCatalog("en", "app");
|
||||
expect(getStringAtPath(enApp, "nav.documents")).toBe("Artifacts");
|
||||
expect(getStringAtPath(enApp, "documents.title")).toBe("Artifacts");
|
||||
expect(getStringAtPath(enApp, "header.documentsView")).toBe("Artifacts view");
|
||||
|
||||
for (const locale of SUPPORTED_LOCALES) {
|
||||
const app = readCatalog(locale, "app");
|
||||
for (const keyPath of ["nav.documents", "documents.title", "header.documentsView"]) {
|
||||
expect(getStringAtPath(app, keyPath), `${locale} app.${keyPath}`).toBeTruthy();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
45
packages/i18n/src/resources.d.ts
vendored
45
packages/i18n/src/resources.d.ts
vendored
@@ -2149,6 +2149,17 @@ export default interface Resources {
|
||||
"viewNode": "View Node"
|
||||
},
|
||||
"documents": {
|
||||
"artifactAudioLabel": "Audio artifact: {{title}}",
|
||||
"artifactCardLabel": "Artifact {{title}}",
|
||||
"artifactTypeAudio": "Audio",
|
||||
"artifactTypeDocument": "Document",
|
||||
"artifactTypeImage": "Image",
|
||||
"artifactTypeOther": "Other",
|
||||
"artifactTypeVideo": "Video",
|
||||
"artifactVideoLabel": "Video artifact: {{title}}",
|
||||
"artifacts": "artifacts",
|
||||
"artifactsCreatedBy": "Artifacts are created by agents, users, and system tools.",
|
||||
"artifactsTab": "Artifacts",
|
||||
"backToFiles": "Back to files",
|
||||
"backToFilesList": "Back to project files list",
|
||||
"clearSearch": "Clear search",
|
||||
@@ -2163,15 +2174,21 @@ export default interface Resources {
|
||||
"hideHidden": "Hide hidden project files",
|
||||
"hideHiddenFiles": "Hide hidden files",
|
||||
"hideHiddenLabel": "Hide Hidden",
|
||||
"loadingArtifacts": "Loading artifacts…",
|
||||
"loadingFileContent": "Loading file content…",
|
||||
"loadingProjectFiles": "Loading project markdown files…",
|
||||
"loadingTaskDocuments": "Loading task documents…",
|
||||
"markdown": "Markdown",
|
||||
"noArtifactPreview": "No preview available.",
|
||||
"noArtifacts": "No artifacts yet.",
|
||||
"noMarkdownFiles": "No Markdown files found in this project.",
|
||||
"noMatchArtifacts": "No artifacts match \"{{query}}\".",
|
||||
"noMatchProject": "No project markdown files match \"{{query}}\".",
|
||||
"noMatchTask": "No task documents match \"{{query}}\".",
|
||||
"noTaskDocuments": "No task documents yet.",
|
||||
"openArtifactMedia": "Open artifact media",
|
||||
"openTask": "Open task",
|
||||
"openTaskAria": "Open task {{taskId}}: {{title}}",
|
||||
"plain": "Plain",
|
||||
"projectFilePreviewLabel": "Project file content preview",
|
||||
"projectFiles": "project files",
|
||||
@@ -2181,10 +2198,12 @@ export default interface Resources {
|
||||
"resultCount_other": "{{count}} result{{plural}}",
|
||||
"retry": "Retry",
|
||||
"retryLoading": "Retry loading documents",
|
||||
"searchArtifacts": "Search artifacts…",
|
||||
"searchProjectFiles": "Search project markdown files…",
|
||||
"searchTaskDocuments": "Search task documents…",
|
||||
"sectionsLabel": "Documents sections",
|
||||
"selectFile": "Select a Markdown file to view its content.",
|
||||
"showArtifacts": "Show artifacts",
|
||||
"showHidden": "Show hidden project files",
|
||||
"showHiddenFiles": "Show hidden files",
|
||||
"showHiddenLabel": "Show Hidden",
|
||||
@@ -2194,8 +2213,9 @@ export default interface Resources {
|
||||
"switchToPlainText": "Switch to plain text",
|
||||
"taskDocuments": "task documents",
|
||||
"taskDocumentsTab": "Task Documents",
|
||||
"title": "Documents",
|
||||
"untitled": "Untitled"
|
||||
"title": "Artifacts",
|
||||
"untitled": "Untitled",
|
||||
"untitledArtifact": "Untitled artifact"
|
||||
},
|
||||
"droidCli": {
|
||||
"active": "Active",
|
||||
@@ -2267,6 +2287,7 @@ export default interface Resources {
|
||||
"connecting": "Connecting…",
|
||||
"daysAgo_one": "{{count}}d ago",
|
||||
"daysAgo_other": "{{count}}d ago",
|
||||
"engineControls": "Engine controls",
|
||||
"escalated": "Escalated",
|
||||
"escalatedSuffix": " (escalated)",
|
||||
"hideProjectDir": "Hide project directory",
|
||||
@@ -2278,6 +2299,7 @@ export default interface Resources {
|
||||
"minutesAgo_one": "{{count}}m ago",
|
||||
"minutesAgo_other": "{{count}}m ago",
|
||||
"noActivity": "no activity",
|
||||
"openEngineControlsForState": "Open engine controls for {{state}} state",
|
||||
"overlapBottleneck_one": "{{status}} overlap bottleneck {{blockerId}}: {{count}} todo blocked via blockedBy (threshold {{threshold}})",
|
||||
"overlapBottleneck_other": "{{status}} overlap bottleneck {{blockerId}}: {{count}} todo blocked via blockedBy (threshold {{threshold}})",
|
||||
"overlapQueue": "Overlap queue",
|
||||
@@ -2294,7 +2316,8 @@ export default interface Resources {
|
||||
"status": "Executor status",
|
||||
"stuck": "Stuck",
|
||||
"temporary": "Temporary",
|
||||
"todoStatus": "todo"
|
||||
"todoStatus": "todo",
|
||||
"triageDisabledWhileStopped": "Start the AI engine before changing triage scheduling"
|
||||
},
|
||||
"fileBrowser": {
|
||||
"back": "Back to file list",
|
||||
@@ -2836,7 +2859,7 @@ export default interface Resources {
|
||||
"commandCenterView": "Command Center",
|
||||
"createTaskWithPlanning": "Create a task with AI planning",
|
||||
"devServerView": "Dev Server",
|
||||
"documentsView": "Documents view",
|
||||
"documentsView": "Artifacts view",
|
||||
"engineOptions": "Engine options",
|
||||
"evalsView": "Evals",
|
||||
"fusionLogo": "Fusion logo",
|
||||
@@ -3913,7 +3936,7 @@ export default interface Resources {
|
||||
"collapseSidebar": "Collapse sidebar",
|
||||
"commandCenter": "Command Center",
|
||||
"devServer": "Dev Server",
|
||||
"documents": "Documents",
|
||||
"documents": "Artifacts",
|
||||
"evals": "Evals",
|
||||
"expandSidebar": "Expand sidebar",
|
||||
"files": "Files",
|
||||
@@ -6961,6 +6984,10 @@ export default interface Resources {
|
||||
"resultSuccess": "Success"
|
||||
},
|
||||
"systemStats": {
|
||||
"agentActive": "active",
|
||||
"agentError": "error",
|
||||
"agentIdle": "idle",
|
||||
"agentRunning": "running",
|
||||
"autoKillLabel": "Auto-kill vitest on memory pressure",
|
||||
"autoRefresh": "Auto-refresh · 5s",
|
||||
"confirmKill": "Confirm Kill?",
|
||||
@@ -6979,6 +7006,10 @@ export default interface Resources {
|
||||
"killedProcesses_one": "Killed {{count}} processes",
|
||||
"killedProcesses_other": "Killed {{count}} processes",
|
||||
"lastAutoKill": "Last auto-kill: {{time}}",
|
||||
"localNodeFallback": "Local node",
|
||||
"nodeSelectorAriaLabel": "Select system stats node",
|
||||
"nodeSelectorLabel": "Node",
|
||||
"nodeStatusSuffix": "{{status}}",
|
||||
"notYet": "Not yet",
|
||||
"refreshAriaLabel": "Refresh system stats",
|
||||
"refreshTitle": "Refresh",
|
||||
@@ -7002,7 +7033,9 @@ export default interface Resources {
|
||||
"sectionTasks": "Tasks",
|
||||
"sectionTasksAriaLabel": "Task stats",
|
||||
"sectionVitest": "Vitest Controls",
|
||||
"thisNodeSuffix": "this node",
|
||||
"updatedAt": "Updated {{time}}",
|
||||
"viewingNode": "Viewing {{node}}",
|
||||
"vitestProcesses": "Vitest Processes",
|
||||
"waitingFirstUpdate": "Waiting for first update"
|
||||
},
|
||||
@@ -8430,8 +8463,10 @@ export default interface Resources {
|
||||
"workflowSwitcher": {
|
||||
"countsAria": "{{todoLabel}}: {{todo}}, {{inProgressLabel}}: {{inProgress}}, {{doneLabel}}: {{done}}",
|
||||
"done": "Done",
|
||||
"editWorkflow": "Edit workflow",
|
||||
"inProgress": "In Progress",
|
||||
"label": "Workflow",
|
||||
"newWorkflow": "New workflow",
|
||||
"todo": "Todo",
|
||||
"triggerAria": "Select workflow. Current workflow: {{name}}"
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user