From 522e88a6a25f1f89c27077af763d35204460a470 Mon Sep 17 00:00:00 2001 From: Jerry Yan <792602257@qq.com> Date: Fri, 12 Jun 2026 13:36:39 +0800 Subject: [PATCH] =?UTF-8?q?=E5=89=8D=E7=AB=AF=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/src/api/client.ts | 7 ++++++- web/src/components/acp/AgentKindForm.vue | 12 ++++++++---- web/src/utils/markdown.ts | 3 +++ web/src/views/chat/ChatDetailView.vue | 1 + .../views/chat/components/MessageBubble.vue | 5 +---- .../projects/components/ArtifactPanel.vue | 4 +--- .../components/RequirementChatPanel.vue | 1 + .../components/RequirementHistoryPanel.vue | 3 +-- .../components/RequirementSummaryPanel.vue | 4 +--- .../projects/components/SaveArtifactModal.vue | 3 +-- web/vite.config.ts | 18 ++++++++++++++++++ 11 files changed, 42 insertions(+), 19 deletions(-) create mode 100644 web/src/utils/markdown.ts diff --git a/web/src/api/client.ts b/web/src/api/client.ts index edb0e1d..a7c1503 100644 --- a/web/src/api/client.ts +++ b/web/src/api/client.ts @@ -34,11 +34,13 @@ export async function request(path: string, opts: RequestOptions = {}): Promi const controller = new AbortController() const timer = setTimeout(() => controller.abort(), DEFAULT_TIMEOUT_MS) + let onAbort: (() => void) | undefined if (opts.signal) { if (opts.signal.aborted) { controller.abort() } else { - opts.signal.addEventListener('abort', () => controller.abort(), { once: true }) + onAbort = () => controller.abort() + opts.signal.addEventListener('abort', onAbort, { once: true }) } } @@ -78,6 +80,9 @@ export async function request(path: string, opts: RequestOptions = {}): Promi return data as T } finally { clearTimeout(timer) + if (opts.signal && onAbort) { + opts.signal.removeEventListener('abort', onAbort) + } } } diff --git a/web/src/components/acp/AgentKindForm.vue b/web/src/components/acp/AgentKindForm.vue index 80e64ca..c8fcae1 100644 --- a/web/src/components/acp/AgentKindForm.vue +++ b/web/src/components/acp/AgentKindForm.vue @@ -57,11 +57,12 @@ const allowlistText = computed({ }) interface EnvRow { + id: string k: string v: string } const envEntries = ref( - Object.entries(local.value.env).map(([k, v]) => ({ k, v })), + Object.entries(local.value.env).map(([k, v]) => ({ id: crypto.randomUUID(), k, v })), ) watch( @@ -77,7 +78,7 @@ watch( ) function addEnv() { - envEntries.value.push({ k: '', v: '' }) + envEntries.value.push({ id: crypto.randomUUID(), k: '', v: '' }) } function removeEnv(idx: number) { envEntries.value.splice(idx, 1) @@ -94,6 +95,7 @@ const mcpTypeOptions = [ ] interface McpRow { + id: string name: string type: 'stdio' | 'http' | 'sse' command: string @@ -123,6 +125,7 @@ function parseKV(s: string): Record | undefined { function specsToRows(specs: McpServerSpec[]): McpRow[] { return specs.map((s) => ({ + id: crypto.randomUUID(), name: s.name, type: s.type, command: s.command ?? '', @@ -173,6 +176,7 @@ watch( function addMcpServer() { mcpRows.value.push({ + id: crypto.randomUUID(), name: '', type: 'http', command: '', @@ -258,7 +262,7 @@ function removeMcpServer(idx: number) {

diff --git a/web/src/utils/markdown.ts b/web/src/utils/markdown.ts new file mode 100644 index 0000000..b90c77b --- /dev/null +++ b/web/src/utils/markdown.ts @@ -0,0 +1,3 @@ +import MarkdownIt from 'markdown-it' + +export const md = new MarkdownIt({ html: false, breaks: true, linkify: true }) diff --git a/web/src/views/chat/ChatDetailView.vue b/web/src/views/chat/ChatDetailView.vue index b3e57ce..6995e8d 100644 --- a/web/src/views/chat/ChatDetailView.vue +++ b/web/src/views/chat/ChatDetailView.vue @@ -94,6 +94,7 @@ diff --git a/web/src/views/chat/components/MessageBubble.vue b/web/src/views/chat/components/MessageBubble.vue index f294561..f4a4c10 100644 --- a/web/src/views/chat/components/MessageBubble.vue +++ b/web/src/views/chat/components/MessageBubble.vue @@ -93,13 +93,10 @@