FN-7153: relabel project card engine controls

Project dashboard cards now describe engine lifecycle actions directly.

- Change project card Pause/Resume controls to Stop engine/Start engine while preserving existing behavior.
- Replace the pause icon with a stop-square glyph for the stop action.
- Update project card i18n resources, generated resource types, tests, and the release changeset.

Files changed:
 .changeset/fn-7153-stop-engine-label.md            |   7 ++
 packages/dashboard/app/components/ProjectCard.tsx  |  20 ++--
 .../app/components/__tests__/ProjectCard.test.tsx  | 103 ++++++++++++++++++---
 .../__tests__/ProjectThemeTokens.test.tsx          |   1 +
 packages/i18n/locales/en/app.json                  |  10 +-
 packages/i18n/locales/es/app.json                  |  10 +-
 packages/i18n/locales/fr/app.json                  |  10 +-
 packages/i18n/locales/ko/app.json                  |  10 +-
 packages/i18n/locales/zh-CN/app.json               |  10 +-
 packages/i18n/locales/zh-TW/app.json               |  10 +-
 packages/i18n/src/resources.d.ts                   |  74 +++++++++++++--
 11 files changed, 208 insertions(+), 57 deletions(-)

Fusion-Task-Id: FN-7153

Fusion-Task-Lineage: 14a4efe7-7538-425e-9759-ded550438df2

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
This commit is contained in:
gsxdsm
2026-06-27 19:54:22 -07:00
parent 6ca51185f3
commit bb89e1ec3c
11 changed files with 208 additions and 57 deletions

View File

@@ -0,0 +1,7 @@
---
"@runfusion/fusion": patch
---
summary: Project Dashboard cards now say "Stop engine"/"Start engine" instead of "Pause"/"Resume".
category: feature
dev: Relabels ProjectCard pause/resume controls; pauseProject already stops the engine, so behavior is unchanged. i18n projectCard.* keys updated (en) with empty-string fallback for other locales.

View File

