дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-09 03:05:40 +02:00
fix(agents): sign-in hint names the CLI the IDE actually runs (#2018)
Fixes #1913. The sign-in hint named the bare command (`cursor-agent login`), but the IDE launches agents through its own resolution (registry installs under the config dir, the login shell's PATH, PATHEXT shims), so the named command could be missing from the terminal's PATH. The agent spec is now resolved once before connecting, and when that executable isn't what a PATH lookup of the bare name finds, every built-in hint names the resolved path, quoted for PowerShell or POSIX shells. Hints for separate login tools (claude-acp, codex-acp, vibe) and custom agents are unchanged; the hint is translated through templates.
Цей коміт міститься в:
1 джерело
ebc1c21836
коміт
8509ca671f
10 files changed
+242
-12
No files matched your search
@@ -1,7 +1,7 @@
|
||||
/** Built-in launch settings; each executable is staged independently until Apply. */
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import type { AgentProvider } from "@/bindings";
|
||||
import { tx, useTx } from "@/platform/i18n";
|
||||
import { tx, useTxTemplate } from "@/platform/i18n";
|
||||
import clsx from "clsx";
|
||||
import { Button, Icon, IconButton, Input, List, Spinner, T } from "@/ui";
|
||||
import { useSettingsForm } from "@/workbench/contributions";
|
||||
@@ -242,7 +242,7 @@ const formatEnv = (env: Record<string, string>) =>
|
||||
|
||||
/** Login hints are plain text with optional backtick-delimited command spans. */
|
||||
function LoginHint({ text }: { text: string }) {
|
||||
const translate = useTx();
|
||||
const translate = useTxTemplate();
|
||||
return translate(text)
|
||||
.split(/(`[^`]+`)/g)
|
||||
.map((part, i) => (i % 2 === 1 ? <code key={i}>{part.slice(1, -1)}</code> : part));
|
||||
|
||||
@@ -58,6 +58,7 @@ import { findRanges, formatDuration, formatSentAt } from "./conversation";
|
||||
import { ImagePreview, imageSrc } from "./ImagePreview";
|
||||
import { AgentReply } from "./AgentReply";
|
||||
import { Markdown } from "./Markdown";
|
||||
import { useAgentErrorText } from "./loginHint";
|
||||
import {
|
||||
branchLabel,
|
||||
entriesKey,
|
||||
@@ -866,12 +867,16 @@ const Entry = memo(function Entry({
|
||||
return (
|
||||
<div className={styles.error} role="alert">
|
||||
<Icon name="error" size={14} />
|
||||
<span>{entry.message}</span>
|
||||
<AgentErrorText message={entry.message} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
function AgentErrorText({ message }: { message: string }) {
|
||||
return <span>{useAgentErrorText(message)}</span>;
|
||||
}
|
||||
|
||||
function UserMessage({
|
||||
task,
|
||||
entry,
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
import { renderHook } from "@testing-library/react";
|
||||
import { afterEach, expect, it } from "vitest";
|
||||
import { _resetI18nForTests, setLocale } from "@/platform/i18n";
|
||||
import { useAgentErrorText } from "./loginHint";
|
||||
|
||||
afterEach(() => _resetI18nForTests());
|
||||
|
||||
it.each([
|
||||
["Run `cursor-agent login` in a terminal.", "在终端中运行 `cursor-agent login`。"],
|
||||
["Run `'/registry path/cursor-agent' login` in a terminal.", "在终端中运行 `'/registry path/cursor-agent' login`。"],
|
||||
[
|
||||
"Run `& 'C:\\Agent Tools\\cursor-agent.cmd' login` in a terminal.",
|
||||
"在终端中运行 `& 'C:\\Agent Tools\\cursor-agent.cmd' login`。",
|
||||
],
|
||||
["Run `'/registry/claude'` in a terminal and sign in.", "在终端中运行 `'/registry/claude'` 并登录。"],
|
||||
])("translates sign-in guidance with its command intact: %s", async (hint, translated) => {
|
||||
await setLocale("zh");
|
||||
const { result } = renderHook(() => useAgentErrorText(`Cursor needs you to sign in. ${hint}`));
|
||||
expect(result.current).toBe(`Cursor 需要你登录。${translated}`);
|
||||
});
|
||||
|
||||
it("preserves external agent errors", async () => {
|
||||
await setLocale("zh");
|
||||
const { result } = renderHook(() => useAgentErrorText("Agent says: authentication failed"));
|
||||
expect(result.current).toBe("Agent says: authentication failed");
|
||||
});
|
||||
@@ -0,0 +1,9 @@
|
||||
import { useTx, useTxTemplate } from "@/platform/i18n";
|
||||
|
||||
/** Translate the IDE's sign-in guidance while preserving the agent's own errors. */
|
||||
export function useAgentErrorText(message: string): string {
|
||||
const tx = useTx();
|
||||
const translate = useTxTemplate();
|
||||
const auth = /^(.+) needs you to sign in\. (.+)$/s.exec(message);
|
||||
return auth ? tx`${auth[1]} needs you to sign in. ${translate(auth[2]!)}` : message;
|
||||
}
|
||||
@@ -1,4 +1,7 @@
|
||||
{
|
||||
"Run `{command}` in a terminal.": "Run `{command}` in a terminal.",
|
||||
"Run `{command}` in a terminal and sign in.": "Run `{command}` in a terminal and sign in.",
|
||||
"{name} needs you to sign in. {hint}": "{name} needs you to sign in. {hint}",
|
||||
"OpenIDEA or JetBrains settings": "OpenIDEA or JetBrains settings",
|
||||
"Import JetBrains Settings": "Import JetBrains Settings",
|
||||
"These settings will be imported:": "These settings will be imported:",
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
{
|
||||
"Run `{command}` in a terminal.": "在终端中运行 `{command}`。",
|
||||
"Run `{command}` in a terminal and sign in.": "在终端中运行 `{command}` 并登录。",
|
||||
"{name} needs you to sign in. {hint}": "{name} 需要你登录。{hint}",
|
||||
"Cannot copy reference": "无法复制引用",
|
||||
"Group actions": "分组操作",
|
||||
"New Project Group": "新建项目组",
|
||||
|
||||
Reference in new issue
Заблокувати користувача