fix: copy and content improvements in goose2 (#8886)
Signed-off-by: morgmart <98432065+morgmart@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: morgmart <98432065+morgmart@users.noreply.github.com>
This commit is contained in:
@@ -299,7 +299,11 @@ export function AgentsView() {
|
||||
>
|
||||
<AlertDialogContent className="max-w-sm">
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>{t("view.deleteTitle")}</AlertDialogTitle>
|
||||
<AlertDialogTitle>
|
||||
{t("view.deleteTitle", {
|
||||
name: deletingPersona?.displayName ?? "",
|
||||
})}
|
||||
</AlertDialogTitle>
|
||||
<AlertDialogDescription>
|
||||
{t("view.deleteDescription", {
|
||||
name: deletingPersona?.displayName ?? "",
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
getChatInputAgentLabel,
|
||||
getChatInputPlaceholder,
|
||||
} from "./chatInputPlaceholder";
|
||||
|
||||
const t = (key: string, options?: { agent: string }) =>
|
||||
options?.agent ? `${key}:${options.agent}` : key;
|
||||
|
||||
describe("getChatInputAgentLabel", () => {
|
||||
it("uses the active persona display name when present", () => {
|
||||
expect(getChatInputAgentLabel("Reviewer", "Goose")).toBe("Reviewer");
|
||||
});
|
||||
|
||||
it("falls back to the provider display name", () => {
|
||||
expect(getChatInputAgentLabel(undefined, "Goose")).toBe("Goose");
|
||||
});
|
||||
|
||||
it("preserves explicit persona names with the default suffix", () => {
|
||||
expect(getChatInputAgentLabel("Ops (Default)", "Goose (Default)")).toBe(
|
||||
"Ops (Default)",
|
||||
);
|
||||
});
|
||||
|
||||
it("removes the default suffix from provider fallback labels", () => {
|
||||
expect(getChatInputAgentLabel(undefined, "Goose (Default)")).toBe("Goose");
|
||||
});
|
||||
});
|
||||
|
||||
describe("getChatInputPlaceholder", () => {
|
||||
it("uses the agent label in the default placeholder", () => {
|
||||
expect(getChatInputPlaceholder(t, "Goose", false, false)).toBe(
|
||||
"input.placeholder:Goose",
|
||||
);
|
||||
});
|
||||
|
||||
it("uses voice status placeholders while recording or transcribing", () => {
|
||||
expect(getChatInputPlaceholder(t, "Goose", true, false)).toBe(
|
||||
"toolbar.voiceInputRecording",
|
||||
);
|
||||
expect(getChatInputPlaceholder(t, "Goose", false, true)).toBe(
|
||||
"toolbar.voiceInputTranscribing",
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -1,3 +1,18 @@
|
||||
const DEFAULT_LABEL_SUFFIX = " (Default)";
|
||||
|
||||
export function getChatInputAgentLabel(
|
||||
personaDisplayName: string | undefined,
|
||||
providerDisplayName: string,
|
||||
): string {
|
||||
if (personaDisplayName) {
|
||||
return personaDisplayName;
|
||||
}
|
||||
|
||||
return providerDisplayName.endsWith(DEFAULT_LABEL_SUFFIX)
|
||||
? providerDisplayName.slice(0, -DEFAULT_LABEL_SUFFIX.length)
|
||||
: providerDisplayName;
|
||||
}
|
||||
|
||||
export function getChatInputPlaceholder(
|
||||
t: (key: string, options?: { agent: string }) => string,
|
||||
agent: string,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import type { Message } from "@/shared/types/messages";
|
||||
import { findExistingDraft } from "./newChat";
|
||||
import type { ChatSession } from "../stores/chatSessionStore";
|
||||
|
||||
@@ -8,7 +9,7 @@ function makeSession(
|
||||
): ChatSession {
|
||||
return {
|
||||
id,
|
||||
title: "New Chat",
|
||||
title: "New chat",
|
||||
createdAt: "2026-04-01T00:00:00.000Z",
|
||||
updatedAt: "2026-04-01T00:00:00.000Z",
|
||||
messageCount: 0,
|
||||
@@ -30,7 +31,7 @@ describe("findExistingDraft", () => {
|
||||
draftsBySession: { "alpha-draft": "alpha draft" },
|
||||
messagesBySession: {},
|
||||
request: {
|
||||
title: "New Chat",
|
||||
title: "New chat",
|
||||
projectId: "alpha",
|
||||
},
|
||||
}),
|
||||
@@ -111,7 +112,12 @@ describe("findExistingDraft", () => {
|
||||
draftsBySession: {},
|
||||
messagesBySession: {
|
||||
"alpha-session": [
|
||||
{ id: "msg-1", role: "user", content: "hello" } as any,
|
||||
{
|
||||
id: "msg-1",
|
||||
role: "user",
|
||||
created: 1,
|
||||
content: [{ type: "text", text: "hello" }],
|
||||
} satisfies Message,
|
||||
],
|
||||
},
|
||||
request: {
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
getDisplaySessionTitle,
|
||||
getEditableSessionTitle,
|
||||
getSessionTitleFromDraft,
|
||||
isDefaultChatTitle,
|
||||
isSessionTitleUnchanged,
|
||||
} from "./sessionTitle";
|
||||
|
||||
@@ -17,6 +18,11 @@ describe("sessionTitle", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("treats the ACP title-case default title as the default title", () => {
|
||||
expect(isDefaultChatTitle("New Chat")).toBe(true);
|
||||
expect(getDisplaySessionTitle("New Chat", "Nuevo chat")).toBe("Nuevo chat");
|
||||
});
|
||||
|
||||
it("treats the localized default title as unchanged while the sentinel is still internal", () => {
|
||||
expect(
|
||||
isSessionTitleUnchanged("Nuevo chat", DEFAULT_CHAT_TITLE, "Nuevo chat"),
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import type { ChatAttachmentDraft } from "@/shared/types/messages";
|
||||
|
||||
export const DEFAULT_CHAT_TITLE = "New Chat";
|
||||
export const DEFAULT_CHAT_TITLE = "New chat";
|
||||
const ACP_DEFAULT_CHAT_TITLE = "New Chat";
|
||||
|
||||
export function isDefaultChatTitle(title: string): boolean {
|
||||
return title === DEFAULT_CHAT_TITLE;
|
||||
return title === DEFAULT_CHAT_TITLE || title === ACP_DEFAULT_CHAT_TITLE;
|
||||
}
|
||||
|
||||
function attachmentKindLabel(kind: ChatAttachmentDraft["kind"], count: number) {
|
||||
@@ -17,6 +18,14 @@ function attachmentKindLabel(kind: ChatAttachmentDraft["kind"], count: number) {
|
||||
}
|
||||
}
|
||||
|
||||
// The goose ACP backend uses "New Chat" (title case) as its default — normalize to ours.
|
||||
export function normalizeAcpTitle(
|
||||
title: string | null | undefined,
|
||||
): string | undefined {
|
||||
if (!title) return undefined;
|
||||
return title === ACP_DEFAULT_CHAT_TITLE ? DEFAULT_CHAT_TITLE : title;
|
||||
}
|
||||
|
||||
export function getSessionTitleFromDraft(
|
||||
text: string,
|
||||
attachments?: ChatAttachmentDraft[],
|
||||
|
||||
@@ -5,7 +5,10 @@ import {
|
||||
type AcpSessionInfo,
|
||||
} from "@/shared/api/acp";
|
||||
import type { Session } from "@/shared/types/chat";
|
||||
import { DEFAULT_CHAT_TITLE } from "@/features/chat/lib/sessionTitle";
|
||||
import {
|
||||
DEFAULT_CHAT_TITLE,
|
||||
normalizeAcpTitle,
|
||||
} from "@/features/chat/lib/sessionTitle";
|
||||
import {
|
||||
archiveSession as acpArchiveSession,
|
||||
unarchiveSession as acpUnarchiveSession,
|
||||
@@ -97,7 +100,7 @@ function acpSessionToChatSession(session: AcpSessionInfo): ChatSession {
|
||||
return {
|
||||
id: session.sessionId,
|
||||
acpSessionId: session.sessionId,
|
||||
title: session.title ?? "Untitled",
|
||||
title: normalizeAcpTitle(session.title) ?? "Untitled",
|
||||
projectId: session.projectId ?? undefined,
|
||||
providerId: session.providerId ?? undefined,
|
||||
personaId: session.personaId ?? undefined,
|
||||
|
||||
@@ -5,7 +5,10 @@ import {
|
||||
attachmentSnapshotsMatch,
|
||||
skillDraftSnapshotsMatch,
|
||||
} from "../lib/chatInputSnapshots";
|
||||
import { getChatInputPlaceholder } from "../lib/chatInputPlaceholder";
|
||||
import {
|
||||
getChatInputAgentLabel,
|
||||
getChatInputPlaceholder,
|
||||
} from "../lib/chatInputPlaceholder";
|
||||
import { cn } from "@/shared/lib/cn";
|
||||
import { Badge } from "@/shared/ui/badge";
|
||||
import { Popover, PopoverAnchor } from "@/shared/ui/popover";
|
||||
@@ -330,7 +333,10 @@ export function ChatInput({
|
||||
const providerDisplayName =
|
||||
providers.find((provider) => provider.id === selectedProvider)?.label ??
|
||||
formatProviderLabel(selectedProvider);
|
||||
const agentDisplayName = activePersona?.displayName ?? providerDisplayName;
|
||||
const agentDisplayName = getChatInputAgentLabel(
|
||||
activePersona?.displayName,
|
||||
providerDisplayName,
|
||||
);
|
||||
const resolvedCurrentModel = useMemo(() => {
|
||||
if (currentModel) {
|
||||
return currentModel;
|
||||
|
||||
@@ -94,9 +94,7 @@ describe("ChatInput", () => {
|
||||
it("renders with default placeholder", () => {
|
||||
render(<ChatInput onSend={vi.fn()} />);
|
||||
expect(
|
||||
screen.getByPlaceholderText(
|
||||
"Message Goose, @ to mention agents or skills",
|
||||
),
|
||||
screen.getByPlaceholderText("Chat with Goose or @ mention an agent"),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
|
||||
@@ -39,9 +39,7 @@ describe("FilesList", () => {
|
||||
render(<FilesList />);
|
||||
|
||||
expect(
|
||||
screen.getByText(
|
||||
"Project files are unavailable until a project with working directories is assigned.",
|
||||
),
|
||||
screen.getByText("Files will show here after you assign a project."),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
|
||||
@@ -183,9 +183,7 @@ describe("HomeScreen", () => {
|
||||
it("renders the chat input placeholder with default agent name when no persona selected", () => {
|
||||
renderHome();
|
||||
expect(
|
||||
screen.getByPlaceholderText(
|
||||
"Message Goose, @ to mention agents or skills",
|
||||
),
|
||||
screen.getByPlaceholderText("Chat with Goose or @ mention an agent"),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
|
||||
@@ -279,7 +279,11 @@ export function ProjectsView({ onStartChat }: ProjectsViewProps) {
|
||||
>
|
||||
<AlertDialogContent className="max-w-sm">
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>{t("view.deleteTitle")}</AlertDialogTitle>
|
||||
<AlertDialogTitle>
|
||||
{t("view.deleteTitle", {
|
||||
name: deletingProject?.name ?? "",
|
||||
})}
|
||||
</AlertDialogTitle>
|
||||
<AlertDialogDescription>
|
||||
{t("view.deleteDescription", {
|
||||
name: deletingProject?.name ?? "",
|
||||
|
||||
@@ -155,13 +155,13 @@ describe("CreateProjectDialog", () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(screen.getByText("Edit Project")).toBeInTheDocument();
|
||||
expect(screen.getByText("Edit project")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("shows New Project title without editingProject", () => {
|
||||
render(<CreateProjectDialog {...defaultProps} isOpen={true} />);
|
||||
|
||||
expect(screen.getByText("New Project")).toBeInTheDocument();
|
||||
expect(screen.getByText("New project")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("populates the prompt editor with working dirs and prompt text", () => {
|
||||
|
||||
@@ -60,9 +60,6 @@ export function AppearanceSettings() {
|
||||
<h3 className="text-lg font-semibold font-display tracking-tight">
|
||||
{t("appearance.title")}
|
||||
</h3>
|
||||
<p className="mt-1 text-sm text-muted-foreground">
|
||||
{t("appearance.description")}
|
||||
</p>
|
||||
|
||||
<Separator className="my-4" />
|
||||
|
||||
|
||||
@@ -124,21 +124,19 @@ export function DoctorCheckRow({ check, onFixed }: DoctorCheckRowProps) {
|
||||
<AlertDialogContent className="max-w-sm">
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>{t("settings:doctor.runFix")}</AlertDialogTitle>
|
||||
<AlertDialogDescription className="break-all font-mono">
|
||||
{check.fixCommand}
|
||||
<AlertDialogDescription>
|
||||
{t("settings:doctor.runFixDescription")}
|
||||
</AlertDialogDescription>
|
||||
<code className="block break-all rounded bg-muted px-3 py-2 font-mono text-xs">
|
||||
{check.fixCommand}
|
||||
</code>
|
||||
</AlertDialogHeader>
|
||||
{fixError && <p className="text-xs text-destructive">{fixError}</p>}
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel disabled={fixing}>
|
||||
{t("common:actions.cancel")}
|
||||
</AlertDialogCancel>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
disabled={fixing}
|
||||
onClick={confirmFix}
|
||||
>
|
||||
<Button disabled={fixing} onClick={confirmFix}>
|
||||
{fixing && <Loader2 className="h-3 w-3 animate-spin" />}
|
||||
{fixing
|
||||
? t("common:actions.running")
|
||||
|
||||
@@ -99,9 +99,6 @@ export function DoctorSettings() {
|
||||
<h3 className="text-lg font-semibold font-display tracking-tight">
|
||||
{t("doctor.title")}
|
||||
</h3>
|
||||
<p className="mt-1 text-sm text-muted-foreground">
|
||||
{t("doctor.description")}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-shrink-0 items-center gap-2">
|
||||
|
||||
@@ -331,6 +331,7 @@ export function ModelProviderRow({
|
||||
const fieldSetupDescription = getFieldSetupDescription(
|
||||
provider.setupMethod,
|
||||
t,
|
||||
provider.fields,
|
||||
);
|
||||
|
||||
if (loadingConfig && hasFields) {
|
||||
|
||||
@@ -117,9 +117,6 @@ export function ProvidersSettings() {
|
||||
<h3 className="text-lg font-semibold font-display tracking-tight">
|
||||
{t("providers.title")}
|
||||
</h3>
|
||||
<p className="mt-1 text-sm text-muted-foreground">
|
||||
{t("providers.description")}
|
||||
</p>
|
||||
|
||||
<Separator className="my-4" />
|
||||
|
||||
|
||||
@@ -377,7 +377,11 @@ export function SettingsModal({
|
||||
>
|
||||
<AlertDialogContent className="max-w-sm">
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>{t("deleteProject.title")}</AlertDialogTitle>
|
||||
<AlertDialogTitle>
|
||||
{t("deleteProject.title", {
|
||||
name: deletingProject?.name ?? "",
|
||||
})}
|
||||
</AlertDialogTitle>
|
||||
<AlertDialogDescription>
|
||||
{t("deleteProject.description", {
|
||||
name: deletingProject?.name ?? "",
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { getFieldSetupDescription } from "../modelProviderHelpers";
|
||||
|
||||
const t = (key: string) => key;
|
||||
|
||||
describe("getFieldSetupDescription", () => {
|
||||
it("uses single API key copy for config fields with one required secret API key", () => {
|
||||
expect(
|
||||
getFieldSetupDescription("config_fields", t, [
|
||||
{
|
||||
key: "OPENAI_API_KEY",
|
||||
label: "API Key",
|
||||
secret: true,
|
||||
required: true,
|
||||
placeholder: "Paste your API key",
|
||||
},
|
||||
]),
|
||||
).toBe("providers.models.setup.fieldDescription.singleApiKey");
|
||||
});
|
||||
|
||||
it("uses generic config fields copy for config fields without an API key field", () => {
|
||||
expect(
|
||||
getFieldSetupDescription("config_fields", t, [
|
||||
{
|
||||
key: "OLLAMA_HOST",
|
||||
label: "Host",
|
||||
secret: false,
|
||||
required: true,
|
||||
placeholder: "localhost or http://localhost:11434",
|
||||
},
|
||||
]),
|
||||
).toBe("providers.models.setup.fieldDescription.configFields");
|
||||
});
|
||||
});
|
||||
@@ -103,10 +103,24 @@ export function getNativeConnectDescription(
|
||||
}
|
||||
}
|
||||
|
||||
function hasSingleApiKeyField(fields?: ProviderField[]): boolean {
|
||||
if (fields?.length !== 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const [field] = fields;
|
||||
return field.secret && field.required && /(?:^|_)API_KEY$/.test(field.key);
|
||||
}
|
||||
|
||||
export function getFieldSetupDescription(
|
||||
setupMethod: ProviderSetupMethod,
|
||||
t: (key: string) => string,
|
||||
fields?: ProviderField[],
|
||||
): string | null {
|
||||
if (setupMethod === "config_fields" && hasSingleApiKeyField(fields)) {
|
||||
return t("providers.models.setup.fieldDescription.singleApiKey");
|
||||
}
|
||||
|
||||
switch (setupMethod) {
|
||||
case "single_api_key":
|
||||
return t("providers.models.setup.fieldDescription.singleApiKey");
|
||||
|
||||
@@ -155,7 +155,7 @@ describe("SidebarChatRow", () => {
|
||||
await user.dblClick(screen.getByTitle("Double-click to rename"));
|
||||
|
||||
const input = screen.getByRole("textbox");
|
||||
expect(input).toHaveValue("New Chat");
|
||||
expect(input).toHaveValue("New chat");
|
||||
|
||||
await user.tab();
|
||||
|
||||
|
||||
@@ -57,7 +57,9 @@ export function SkillsDialogs({
|
||||
>
|
||||
<AlertDialogContent className="max-w-sm">
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>{t("view.deleteTitle")}</AlertDialogTitle>
|
||||
<AlertDialogTitle>
|
||||
{t("view.deleteTitle", { name: deletingSkill?.name ?? "" })}
|
||||
</AlertDialogTitle>
|
||||
<AlertDialogDescription>
|
||||
{t("view.deleteDescription", {
|
||||
name: deletingSkill?.name ?? "",
|
||||
|
||||
@@ -43,7 +43,7 @@ describe("CreateSkillDialog", () => {
|
||||
|
||||
it('shows "New Skill" title in create mode', () => {
|
||||
render(<CreateSkillDialog {...defaultProps} />);
|
||||
expect(screen.getByText("New Skill")).toBeInTheDocument();
|
||||
expect(screen.getByText("New skill")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('shows "Edit Skill" title when editingSkill is provided', () => {
|
||||
@@ -59,7 +59,7 @@ describe("CreateSkillDialog", () => {
|
||||
}}
|
||||
/>,
|
||||
);
|
||||
expect(screen.getByText("Edit Skill")).toBeInTheDocument();
|
||||
expect(screen.getByText("Edit skill")).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -115,7 +115,7 @@ describe("SkillsView", () => {
|
||||
render(<SkillsView />);
|
||||
expect(screen.getByText("Skills")).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText(/Skills are reusable instructions/),
|
||||
screen.getByText(/Use skills to add specific instructions/),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -356,7 +356,9 @@ describe("SkillsView", () => {
|
||||
await user.keyboard("{Enter}");
|
||||
await user.click(screen.getByRole("menuitem", { name: "Delete" }));
|
||||
|
||||
expect(screen.getByText("Delete skill?")).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText('Delete "code-review" permanently?'),
|
||||
).toBeInTheDocument();
|
||||
|
||||
const deleteButtons = screen.getAllByRole("button", { name: "Delete" });
|
||||
await user.click(deleteButtons[deleteButtons.length - 1]);
|
||||
|
||||
@@ -68,8 +68,8 @@
|
||||
"view": {
|
||||
"copyName": "{{name}} (Copy)",
|
||||
"deleteFailed": "Failed to delete agent.",
|
||||
"deleteDescription": "Are you sure you want to delete \"{{name}}\"? This cannot be undone.",
|
||||
"deleteTitle": "Delete agent?",
|
||||
"deleteDescription": "This agent and its configuration will be permanently removed.",
|
||||
"deleteTitle": "Delete \"{{name}}\" permanently?",
|
||||
"deleted": "\"{{name}}\" deleted.",
|
||||
"description": "Custom agent configurations for specific workflows",
|
||||
"emptyAgentsDescription": "Create an agent to get started.",
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
"branchName": "Branch name",
|
||||
"branchNamePlaceholder": "feature/my-branch",
|
||||
"branchSuccess": "Created and switched to {{branch}}.",
|
||||
"branchTitle": "New Branch",
|
||||
"branchTitle": "New branch",
|
||||
"branchToOpen": "Branch to open",
|
||||
"cancel": "Cancel",
|
||||
"createBranch": "Create branch",
|
||||
@@ -40,17 +40,17 @@
|
||||
"worktreeNamePlaceholder": "my-worktree",
|
||||
"worktreePath": "Folder: {{path}}",
|
||||
"worktreeSuccess": "Created worktree {{worktree}}.",
|
||||
"worktreeTitle": "New Worktree"
|
||||
"worktreeTitle": "New worktree"
|
||||
},
|
||||
"empty": {
|
||||
"folderNotSet": "Folder not set",
|
||||
"noChanges": "No uncommitted changes",
|
||||
"noProjectAssigned": "No project assigned.",
|
||||
"noProjectAssigned": "No project assigned",
|
||||
"noExtensions": "No extensions enabled",
|
||||
"noMatchingExtensions": "No matching extensions"
|
||||
},
|
||||
"errors": {
|
||||
"gitRead": "Unable to read git status."
|
||||
"gitRead": "Couldn't read git status."
|
||||
},
|
||||
"picker": {
|
||||
"selectContext": "Select worktree or branch",
|
||||
@@ -58,8 +58,9 @@
|
||||
"allBranches": "All branches",
|
||||
"checkedOutBranch": "{{branch}}",
|
||||
"currentBranch": "Current branch",
|
||||
"dirtyTitle": "Uncommitted Changes",
|
||||
"dirtyDescription": "You have {{count}} uncommitted change(s). How would you like to proceed?",
|
||||
"dirtyTitle": "Uncommitted changes",
|
||||
"dirtyDescription_one": "You have {{count}} uncommitted change. How would you like to proceed?",
|
||||
"dirtyDescription_other": "You have {{count}} uncommitted changes. How would you like to proceed?",
|
||||
"stashAndSwitch": "Stash & Switch",
|
||||
"carryChanges": "Carry to Branch",
|
||||
"cancel": "Cancel",
|
||||
@@ -96,19 +97,19 @@
|
||||
}
|
||||
},
|
||||
"files": {
|
||||
"empty": "Project files are unavailable until a project with working directories is assigned.",
|
||||
"empty": "Files will show here after you assign a project.",
|
||||
"folderEmpty": "Folder is empty",
|
||||
"loadError": "Unable to load folder contents.",
|
||||
"loadError": "Couldn't load this folder. Try again.",
|
||||
"loading": "Loading files...",
|
||||
"openFolder": "Open folder: {{path}}",
|
||||
"rootLoadError": "Unable to load this folder."
|
||||
"rootLoadError": "Couldn't load this folder. Try again."
|
||||
},
|
||||
"image": {
|
||||
"view": "View {{label}}"
|
||||
},
|
||||
"input": {
|
||||
"ariaLabel": "Chat message input",
|
||||
"placeholder": "Message {{agent}}, @ to mention agents or skills"
|
||||
"placeholder": "Chat with {{agent}} or @ mention an agent"
|
||||
},
|
||||
"loading": {
|
||||
"compacting": "Compacting conversation...",
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
"run": "Run",
|
||||
"running": "Running",
|
||||
"save": "Save",
|
||||
"saveChanges": "Save Changes",
|
||||
"saveChanges": "Save changes",
|
||||
"search": "Search",
|
||||
"select": "Select",
|
||||
"send": "Send",
|
||||
@@ -42,7 +42,7 @@
|
||||
},
|
||||
"environmentVariables": {
|
||||
"copyLabel": "Copy environment variable",
|
||||
"title": "Environment Variables",
|
||||
"title": "Environment variables",
|
||||
"toggleVisibility": "Toggle value visibility"
|
||||
},
|
||||
"linkSafety": {
|
||||
@@ -78,7 +78,7 @@
|
||||
},
|
||||
"labels": {
|
||||
"assistant": "Assistant",
|
||||
"copyPath": "Copy Path",
|
||||
"copyPath": "Copy path",
|
||||
"revealInFileManager_mac": "Reveal in Finder",
|
||||
"revealInFileManager_windows": "Reveal in Explorer",
|
||||
"revealInFileManager_linux": "Reveal in File Manager",
|
||||
@@ -91,7 +91,7 @@
|
||||
"required": "Required"
|
||||
},
|
||||
"session": {
|
||||
"defaultTitle": "New Chat"
|
||||
"defaultTitle": "New chat"
|
||||
},
|
||||
"usage": {
|
||||
"cache": "Cache",
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
{
|
||||
"dialog": {
|
||||
"addDirectory": "Add directory",
|
||||
"addDirectoryDialogTitle": "Select Directory",
|
||||
"addDirectoryDialogTitle": "Select directory",
|
||||
"color": "Color",
|
||||
"colorAria": "Color {{color}}",
|
||||
"createProject": "Create Project",
|
||||
"createProject": "Create project",
|
||||
"creating": "Creating...",
|
||||
"customIcon": "Custom icon",
|
||||
"customIconDialogTitle": "Select Icon",
|
||||
"editTitle": "Edit Project",
|
||||
"editTitle": "Edit project",
|
||||
"icon": "Icon",
|
||||
"iconAria": "Icon {{icon}}",
|
||||
"iconCandidateTitle": "{{sourceDir}}: {{label}}",
|
||||
@@ -37,26 +37,26 @@
|
||||
"instructionsPlaceholder": "System prompt or context for agents working in this project...",
|
||||
"name": "Name",
|
||||
"namePlaceholder": "My Project",
|
||||
"newTitle": "New Project",
|
||||
"newTitle": "New project",
|
||||
"noneUseDefault": "None (use default)",
|
||||
"provider": "Provider",
|
||||
"saving": "Saving...",
|
||||
"scanningIcons": "Scanning...",
|
||||
"uploadIcon": "Upload",
|
||||
"useWorktrees": "Use git worktrees for branch isolation"
|
||||
"useWorktrees": "Use Git worktrees for branch isolation"
|
||||
},
|
||||
"view": {
|
||||
"deleteDescription": "Are you sure you want to delete \"{{name}}\"? This cannot be undone.",
|
||||
"deleteTitle": "Delete project?",
|
||||
"deleteDescription": "This project and all its data will be permanently removed.",
|
||||
"deleteTitle": "Delete \"{{name}}\" permanently?",
|
||||
"description": "Organize your work into focused project contexts",
|
||||
"emptyDescription": "Create a project to organize your work.",
|
||||
"emptyTitle": "No projects yet",
|
||||
"newProject": "New Project",
|
||||
"newProject": "New project",
|
||||
"noMatchesDescription": "Try a different search term.",
|
||||
"noMatchesTitle": "No matching projects",
|
||||
"optionsAria": "Options for {{name}}",
|
||||
"searchPlaceholder": "Search projects by name or description...",
|
||||
"startChat": "Start Chat",
|
||||
"startChat": "Start chat",
|
||||
"title": "Projects"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
},
|
||||
"history": {
|
||||
"archivedSubtitle": "Sessions you've archived",
|
||||
"archivedTitle": "Archived Sessions",
|
||||
"archivedTitle": "Archived sessions",
|
||||
"backToActive": "Back to active",
|
||||
"emptyArchived": "No archived sessions",
|
||||
"emptyArchivedHint": "Archived sessions will appear here.",
|
||||
@@ -18,12 +18,12 @@
|
||||
"emptyNoMatchesHint": "Try a different search term.",
|
||||
"emptyTitle": "No sessions yet",
|
||||
"searchArchivedPlaceholder": "Search archived sessions...",
|
||||
"searchError": "Message search failed. Showing title, agent, and project matches only.",
|
||||
"searchPlaceholder": "Search conversations",
|
||||
"searchError": "Message search failed. Showing title, agent, and project matches only. Try again.",
|
||||
"searchPlaceholder": "Search sessions...",
|
||||
"searching": "Searching sessions...",
|
||||
"subtitle": "Browse and search past sessions",
|
||||
"toggleArchived": "Archived",
|
||||
"title": "Session History"
|
||||
"title": "Session history"
|
||||
},
|
||||
"search": {
|
||||
"messageMatches_one": "{{displayCount}} message match",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"about": {
|
||||
"description": "About information will appear here.",
|
||||
"description": "View app version, build info, and licenses.",
|
||||
"title": "About"
|
||||
},
|
||||
"appearance": {
|
||||
@@ -16,18 +16,17 @@
|
||||
"red": "Red"
|
||||
},
|
||||
"description": "Choose your accent color",
|
||||
"label": "Accent Color"
|
||||
"label": "Accent color"
|
||||
},
|
||||
"density": {
|
||||
"description": "Adjust the spacing of UI elements",
|
||||
"label": "Interface Density",
|
||||
"label": "Interface density",
|
||||
"options": {
|
||||
"comfortable": "Comfortable",
|
||||
"compact": "Compact",
|
||||
"spacious": "Spacious"
|
||||
}
|
||||
},
|
||||
"description": "Customize the look and feel of Goose",
|
||||
"theme": {
|
||||
"description": "Choose your preferred color scheme",
|
||||
"label": "Theme",
|
||||
@@ -40,11 +39,11 @@
|
||||
"title": "Appearance"
|
||||
},
|
||||
"chats": {
|
||||
"description": "Restore archived chats.",
|
||||
"description": "View and restore your archived chats.",
|
||||
"empty": "No archived chats.",
|
||||
"messageCount_one": "{{displayCount}} message",
|
||||
"messageCount_other": "{{displayCount}} messages",
|
||||
"sectionTitle": "Archived Chats",
|
||||
"sectionTitle": "Archived chats",
|
||||
"title": "Chats",
|
||||
"types": {
|
||||
"project": "Project chat",
|
||||
@@ -70,8 +69,8 @@
|
||||
"title": "Compaction"
|
||||
},
|
||||
"deleteProject": {
|
||||
"description": "Are you sure you want to permanently delete \"{{name}}\"? This cannot be undone.",
|
||||
"title": "Delete project permanently?"
|
||||
"description": "This project and all its data will be permanently removed.",
|
||||
"title": "Delete \"{{name}}\" permanently?"
|
||||
},
|
||||
"extensions": {
|
||||
"title": "Extensions",
|
||||
@@ -125,10 +124,10 @@
|
||||
"agents": "Agents",
|
||||
"copied": "Copied",
|
||||
"copyDetails": "Copy details",
|
||||
"description": "Verify required tools and agent availability for Goose.",
|
||||
"empty": "No checks are available yet.",
|
||||
"rerun": "Re-run",
|
||||
"rerun": "Try again",
|
||||
"runFix": "Run fix command?",
|
||||
"runFixDescription": "This will run the following command:",
|
||||
"running": "Running checks...",
|
||||
"title": "Doctor",
|
||||
"tools": "Tools"
|
||||
@@ -201,12 +200,12 @@
|
||||
"projects": {
|
||||
"description": "Manage your projects.",
|
||||
"empty": "No archived projects.",
|
||||
"sectionTitle": "Archived Projects",
|
||||
"sectionTitle": "Archived projects",
|
||||
"title": "Projects"
|
||||
},
|
||||
"providers": {
|
||||
"agents": {
|
||||
"description": "Agents handle your requests using their own tools and models",
|
||||
"description": "Goose is built in to your workspace. Install others to extend your setup.",
|
||||
"errors": {
|
||||
"installVerificationFailed": "Install finished but the CLI was not found on PATH. You may need to restart your terminal."
|
||||
},
|
||||
@@ -225,10 +224,9 @@
|
||||
},
|
||||
"title": "Agent harnesses"
|
||||
},
|
||||
"description": "Connect agents and AI models to use with Goose",
|
||||
"disconnect": "Disconnect",
|
||||
"models": {
|
||||
"description": "AI models that power Goose. Expand a provider to review what it needs. Connect signs in with an existing account, while Set up saves API keys or other provider settings.",
|
||||
"description": "AI models power your agents. Goose requires one to work, but some agents bring their own.",
|
||||
"notSet": "Not set",
|
||||
"setup": {
|
||||
"connected": {
|
||||
@@ -238,17 +236,17 @@
|
||||
"oauthDeviceCode": "Connected through Goose device-code sign-in."
|
||||
},
|
||||
"fieldDescription": {
|
||||
"cloudCredentials": "Set up saves any provider details Goose needs here. Your actual authentication still comes from your cloud credentials.",
|
||||
"configFields": "Set up saves the provider details Goose needs, such as an API key, endpoint, or model settings.",
|
||||
"hostWithOauthFallback": "Set up saves the host details Goose needs here. You can add a token now, or leave it blank and sign in afterward from Goose.",
|
||||
"singleApiKey": "Set up saves the API key Goose needs for this provider."
|
||||
"cloudCredentials": "Add the required details to use this provider.",
|
||||
"configFields": "Add the required details to use this provider.",
|
||||
"hostWithOauthFallback": "Add the required details to use this provider.",
|
||||
"singleApiKey": "Add your API key to use this provider."
|
||||
},
|
||||
"hostWithOauthFallbackTerminal": "Leave Access Token blank, save your host URL, then run `goose configure` in your terminal to sign in.",
|
||||
"nativeConnectDescription": "Sign in with your existing account.",
|
||||
"pending": {
|
||||
"cloudCredentials": "Configure your cloud credentials in your terminal environment before using this provider.",
|
||||
"local": "This provider runs locally and does not need saved settings here.",
|
||||
"oauthGuided": "Goose will guide you through sign-in from here.",
|
||||
"local": "This provider runs locally and doesn't need saved settings.",
|
||||
"oauthGuided": "Goose will guide you through sign-in.",
|
||||
"oauthTerminal": "Run `goose configure` in your terminal to finish sign-in."
|
||||
}
|
||||
},
|
||||
|
||||
@@ -13,12 +13,12 @@
|
||||
"navigation": {
|
||||
"agents": "Agents",
|
||||
"home": "Home",
|
||||
"sessionHistory": "Session History",
|
||||
"sessionHistory": "Session history",
|
||||
"skills": "Skills"
|
||||
},
|
||||
"search": {
|
||||
"error": "Message search failed. Showing metadata matches only.",
|
||||
"placeholder": "Search conversations",
|
||||
"error": "Message search failed. Showing metadata matches only. Try again.",
|
||||
"placeholder": "Search chats...",
|
||||
"searching": "Searching chats..."
|
||||
},
|
||||
"sections": {
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
{
|
||||
"dialog": {
|
||||
"createSkill": "Create Skill",
|
||||
"createSkill": "Create skill",
|
||||
"creating": "Creating...",
|
||||
"description": "Description",
|
||||
"descriptionPlaceholder": "What it does and when to use it...",
|
||||
"editTitle": "Edit Skill",
|
||||
"editTitle": "Edit skill",
|
||||
"instructions": "Instructions",
|
||||
"instructionsPlaceholder": "Markdown instructions the agent will follow...",
|
||||
"name": "Name",
|
||||
"namePlaceholder": "my-skill-name",
|
||||
"nameValidation": "Use 1–64 lowercase letters, numbers, or hyphens. Names cannot start or end with a hyphen.",
|
||||
"pathOnDisk": "Path on disk",
|
||||
"newTitle": "New Skill",
|
||||
"newTitle": "New skill",
|
||||
"saving": "Saving..."
|
||||
},
|
||||
"view": {
|
||||
"backToSkills": "Back to skills",
|
||||
"deleteDescription": "Are you sure you want to delete \"{{name}}\"? This cannot be undone.",
|
||||
"deleteTitle": "Delete skill?",
|
||||
"deleteDescription": "This skill and its configuration will be permanently removed.",
|
||||
"deleteTitle": "Delete \"{{name}}\" permanently?",
|
||||
"category": "Category",
|
||||
"categories": {
|
||||
"clear": "Clear categories",
|
||||
@@ -36,7 +36,7 @@
|
||||
"writing": "Writing"
|
||||
}
|
||||
},
|
||||
"description": "Skills are reusable instructions that help an agent handle specific tasks, workflows, or tools.",
|
||||
"description": "Use skills to add specific instructions or behaviors to any agent.",
|
||||
"detailEmptyDescription": "Select a skill to inspect its source, location, and instructions.",
|
||||
"detailEmptyTitle": "Choose a skill",
|
||||
"dropFile": "or drop a file",
|
||||
@@ -49,8 +49,8 @@
|
||||
"instructions": "Instructions",
|
||||
"location": "Location",
|
||||
"more": "More",
|
||||
"newSkill": "New Skill",
|
||||
"noMatchesDescription": "Try a different search or filter.",
|
||||
"newSkill": "New skill",
|
||||
"noMatchesDescription": "Try a different search term.",
|
||||
"noMatchesTitle": "No matching skills",
|
||||
"openDetails": "Open {{name}} details",
|
||||
"projects": "Projects",
|
||||
|
||||
@@ -68,8 +68,8 @@
|
||||
"view": {
|
||||
"copyName": "{{name}} (Copia)",
|
||||
"deleteFailed": "No se pudo eliminar el agente.",
|
||||
"deleteDescription": "¿Seguro que quieres eliminar \"{{name}}\"? Esto no se puede deshacer.",
|
||||
"deleteTitle": "¿Eliminar agente?",
|
||||
"deleteDescription": "Este agente y su configuración se eliminarán de forma permanente.",
|
||||
"deleteTitle": "¿Eliminar \"{{name}}\" de forma permanente?",
|
||||
"deleted": "Se eliminó \"{{name}}\".",
|
||||
"description": "Configuraciones de agente personalizadas para flujos de trabajo específicos",
|
||||
"emptyAgentsDescription": "Crea un agente para empezar.",
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
"empty": {
|
||||
"folderNotSet": "Carpeta no configurada",
|
||||
"noChanges": "No hay cambios sin confirmar",
|
||||
"noProjectAssigned": "No hay proyecto asignado.",
|
||||
"noProjectAssigned": "No hay proyecto asignado",
|
||||
"noExtensions": "No hay extensiones habilitadas",
|
||||
"noMatchingExtensions": "No hay extensiones que coincidan"
|
||||
},
|
||||
@@ -59,7 +59,8 @@
|
||||
"checkedOutBranch": "{{branch}}",
|
||||
"currentBranch": "Rama actual",
|
||||
"dirtyTitle": "Cambios sin confirmar",
|
||||
"dirtyDescription": "Tienes {{count}} cambio(s) sin confirmar. ¿Cómo deseas proceder?",
|
||||
"dirtyDescription_one": "Tienes {{count}} cambio sin confirmar. ¿Cómo deseas proceder?",
|
||||
"dirtyDescription_other": "Tienes {{count}} cambios sin confirmar. ¿Cómo deseas proceder?",
|
||||
"stashAndSwitch": "Guardar y cambiar",
|
||||
"carryChanges": "Llevar a la rama",
|
||||
"cancel": "Cancelar",
|
||||
@@ -96,19 +97,19 @@
|
||||
}
|
||||
},
|
||||
"files": {
|
||||
"empty": "Los archivos del proyecto no están disponibles hasta que se asigne un proyecto con directorios de trabajo.",
|
||||
"empty": "Los archivos aparecerán aquí después de asignar un proyecto.",
|
||||
"folderEmpty": "La carpeta está vacía",
|
||||
"loadError": "No se pudo cargar el contenido de la carpeta.",
|
||||
"loadError": "No se pudo cargar esta carpeta. Inténtalo de nuevo.",
|
||||
"loading": "Cargando archivos...",
|
||||
"openFolder": "Abrir carpeta: {{path}}",
|
||||
"rootLoadError": "No se pudo cargar esta carpeta."
|
||||
"rootLoadError": "No se pudo cargar esta carpeta. Inténtalo de nuevo."
|
||||
},
|
||||
"image": {
|
||||
"view": "Ver {{label}}"
|
||||
},
|
||||
"input": {
|
||||
"ariaLabel": "Entrada de mensaje del chat",
|
||||
"placeholder": "Enviar mensaje a {{agent}}, usa @ para mencionar agentes o habilidades"
|
||||
"placeholder": "Chatea con {{agent}} o usa @ para mencionar un agente"
|
||||
},
|
||||
"loading": {
|
||||
"compacting": "Compactando conversación...",
|
||||
|
||||
@@ -46,8 +46,8 @@
|
||||
"useWorktrees": "Usar git worktrees para aislar ramas"
|
||||
},
|
||||
"view": {
|
||||
"deleteDescription": "¿Seguro que quieres eliminar \"{{name}}\"? Esto no se puede deshacer.",
|
||||
"deleteTitle": "¿Eliminar proyecto?",
|
||||
"deleteDescription": "Este proyecto y todos sus datos se eliminarán de forma permanente.",
|
||||
"deleteTitle": "¿Eliminar \"{{name}}\" de forma permanente?",
|
||||
"description": "Organiza tu trabajo en contextos de proyecto enfocados",
|
||||
"emptyDescription": "Crea un proyecto para organizar tu trabajo.",
|
||||
"emptyTitle": "Aún no hay proyectos",
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
"emptyNoMatchesHint": "Prueba con otro término de búsqueda.",
|
||||
"emptyTitle": "Aún no hay sesiones",
|
||||
"searchArchivedPlaceholder": "Buscar sesiones archivadas...",
|
||||
"searchError": "La búsqueda de mensajes falló. Mostrando solo coincidencias por título, agente y proyecto.",
|
||||
"searchPlaceholder": "Buscar conversaciones",
|
||||
"searchError": "La búsqueda de mensajes falló. Mostrando solo coincidencias por título, agente y proyecto. Inténtalo de nuevo.",
|
||||
"searchPlaceholder": "Buscar sesiones...",
|
||||
"searching": "Buscando sesiones...",
|
||||
"subtitle": "Explora y busca sesiones anteriores",
|
||||
"toggleArchived": "Archivadas",
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
"spacious": "Espaciosa"
|
||||
}
|
||||
},
|
||||
"description": "Personaliza el aspecto de Goose",
|
||||
"theme": {
|
||||
"description": "Elige tu esquema de color preferido",
|
||||
"label": "Tema",
|
||||
@@ -70,8 +69,8 @@
|
||||
"title": "Compactación"
|
||||
},
|
||||
"deleteProject": {
|
||||
"description": "¿Seguro que quieres eliminar permanentemente \"{{name}}\"? Esta acción no se puede deshacer.",
|
||||
"title": "¿Eliminar el proyecto de forma permanente?"
|
||||
"description": "Este proyecto y todos sus datos se eliminarán de forma permanente.",
|
||||
"title": "¿Eliminar \"{{name}}\" de forma permanente?"
|
||||
},
|
||||
"extensions": {
|
||||
"title": "Extensiones",
|
||||
@@ -125,10 +124,10 @@
|
||||
"agents": "Agentes",
|
||||
"copied": "Copiado",
|
||||
"copyDetails": "Copiar detalles",
|
||||
"description": "Verifica las herramientas necesarias y la disponibilidad de agentes para Goose.",
|
||||
"empty": "Todavía no hay comprobaciones disponibles.",
|
||||
"rerun": "Volver a ejecutar",
|
||||
"runFix": "¿Ejecutar el comando de corrección?",
|
||||
"rerun": "Volver a intentar",
|
||||
"runFix": "¿Ejecutar corrección?",
|
||||
"runFixDescription": "Esto ejecutará el siguiente comando:",
|
||||
"running": "Ejecutando comprobaciones...",
|
||||
"title": "Diagnóstico",
|
||||
"tools": "Herramientas"
|
||||
@@ -206,7 +205,7 @@
|
||||
},
|
||||
"providers": {
|
||||
"agents": {
|
||||
"description": "Los agentes manejan tus solicitudes usando sus propias herramientas y modelos",
|
||||
"description": "Goose está integrado en tu espacio de trabajo. Instala otros para ampliar tu configuración.",
|
||||
"errors": {
|
||||
"installVerificationFailed": "La instalación terminó, pero no se encontró la CLI en PATH. Puede que tengas que reiniciar tu terminal."
|
||||
},
|
||||
@@ -225,10 +224,9 @@
|
||||
},
|
||||
"title": "Arneses de agentes"
|
||||
},
|
||||
"description": "Conecta agentes y modelos de IA para usar con Goose",
|
||||
"disconnect": "Desconectar",
|
||||
"models": {
|
||||
"description": "Modelos de IA que alimentan a Goose. Expande un proveedor para revisar lo que necesita. Conectar inicia sesión con una cuenta existente, mientras que Configurar guarda claves API u otros ajustes del proveedor.",
|
||||
"description": "Necesitas al menos un proveedor de modelos para usar el agente Goose. Algunos agentes pueden traer sus propias conexiones de modelo.",
|
||||
"notSet": "No configurado",
|
||||
"setup": {
|
||||
"connected": {
|
||||
@@ -238,17 +236,17 @@
|
||||
"oauthDeviceCode": "Conectado mediante el inicio de sesión por código de dispositivo de Goose."
|
||||
},
|
||||
"fieldDescription": {
|
||||
"cloudCredentials": "La configuración guarda aquí cualquier detalle del proveedor que Goose necesite. Tu autenticación real sigue viniendo de tus credenciales de nube.",
|
||||
"configFields": "La configuración guarda los detalles del proveedor que Goose necesita, como una clave API, un endpoint o ajustes del modelo.",
|
||||
"hostWithOauthFallback": "La configuración guarda aquí los detalles del host que Goose necesita. Puedes añadir un token ahora o dejarlo en blanco e iniciar sesión después desde Goose.",
|
||||
"singleApiKey": "La configuración guarda la clave API que Goose necesita para este proveedor."
|
||||
"cloudCredentials": "Agrega los datos requeridos para usar este proveedor.",
|
||||
"configFields": "Agrega los datos requeridos para usar este proveedor.",
|
||||
"hostWithOauthFallback": "Agrega los datos requeridos para usar este proveedor.",
|
||||
"singleApiKey": "Agrega tu clave API para usar este proveedor."
|
||||
},
|
||||
"hostWithOauthFallbackTerminal": "Deja en blanco el token de acceso, guarda la URL del host y luego ejecuta `goose configure` en tu terminal para iniciar sesión.",
|
||||
"nativeConnectDescription": "Inicia sesión con tu cuenta existente.",
|
||||
"pending": {
|
||||
"cloudCredentials": "Configura tus credenciales de nube en el entorno de tu terminal antes de usar este proveedor.",
|
||||
"local": "Este proveedor se ejecuta localmente y no necesita ajustes guardados aquí.",
|
||||
"oauthGuided": "Goose te guiará por el inicio de sesión desde aquí.",
|
||||
"local": "Este proveedor se ejecuta localmente y no necesita ajustes guardados.",
|
||||
"oauthGuided": "Goose te guiará por el inicio de sesión.",
|
||||
"oauthTerminal": "Ejecuta `goose configure` en tu terminal para terminar de iniciar sesión."
|
||||
}
|
||||
},
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
"skills": "Habilidades"
|
||||
},
|
||||
"search": {
|
||||
"error": "La búsqueda de mensajes falló. Mostrando solo coincidencias de metadatos.",
|
||||
"placeholder": "Buscar conversaciones",
|
||||
"error": "La búsqueda de mensajes falló. Mostrando solo coincidencias de metadatos. Inténtalo de nuevo.",
|
||||
"placeholder": "Buscar chats...",
|
||||
"searching": "Buscando chats..."
|
||||
},
|
||||
"sections": {
|
||||
|
||||
@@ -34,8 +34,8 @@
|
||||
"writing": "Redacción"
|
||||
}
|
||||
},
|
||||
"deleteDescription": "¿Seguro que quieres eliminar \"{{name}}\"? Esto no se puede deshacer.",
|
||||
"deleteTitle": "¿Eliminar skill?",
|
||||
"deleteDescription": "Esta habilidad y su configuración se eliminarán de forma permanente.",
|
||||
"deleteTitle": "¿Eliminar \"{{name}}\" de forma permanente?",
|
||||
"description": "Las skills son instrucciones reutilizables que ayudan a un agente a manejar tareas, flujos de trabajo o herramientas específicas.",
|
||||
"detailEmptyDescription": "Selecciona una skill para inspeccionar su origen, ubicación e instrucciones.",
|
||||
"detailEmptyTitle": "Elige una skill",
|
||||
|
||||
@@ -205,9 +205,13 @@ test.describe("Agents view", () => {
|
||||
await card.getByLabel("Agent options").click();
|
||||
await page.getByRole("menuitem", { name: "Delete" }).click();
|
||||
|
||||
await expect(page.getByText("Delete agent?")).toBeVisible();
|
||||
await expect(
|
||||
page.getByText(/Are you sure you want to delete.*Code Reviewer/),
|
||||
page.getByText('Delete "Code Reviewer" permanently?'),
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.getByText(
|
||||
"This agent and its configuration will be permanently removed.",
|
||||
),
|
||||
).toBeVisible();
|
||||
await expect(page.getByRole("button", { name: "Cancel" })).toBeVisible();
|
||||
await expect(page.getByRole("button", { name: "Delete" })).toBeVisible();
|
||||
@@ -221,14 +225,18 @@ test.describe("Agents view", () => {
|
||||
const card = page.getByLabel("Agent: Code Reviewer");
|
||||
await card.getByLabel("Agent options").click();
|
||||
await page.getByRole("menuitem", { name: "Delete" }).click();
|
||||
await expect(page.getByText("Delete agent?")).toBeVisible();
|
||||
await expect(
|
||||
page.getByText('Delete "Code Reviewer" permanently?'),
|
||||
).toBeVisible();
|
||||
|
||||
const confirmDialog = page.locator(".max-w-sm", {
|
||||
has: page.getByText("Delete agent?"),
|
||||
has: page.getByText('Delete "Code Reviewer" permanently?'),
|
||||
});
|
||||
await confirmDialog.getByRole("button", { name: "Cancel" }).click();
|
||||
|
||||
await expect(page.getByText("Delete agent?")).not.toBeVisible();
|
||||
await expect(
|
||||
page.getByText('Delete "Code Reviewer" permanently?'),
|
||||
).not.toBeVisible();
|
||||
await expect(page.getByLabel("Agent: Code Reviewer")).toBeVisible();
|
||||
});
|
||||
|
||||
|
||||
@@ -13,10 +13,10 @@ test.describe("Skills view", () => {
|
||||
|
||||
await expect(page.locator("h1", { hasText: "Skills" })).toBeVisible();
|
||||
await expect(
|
||||
page.getByText(/Skills are reusable instructions/),
|
||||
page.getByText(/Use skills to add specific instructions/),
|
||||
).toBeVisible();
|
||||
await expect(page.getByRole("button", { name: "Import" })).toBeVisible();
|
||||
await expect(page.getByRole("button", { name: "New Skill" })).toBeVisible();
|
||||
await expect(page.getByRole("button", { name: "New skill" })).toBeVisible();
|
||||
});
|
||||
|
||||
test("shows skills in the list and opens a dedicated detail page", async ({
|
||||
|
||||
@@ -21,7 +21,7 @@ test.describe("Smoke tests", () => {
|
||||
await page.goto("/");
|
||||
|
||||
await expect(
|
||||
page.getByPlaceholder(/Message .*, @ to mention agents/),
|
||||
page.getByPlaceholder(/Chat with .* or @ mention an agent/),
|
||||
).toBeVisible({ timeout: 10_000 });
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user