@@ -1,7 +1,7 @@
import { memo, useCallback, useState } from "react"; import { memo, useCallback, useState } from "react";
import type { TFunction } from "i18next"; import type { TFunction } from "i18next";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { Play, Pause, Trash2, Folder, ArrowRight } from "lucide-react"; import { Play, Square, Trash2, Folder, ArrowRight } from "lucide-react";
import "./ProjectCard.css"; import "./ProjectCard.css";
import type { RegisteredProject, ProjectHealth } from "@fusion/core"; import type { RegisteredProject, ProjectHealth } from "@fusion/core";
import type { ProjectNodeAvailability } from "../api"; import type { ProjectNodeAvailability } from "../api";
@@ -219,27 +219,31 @@ function ProjectCardInner({
</div> </div>
<div className="project-card-actions"> <div className="project-card-actions">
{/*
* FNXC:ProjectCardEngineControls 2026-06-27-00:00:
* ProjectEngineManager.pauseProject already calls engine.stop(), so the card action names the engine-lifecycle action as Stop engine/Start engine while preserving the active/paused project status model and pauseProject/resumeProject wiring.
*/}
{isPaused ? ( {isPaused ? (
<button <button
className="project-card-action project-card-action-resume" className="project-card-action project-card-action-resume"
onClick={handleResume} onClick={handleResume}
disabled={isLoading} disabled={isLoading}
title={t("projectCard.resumeProject", "Resume project")} title={t("projectCard.resumeProject", "Start engine")}
aria-label={t("projectCard.resumeProject", "Resume project")} aria-label={t("projectCard.resumeProject", "Start engine")}
> >
<Play size={14} /> <Play size={14} />
<span>{t("projectCard.resume", "Resume")}</span> <span>{t("projectCard.resume", "Start engine")}</span>
</button> </button>
) : ( ) : (
<button <button
className="project-card-action project-card-action-pause" className="project-card-action project-card-action-pause"
onClick={handlePause} onClick={handlePause}
disabled={isLoading || isInitializing} disabled={isLoading || isInitializing}
title={isInitializing ? t("projectCard.cannotPauseWhileInitializing", "Cannot pause while initializing") : t("projectCard.pauseProject", "Pause project")} title={isInitializing ? t("projectCard.cannotPauseWhileInitializing", "Cannot stop engine while initializing") : t("projectCard.pauseProject", "Stop engine")}
aria-label={t("projectCard.pauseProject", "Pause project")} aria-label={t("projectCard.pauseProject", "Stop engine")}
> >
<Pause size={14} /> <Square size={14} />
<span>{t("projectCard.pause", "Pause")}</span> <span>{t("projectCard.pause", "Stop engine")}</span>
</button> </button>
)} )}

View File

@@ -6,7 +6,8 @@ import type { RegisteredProject, ProjectHealth, ProjectStatus } from "@fusion/co
// Mock lucide-react to avoid SVG rendering issues in test env // Mock lucide-react to avoid SVG rendering issues in test env
vi.mock("lucide-react", () => ({ vi.mock("lucide-react", () => ({
Play: () => <span data-testid="play-icon">▶</span>, Play: () => <span data-testid="play-icon">▶</span>,
Pause: () => <span data-testid="pause-icon">⏸</span>, Pause: () => <span data-testid="status-pause-icon">⏸</span>,
Square: () => <span data-testid="stop-icon">■</span>,
AlertCircle: () => <span data-testid="alert-icon">⚠</span>, AlertCircle: () => <span data-testid="alert-icon">⚠</span>,
Loader2: () => <span data-testid="loader-icon">⟳</span>, Loader2: () => <span data-testid="loader-icon">⟳</span>,
MoreHorizontal: () => null, MoreHorizontal: () => null,
@@ -366,7 +367,7 @@ describe("ProjectCard", () => {
expect(onSelect).toHaveBeenCalledWith(project); expect(onSelect).toHaveBeenCalledWith(project);
}); });
it("calls onPause when pause button is clicked", () => { it("calls onPause when stop-engine button is clicked", () => {
const onPause = vi.fn(); const onPause = vi.fn();
const project = makeProject({ status: "active" }); const project = makeProject({ status: "active" });
@@ -381,11 +382,11 @@ describe("ProjectCard", () => {
/> />
); );
fireEvent.click(screen.getByLabelText("Pause project")); fireEvent.click(screen.getByLabelText("Stop engine"));
expect(onPause).toHaveBeenCalledWith(project); expect(onPause).toHaveBeenCalledWith(project);
}); });
it("calls onResume when resume button is clicked", () => { it("calls onResume when start-engine button is clicked", () => {
const onResume = vi.fn(); const onResume = vi.fn();
const project = makeProject({ status: "paused" }); const project = makeProject({ status: "paused" });
@@ -400,10 +401,88 @@ describe("ProjectCard", () => {
/> />
); );
fireEvent.click(screen.getByLabelText("Resume project")); fireEvent.click(screen.getByLabelText("Start engine"));
expect(onResume).toHaveBeenCalledWith(project); expect(onResume).toHaveBeenCalledWith(project);
}); });
it("labels engine lifecycle controls across active, errored, paused, and initializing states", () => {
const activePause = vi.fn();
const activeProject = makeProject({ status: "active" });
const activeRender = render(
<ProjectCard
project={activeProject}
health={makeHealth({ status: "active" })}
onSelect={noop}
onPause={activePause}
onResume={noop}
onRemove={noop}
/>
);
const activeStop = screen.getByRole("button", { name: "Stop engine" });
expect(activeStop).toHaveAttribute("title", "Stop engine");
expect(screen.getByTestId("stop-icon")).toBeDefined();
const stalePauseLabel = ["Pause", "project"].join(" ");
const staleResumeLabel = ["Resume", "project"].join(" ");
expect(screen.queryByLabelText(stalePauseLabel)).toBeNull();
expect(screen.queryByLabelText(staleResumeLabel)).toBeNull();
fireEvent.click(activeStop);
expect(activePause).toHaveBeenCalledWith(activeProject);
activeRender.unmount();
const erroredPause = vi.fn();
const erroredProject = makeProject({ status: "errored" });
const erroredRender = render(
<ProjectCard
project={erroredProject}
health={makeHealth({ status: "errored" })}
onSelect={noop}
onPause={erroredPause}
onResume={noop}
onRemove={noop}
/>
);
fireEvent.click(screen.getByRole("button", { name: "Stop engine" }));
expect(erroredPause).toHaveBeenCalledWith(erroredProject);
erroredRender.unmount();
const pausedResume = vi.fn();
const pausedProject = makeProject({ status: "paused" });
const pausedRender = render(
<ProjectCard
project={pausedProject}
health={makeHealth({ status: "paused" })}
onSelect={noop}
onPause={noop}
onResume={pausedResume}
onRemove={noop}
/>
);
const pausedStart = screen.getByRole("button", { name: "Start engine" });
expect(pausedStart).toHaveAttribute("title", "Start engine");
expect(screen.getByTestId("play-icon")).toBeDefined();
fireEvent.click(pausedStart);
expect(pausedResume).toHaveBeenCalledWith(pausedProject);
pausedRender.unmount();
render(
<ProjectCard
project={makeProject({ status: "initializing" })}
health={makeHealth({ status: "initializing" })}
onSelect={noop}
onPause={noop}
onResume={noop}
onRemove={noop}
/>
);
const initializingStop = screen.getByRole("button", { name: "Stop engine" });
expect(initializingStop).toBeDisabled();
expect(initializingStop).toHaveAttribute("title", "Cannot stop engine while initializing");
});
it("calls onRemove when remove button is clicked", () => { it("calls onRemove when remove button is clicked", () => {
const onRemove = vi.fn(); const onRemove = vi.fn();
const project = makeProject(); const project = makeProject();
@@ -454,7 +533,7 @@ describe("ProjectCard", () => {
expect(container.querySelector(".is-armed")).not.toBeNull(); expect(container.querySelector(".is-armed")).not.toBeNull();
}); });
it("disables pause button when initializing", () => { it("disables stop-engine button when initializing", () => {
const { container } = render( const { container } = render(
<ProjectCard <ProjectCard
project={makeProject({ status: "initializing" })} project={makeProject({ status: "initializing" })}
@@ -466,10 +545,10 @@ describe("ProjectCard", () => {
/> />
); );
// Find the pause button by its title attribute // Find the stop-engine button by its title attribute
const pauseButton = container.querySelector('button[title="Cannot pause while initializing"]'); const stopEngineButton = container.querySelector('button[title="Cannot stop engine while initializing"]');
expect(pauseButton).not.toBeNull(); expect(stopEngineButton).not.toBeNull();
expect(pauseButton).toBeDisabled(); expect(stopEngineButton).toBeDisabled();
}); });
it("disables all buttons when isLoading is true", () => { it("disables all buttons when isLoading is true", () => {
@@ -485,7 +564,7 @@ describe("ProjectCard", () => {
/> />
); );
expect(screen.getByLabelText("Pause project")).toBeDisabled(); expect(screen.getByLabelText("Stop engine")).toBeDisabled();
expect(screen.getByLabelText("Open project")).toBeDisabled(); expect(screen.getByLabelText("Open project")).toBeDisabled();
expect(screen.getByLabelText("Remove project")).toBeDisabled(); expect(screen.getByLabelText("Remove project")).toBeDisabled();
}); });
@@ -536,7 +615,7 @@ describe("ProjectCard", () => {
/> />
); );
fireEvent.click(screen.getByLabelText("Pause project")); fireEvent.click(screen.getByLabelText("Stop engine"));
expect(onPause).toHaveBeenCalled(); expect(onPause).toHaveBeenCalled();
expect(onSelect).not.toHaveBeenCalled(); expect(onSelect).not.toHaveBeenCalled();
}); });

View File

@@ -23,6 +23,7 @@ import type { ProjectInfo } from "../../../app/api";
vi.mock("lucide-react", () => ({ vi.mock("lucide-react", () => ({
Play: () => <span>Play</span>, Play: () => <span>Play</span>,
Pause: () => <span>Pause</span>, Pause: () => <span>Pause</span>,
Square: () => <span>Square</span>,
AlertCircle: () => <span>AlertCircle</span>, AlertCircle: () => <span>AlertCircle</span>,
Loader2: () => <span>Loader2</span>, Loader2: () => <span>Loader2</span>,
ChevronDown: () => <span>ChevronDown</span>, ChevronDown: () => <span>ChevronDown</span>,

View File

@@ -4837,7 +4837,7 @@
"projectCard": { "projectCard": {
"activeTasks": "Active Tasks", "activeTasks": "Active Tasks",
"agents": "Agents", "agents": "Agents",
"cannotPauseWhileInitializing": "Cannot pause while initializing", "cannotPauseWhileInitializing": "Cannot stop engine while initializing",
"completed": "Completed", "completed": "Completed",
"confirm": "Confirm", "confirm": "Confirm",
"confirmRemove": "Confirm remove", "confirmRemove": "Confirm remove",
@@ -4857,11 +4857,11 @@
"noHealthData": "No health data available", "noHealthData": "No health data available",
"open": "Open", "open": "Open",
"openProject": "Open project", "openProject": "Open project",
"pause": "Pause", "pause": "Stop engine",
"pauseProject": "Pause project", "pauseProject": "Stop engine",
"removeProject": "Remove project", "removeProject": "Remove project",
"resume": "Resume", "resume": "Start engine",
"resumeProject": "Resume project" "resumeProject": "Start engine"
}, },
"projectDetection": { "projectDetection": {
"editName": "Edit name", "editName": "Edit name",

View File

@@ -4827,7 +4827,7 @@
"projectCard": { "projectCard": {
"activeTasks": "Tareas activas", "activeTasks": "Tareas activas",
"agents": "Agentes", "agents": "Agentes",
"cannotPauseWhileInitializing": "No se puede pausar mientras se inicializa", "cannotPauseWhileInitializing": "",
"completed": "Completado", "completed": "Completado",
"confirm": "Confirmar", "confirm": "Confirmar",
"confirmRemove": "Confirmar eliminación", "confirmRemove": "Confirmar eliminación",
@@ -4847,11 +4847,11 @@
"noHealthData": "No hay datos de salud disponibles", "noHealthData": "No hay datos de salud disponibles",
"open": "Abrir", "open": "Abrir",
"openProject": "Abrir proyecto", "openProject": "Abrir proyecto",
"pause": "Pausar", "pause": "",
"pauseProject": "Pausar proyecto", "pauseProject": "",
"removeProject": "Eliminar proyecto", "removeProject": "Eliminar proyecto",
"resume": "Reanudar", "resume": "",
"resumeProject": "Reanudar proyecto" "resumeProject": ""
}, },
"projectDetection": { "projectDetection": {
"editName": "Editar nombre", "editName": "Editar nombre",

View File

@@ -4827,7 +4827,7 @@
"projectCard": { "projectCard": {
"activeTasks": "Tâches actives", "activeTasks": "Tâches actives",
"agents": "Agents", "agents": "Agents",
"cannotPauseWhileInitializing": "Impossible de mettre en pause lors de l'initialisation", "cannotPauseWhileInitializing": "",
"completed": "Complétée", "completed": "Complétée",
"confirm": "Confirmer", "confirm": "Confirmer",
"confirmRemove": "Confirmer la suppression", "confirmRemove": "Confirmer la suppression",
@@ -4847,11 +4847,11 @@
"noHealthData": "Aucune donnée de santé disponible", "noHealthData": "Aucune donnée de santé disponible",
"open": "Ouvrir", "open": "Ouvrir",
"openProject": "Ouvrir le projet", "openProject": "Ouvrir le projet",
"pause": "Pause", "pause": "",
"pauseProject": "Mettre le projet en pause", "pauseProject": "",
"removeProject": "Supprimer le projet", "removeProject": "Supprimer le projet",
"resume": "Reprendre", "resume": "",
"resumeProject": "Reprendre le projet" "resumeProject": ""
}, },
"projectDetection": { "projectDetection": {
"editName": "Modifier le nom", "editName": "Modifier le nom",

View File

@@ -4827,7 +4827,7 @@
"projectCard": { "projectCard": {
"activeTasks": "활성 작업", "activeTasks": "활성 작업",
"agents": "에이전트", "agents": "에이전트",
"cannotPauseWhileInitializing": "초기화 중에는 일시 중지할 수 없습니다", "cannotPauseWhileInitializing": "",
"completed": "완료됨", "completed": "완료됨",
"confirm": "확인", "confirm": "확인",
"confirmRemove": "제거 확인", "confirmRemove": "제거 확인",
@@ -4847,11 +4847,11 @@
"noHealthData": "사용 가능한 상태 데이터가 없습니다", "noHealthData": "사용 가능한 상태 데이터가 없습니다",
"open": "열기", "open": "열기",
"openProject": "프로젝트 열기", "openProject": "프로젝트 열기",
"pause": "일시 중지", "pause": "",
"pauseProject": "프로젝트 일시 중지", "pauseProject": "",
"removeProject": "프로젝트 제거", "removeProject": "프로젝트 제거",
"resume": "재개", "resume": "",
"resumeProject": "프로젝트 재개" "resumeProject": ""
}, },
"projectDetection": { "projectDetection": {
"editName": "이름 편집", "editName": "이름 편집",

View File

@@ -4827,7 +4827,7 @@
"projectCard": { "projectCard": {
"activeTasks": "活跃任务", "activeTasks": "活跃任务",
"agents": "代理", "agents": "代理",
"cannotPauseWhileInitializing": "初始化时无法暂停", "cannotPauseWhileInitializing": "",
"completed": "已完成", "completed": "已完成",
"confirm": "确认", "confirm": "确认",
"confirmRemove": "确认删除", "confirmRemove": "确认删除",
@@ -4847,11 +4847,11 @@
"noHealthData": "没有可用的健康数据", "noHealthData": "没有可用的健康数据",
"open": "打开", "open": "打开",
"openProject": "打开项目", "openProject": "打开项目",
"pause": "暂停", "pause": "",
"pauseProject": "暂停项目", "pauseProject": "",
"removeProject": "删除项目", "removeProject": "删除项目",
"resume": "恢复", "resume": "",
"resumeProject": "恢复项目" "resumeProject": ""
}, },
"projectDetection": { "projectDetection": {
"editName": "编辑名称", "editName": "编辑名称",

View File

@@ -4827,7 +4827,7 @@
"projectCard": { "projectCard": {
"activeTasks": "活躍任務", "activeTasks": "活躍任務",
"agents": "代理", "agents": "代理",
"cannotPauseWhileInitializing": "初始化時無法暫停", "cannotPauseWhileInitializing": "",
"completed": "已完成", "completed": "已完成",
"confirm": "確認", "confirm": "確認",
"confirmRemove": "確認移除", "confirmRemove": "確認移除",
@@ -4847,11 +4847,11 @@
"noHealthData": "沒有可用的健康資料", "noHealthData": "沒有可用的健康資料",
"open": "打開", "open": "打開",
"openProject": "打開專案", "openProject": "打開專案",
"pause": "暫停", "pause": "",
"pauseProject": "暫停專案", "pauseProject": "",
"removeProject": "移除專案", "removeProject": "移除專案",
"resume": "恢復", "resume": "",
"resumeProject": "恢復專案" "resumeProject": ""
}, },
"projectDetection": { "projectDetection": {
"editName": "編輯名稱", "editName": "編輯名稱",

View File

@@ -1230,6 +1230,7 @@ export default interface Resources {
"cancelButton": "Cancel", "cancelButton": "Cancel",
"clearConversationFailed": "Failed to clear conversation", "clearConversationFailed": "Failed to clear conversation",
"closeQuickChat": "Close quick chat", "closeQuickChat": "Close quick chat",
"contextWindowAria": "Estimated {{used}} of {{total}} context tokens",
"conversationArchived": "Conversation archived", "conversationArchived": "Conversation archived",
"conversationDeleted": "Conversation deleted", "conversationDeleted": "Conversation deleted",
"conversationName": "Conversation name", "conversationName": "Conversation name",
@@ -1533,6 +1534,8 @@ export default interface Resources {
"maxConcurrent": "Max concurrent tasks", "maxConcurrent": "Max concurrent tasks",
"maxTriageConcurrent": "Max triage concurrent", "maxTriageConcurrent": "Max triage concurrent",
"maxWorktrees": "Max worktrees", "maxWorktrees": "Max worktrees",
"runningGlobal": "{{count}} running (all projects)",
"runningProject": "{{count}} running (this project)",
"title": "Concurrency" "title": "Concurrency"
}, },
"engine": { "engine": {
@@ -1761,7 +1764,8 @@ export default interface Resources {
"system": "System", "system": "System",
"team": "Team", "team": "Team",
"tokens": "Tokens", "tokens": "Tokens",
"tools": "Tools" "tools": "Tools",
"workflows": "Workflows"
}, },
"team": { "team": {
"agent": "Agent", "agent": "Agent",
@@ -1819,6 +1823,26 @@ export default interface Resources {
"sessions": "Sessions", "sessions": "Sessions",
"summaryTitle": "Summary", "summaryTitle": "Summary",
"toolCalls": "Tool calls" "toolCalls": "Tool calls"
},
"workflows": {
"completedByWorkflow": "Tasks done by workflow",
"cost": "Cost",
"done": "Tasks done",
"empty": "No workflow analytics have been recorded for this range yet.",
"files": "Files changed",
"filesChanged": "Files changed",
"inProgress": "In progress",
"inReview": "In review",
"noChartData": "No non-zero values for this chart yet.",
"tableTitle": "Per-workflow breakdown",
"tasksCompleted": "Tasks done",
"tokens": "Tokens",
"tokensByWorkflow": "Tokens by workflow",
"totalCost": "Estimated cost",
"totalTokens": "Total tokens",
"totalsTitle": "Workflow totals",
"unknownWorkflow": "(unknown workflow)",
"workflow": "Workflow"
} }
}, },
"comments": { "comments": {
@@ -2318,6 +2342,7 @@ export default interface Resources {
"daysAgo_one": "{{count}}d ago", "daysAgo_one": "{{count}}d ago",
"daysAgo_other": "{{count}}d ago", "daysAgo_other": "{{count}}d ago",
"engineControls": "Engine controls", "engineControls": "Engine controls",
"engineControlsClose": "Close engine controls",
"escalated": "Escalated", "escalated": "Escalated",
"escalatedSuffix": " (escalated)", "escalatedSuffix": " (escalated)",
"hideProjectDir": "Hide project directory", "hideProjectDir": "Hide project directory",
@@ -4814,7 +4839,7 @@ export default interface Resources {
"projectCard": { "projectCard": {
"activeTasks": "Active Tasks", "activeTasks": "Active Tasks",
"agents": "Agents", "agents": "Agents",
"cannotPauseWhileInitializing": "Cannot pause while initializing", "cannotPauseWhileInitializing": "Cannot stop engine while initializing",
"completed": "Completed", "completed": "Completed",
"confirm": "Confirm", "confirm": "Confirm",
"confirmRemove": "Confirm remove", "confirmRemove": "Confirm remove",
@@ -4834,11 +4859,11 @@ export default interface Resources {
"nodeAvailability": "Project node availability", "nodeAvailability": "Project node availability",
"open": "Open", "open": "Open",
"openProject": "Open project", "openProject": "Open project",
"pause": "Pause", "pause": "Stop engine",
"pauseProject": "Pause project", "pauseProject": "Stop engine",
"removeProject": "Remove project", "removeProject": "Remove project",
"resume": "Resume", "resume": "Start engine",
"resumeProject": "Resume project" "resumeProject": "Start engine"
}, },
"projectDetection": { "projectDetection": {
"editName": "Edit name", "editName": "Edit name",
@@ -5936,6 +5961,12 @@ export default interface Resources {
"keepLocal": "Keep Local", "keepLocal": "Keep Local",
"keepRemote": "Keep Remote", "keepRemote": "Keep Remote",
"loading": "Loading…", "loading": "Loading…",
"mcp": {
"globalDescription": "Configure MCP servers shared by all projects. Project settings may override or disable these servers by name.",
"globalTitle": "Global MCP servers",
"projectDescription": "Configure project-specific MCP servers, overrides, and disabled inherited servers.",
"projectTitle": "Project MCP servers"
},
"memory": { "memory": {
"03": "0 3 * * *", "03": "0 3 * * *",
"agentsGetMemorySearchMemoryGetAndMemory": "Agents get memory_search, memory_get, and memory_append tools. Search defaults to qmd with a local file fallback.", "agentsGetMemorySearchMemoryGetAndMemory": "Agents get memory_search, memory_get, and memory_append tools. Search defaults to qmd with a local file fallback.",
@@ -6070,12 +6101,12 @@ export default interface Resources {
"origin": "origin", "origin": "origin",
"personalAccessToken": "Personal access token", "personalAccessToken": "Personal access token",
"pickALocalBranchFromTheDropdownCommon": "). Pick a local branch from the dropdown — common integration names like ", "pickALocalBranchFromTheDropdownCommon": "). Pick a local branch from the dropdown — common integration names like ",
"positiveIntegerRetryCapForAutoMergeConflict": "Positive integer retry cap for auto-merge conflict resolution before a task parks for human recovery. Default 3.",
"planApprovalMode": "Plan approval mode", "planApprovalMode": "Plan approval mode",
"planApprovalModeAutoApproveAll": "Auto-approve all tasks", "planApprovalModeAutoApproveAll": "Auto-approve all tasks",
"planApprovalModeHelp": "Project-wide override for the planning approval gate. Leave on workflow to use each workflow's Require plan approval setting, or force all approved specs to bypass or wait for manual approval.", "planApprovalModeHelp": "Project-wide override for the planning approval gate. Leave on workflow to use each workflow's Require plan approval setting, or force all approved specs to bypass or wait for manual approval.",
"planApprovalModeRequireAll": "Require approval for all tasks", "planApprovalModeRequireAll": "Require approval for all tasks",
"planApprovalModeWorkflow": "Use workflow setting", "planApprovalModeWorkflow": "Use workflow setting",
"positiveIntegerRetryCapForAutoMergeConflict": "Positive integer retry cap for auto-merge conflict resolution before a task parks for human recovery. Default 3.",
"postMergeAuditMode": "Post-merge audit mode", "postMergeAuditMode": "Post-merge audit mode",
"pushRemote": "Push Remote", "pushRemote": "Push Remote",
"pushToRemoteAfterMerge": " Push to remote after merge ", "pushToRemoteAfterMerge": " Push to remote after merge ",
@@ -6143,6 +6174,8 @@ export default interface Resources {
"global": "Global setting", "global": "Global setting",
"project": "Project setting" "project": "Project setting"
}, },
"globalMcp": "MCP Servers",
"mcp": "MCP Servers",
"prompts": "Prompts", "prompts": "Prompts",
"secrets": "Secrets", "secrets": "Secrets",
"tooltip": { "tooltip": {
@@ -7567,6 +7600,32 @@ export default interface Resources {
"summary": { "summary": {
"heading": "Summary" "heading": "Summary"
}, },
"summaryTab": {
"agentWorkHeading": "Work done by agents",
"cachedTokens": "Cached",
"changedHeading": "What changed",
"commit": "Commit",
"completedSteps": "Completed steps",
"completionHeading": "Completion summary",
"cost": "Cost",
"costUnavailable": "No pricing for this model",
"deletions": "Removed",
"filesChanged": "Files",
"inputTokens": "Input",
"insertions": "Added",
"model": "Model",
"noAgentWork": "No completed steps or workflow results are available for this task.",
"noChangedFiles": "No changed-file list is available for this task.",
"noCompletionSummary": "No completion summary was recorded for this task.",
"noTokenUsage": "No token usage recorded for this task yet.",
"outputTokens": "Output",
"retries": "Agents retried this task {{count}} time{{plural}}.",
"tokenCostHeading": "Token usage & cost",
"totalCost": "Total cost",
"totalTokens": "Total",
"unknownModel": "(unknown)",
"workflowResults": "Workflow results"
},
"tabs": { "tabs": {
"changes": "Changes", "changes": "Changes",
"chat": "Chat", "chat": "Chat",
@@ -7579,6 +7638,7 @@ export default interface Resources {
"review": "Review", "review": "Review",
"routing": "Routing", "routing": "Routing",
"stats": "Stats", "stats": "Stats",
"summary": "Summary",
"terminal": "Terminal", "terminal": "Terminal",
"workflow": "Workflow" "workflow": "Workflow"
}, },