From ba52f3ca39e648df8042f55684a0ac5088a5787b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 21 Jul 2026 02:18:50 +0000 Subject: [PATCH 1/7] Initial plan From 528244fa97163ef032a1a337ff7a478c36c236fc Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 21 Jul 2026 02:29:28 +0000 Subject: [PATCH 2/7] Plan chat scope routing flow --- .../cache/miniflare-CacheObject/metadata.sqlite | Bin 0 -> 4096 bytes .../miniflare-CacheObject/metadata.sqlite-shm | Bin 0 -> 32768 bytes .../miniflare-CacheObject/metadata.sqlite-wal | Bin 0 -> 8272 bytes ...le-to-be-interrupted-and-recover-state-1.png | Bin 0 -> 2901 bytes ...hon-Runtime-REPL-should-capture-errors-1.png | Bin 0 -> 2901 bytes ...ould-capture-files-modified-by-command-1.png | Bin 0 -> 2901 bytes ...hon-Runtime-REPL-should-capture-stdout-1.png | Bin 0 -> 2901 bytes ...uld-preserve-variables-across-commands-1.png | Bin 0 -> 2901 bytes 8 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 .wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite create mode 100644 .wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite-shm create mode 100644 .wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite-wal create mode 100644 packages/runtime/tests/__screenshots__/vitest-all.tsx/Runtime-Integration-Tests-python-Runtime-REPL-should-be-able-to-be-interrupted-and-recover-state-1.png create mode 100644 packages/runtime/tests/__screenshots__/vitest-all.tsx/Runtime-Integration-Tests-python-Runtime-REPL-should-capture-errors-1.png create mode 100644 packages/runtime/tests/__screenshots__/vitest-all.tsx/Runtime-Integration-Tests-python-Runtime-REPL-should-capture-files-modified-by-command-1.png create mode 100644 packages/runtime/tests/__screenshots__/vitest-all.tsx/Runtime-Integration-Tests-python-Runtime-REPL-should-capture-stdout-1.png create mode 100644 packages/runtime/tests/__screenshots__/vitest-all.tsx/Runtime-Integration-Tests-python-Runtime-REPL-should-preserve-variables-across-commands-1.png diff --git a/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite b/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..0b58f0dca7d6ce95907cb0b322dc4802f04688c0 GIT binary patch literal 4096 zcmWFz^vNtqRY=P(%1ta$FlG>7U}9o$P*7lCU|@t|AVoG{WYDXN;00+HAlr;ljiVtj n8UmvsFd71*Aut*OqaiRF0;3@?8UmvsFd71*Aut*O6ovo**AfQj literal 0 HcmV?d00001 diff --git a/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite-shm b/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite-shm new file mode 100644 index 0000000000000000000000000000000000000000..775cddfb1929a9f23883f7cff213dd55b4977942 GIT binary patch literal 32768 zcmeI)u?fOJ6b9g!2`ns9SPI&>gChh43AQ$_V4o!{EP?|#geznM7m0Z$h;2IIz8@Y3 z$K#Isu7AaAn?+_r&GUYZYL@MzJl551vpU@`i$nc9H|yPXUrg-pkNPCe?0zzCf0wvF zdV~N00t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyKp-W7m^vW@(iAXnCCz{LY61iZ5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK;XXx-fegy A?EnA( literal 0 HcmV?d00001 diff --git a/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite-wal b/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite-wal new file mode 100644 index 0000000000000000000000000000000000000000..20e9df52f9f6c2a22048ae5e0e4663fba1ebf974 GIT binary patch literal 8272 zcmXr7XKP~6eI&uaAiw|ub2U_w7gvgeS#WD_aAU9e0Tg0H7N5I$8Dr^hi9^AGKA9z{ z3TgR8xrrqT#z5UnObiYR3P80?Pz=%r0wDb?U>1Y`n}@{5#$;m9tBc?T$}sYmFaXgg z7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fe{k|jhu|^;_~v0jfo|RNja(U z$!YP9K8``Ya0ZiekgH>et3rsQlaH$cTv$PaO92cLlS}f8;xkheLR=$46as=geI0`$ z6}(*|b)X80lQU9NN^??E;!84fQx!b@LR{TlgTRuS3gMn19{!;r3PJwio-V*Z2lw+~ z;|1%l$SjO#i3;EX#Rg<3VZ_ACs7FUbU^E0qLtr!nMnhmU1V%$(Gz3ONU^E0qLtr!n KMnhnvg#Z92g+zM* literal 0 HcmV?d00001 diff --git a/packages/runtime/tests/__screenshots__/vitest-all.tsx/Runtime-Integration-Tests-python-Runtime-REPL-should-be-able-to-be-interrupted-and-recover-state-1.png b/packages/runtime/tests/__screenshots__/vitest-all.tsx/Runtime-Integration-Tests-python-Runtime-REPL-should-be-able-to-be-interrupted-and-recover-state-1.png new file mode 100644 index 0000000000000000000000000000000000000000..f1c5529decfa5731cc68f21093466f2f91c1d674 GIT binary patch literal 2901 zcmeAS@N?(olHy`uVBq!ia0y~yV4TOmz}&#W1QcnFZJNcvz|H09;uumf=gk#HUIqh> z0|uY&>`(o$af{Ng@^Xf#dkjxj@Nxu63oJ2H@W^$TaH~OKE2Co;bJGR0%nX}OaxtWKtgr%# OFnGH9xvX z0|uY&>`(o$af{Ng@^Xf#dkjxj@Nxu63oJ2H@W^$TaH~OKE2Co;bJGR0%nX}OaxtWKtgr%# OFnGH9xvX z0|uY&>`(o$af{Ng@^Xf#dkjxj@Nxu63oJ2H@W^$TaH~OKE2Co;bJGR0%nX}OaxtWKtgr%# OFnGH9xvX z0|uY&>`(o$af{Ng@^Xf#dkjxj@Nxu63oJ2H@W^$TaH~OKE2Co;bJGR0%nX}OaxtWKtgr%# OFnGH9xvX z0|uY&>`(o$af{Ng@^Xf#dkjxj@Nxu63oJ2H@W^$TaH~OKE2Co;bJGR0%nX}OaxtWKtgr%# OFnGH9xvX Date: Tue, 21 Jul 2026 02:31:44 +0000 Subject: [PATCH 3/7] Add language-wide chat scope with page routing --- app/(docs)/@docs/[lang]/[pageId]/chatForm.tsx | 49 ++++++-- .../@docs/[lang]/[pageId]/pageContent.tsx | 1 + app/api/chat/route.ts | 107 +++++++++++++++--- 3 files changed, 133 insertions(+), 24 deletions(-) diff --git a/app/(docs)/@docs/[lang]/[pageId]/chatForm.tsx b/app/(docs)/@docs/[lang]/[pageId]/chatForm.tsx index 24c489dd..e707d047 100644 --- a/app/(docs)/@docs/[lang]/[pageId]/chatForm.tsx +++ b/app/(docs)/@docs/[lang]/[pageId]/chatForm.tsx @@ -24,13 +24,17 @@ import { captureException } from "@sentry/nextjs"; interface ChatFormProps { path: PagePath; + langName: string; sectionContent: DynamicMarkdownSection[]; close: () => void; } -export function ChatForm({ path, sectionContent, close }: ChatFormProps) { +export function ChatForm({ path, langName, sectionContent, close }: ChatFormProps) { // const [messages, updateChatHistory] = useChatHistory(sectionId); const [inputValue, setInputValue] = useState(""); + const [questionScope, setQuestionScope] = useState<"page" | "language">( + "page" + ); const [isLoading, setIsLoading] = useState(false); const [errorMessage, setErrorMessage] = useState(null); @@ -115,6 +119,7 @@ export function ChatForm({ path, sectionContent, close }: ChatFormProps) { body: JSON.stringify({ path, userQuestion, + questionScope, sectionContent, replOutputs, files, @@ -138,6 +143,7 @@ export function ChatForm({ path, sectionContent, close }: ChatFormProps) { const decoder = new TextDecoder(); let buffer = ""; let chatId: string | null = null; + let chatPagePath: string | PagePath = path; let navigated = false; // ストリームを非同期で読み続ける(ナビゲーション後もバックグラウンドで継続) @@ -158,13 +164,16 @@ export function ChatForm({ path, sectionContent, close }: ChatFormProps) { const event = JSON.parse(line) as ChatStreamEvent; if (event.type === "chat") { + chatPagePath = event.pagePath; // revalidateChatは/api/chatの中では呼ばず、別のServerActionとして呼び出す - await revalidateChatAction(event.chatId, path); + await revalidateChatAction(event.chatId, event.pagePath); chatId = event.chatId; streamingChatContext.startStreaming(event.chatId); - document.getElementById(event.sectionId)?.scrollIntoView({ - behavior: "smooth", - }); + if (event.pagePath === `${path.lang}/${path.page}`) { + document.getElementById(event.sectionId)?.scrollIntoView({ + behavior: "smooth", + }); + } await asyncRouterPush(`/chat/${event.chatId}`, { scroll: false, }); @@ -177,7 +186,7 @@ export function ChatForm({ path, sectionContent, close }: ChatFormProps) { streamingChatContext.appendChunk(event.text); } else if (event.type === "done") { if (chatId) { - await revalidateChatAction(chatId, path); + await revalidateChatAction(chatId, chatPagePath); } streamingChatContext.finishStreaming(); router.refresh(); @@ -187,7 +196,7 @@ export function ChatForm({ path, sectionContent, close }: ChatFormProps) { setIsLoading(false); } if (chatId) { - await revalidateChatAction(chatId, path); + await revalidateChatAction(chatId, chatPagePath); } streamingChatContext.finishStreaming(); router.refresh(); @@ -238,6 +247,32 @@ export function ChatForm({ path, sectionContent, close }: ChatFormProps) { onChange={(e) => setInputValue(e.target.value)} disabled={isLoading} > +
+ + +
setIsFormVisible(false)} /> diff --git a/app/api/chat/route.ts b/app/api/chat/route.ts index 5c8a5b99..f2fed0d0 100644 --- a/app/api/chat/route.ts +++ b/app/api/chat/route.ts @@ -8,6 +8,7 @@ import { } from "@/lib/chatHistory"; import { DynamicMarkdownSectionSchema, + getMarkdownSections, getPagesList, introSectionId, PagePathSchema, @@ -23,6 +24,7 @@ import { captureException } from "@sentry/nextjs"; const ChatParamsSchema = z.object({ path: PagePathSchema, userQuestion: z.string().min(1), + questionScope: z.enum(["page", "language"]).default("page"), sectionContent: z.array(DynamicMarkdownSectionSchema), replOutputs: z.record(z.string(), z.array(ReplCommandSchema)), files: z.record(z.string(), z.string()), @@ -30,7 +32,7 @@ const ChatParamsSchema = z.object({ }); export type ChatStreamEvent = - | { type: "chat"; chatId: string; sectionId: string } + | { type: "chat"; chatId: string; sectionId: string; pagePath: string } | { type: "chunk"; text: string } | { type: "done" } | { type: "error"; message: string }; @@ -48,6 +50,7 @@ export async function POST(request: NextRequest) { const { path, userQuestion, + questionScope, sectionContent, replOutputs, files, @@ -55,7 +58,71 @@ export async function POST(request: NextRequest) { } = parseResult.data; const pagesList = await getPagesList(); - const langName = pagesList.find((lang) => lang.id === path.lang)?.name; + const langEntry = pagesList.find((lang) => lang.id === path.lang); + const langName = langEntry?.name ?? path.lang; + let targetPath = path; + let targetSectionContent = sectionContent; + + if (questionScope === "language" && langEntry) { + const routePrompt: string[] = []; + routePrompt.push( + `あなたは${langName}言語チュートリアルの質問ルーターです。ユーザーの質問に最も関連するページslugを選んでください。` + ); + routePrompt.push(``); + routePrompt.push("# 指示"); + routePrompt.push( + "- 1行目にページslugのみを出力してください(引用符や補足説明は不要です)。" + ); + routePrompt.push( + "- どのページにも関連しない場合は null と出力してください。" + ); + routePrompt.push(``); + routePrompt.push("# 目次"); + routePrompt.push(``); + for (const page of langEntry.pages) { + const sections = await getMarkdownSections(path.lang, page.slug); + const sectionTitles = sections + .map((s) => s.title.trim()) + .filter((title) => title.length > 0) + .join(" / "); + routePrompt.push( + `- slug: ${page.slug} | 章題: ${page.title} | セクション: ${sectionTitles}` + ); + } + routePrompt.push(``); + routePrompt.push(`# ユーザーの質問`); + routePrompt.push(userQuestion); + routePrompt.push(``); + routePrompt.push(`# 回答`); + + let routeResult = ""; + for await (const chunk of generateContentStream( + userQuestion, + routePrompt.join("\n") + )) { + routeResult += chunk; + } + const selectedPageSlug = routeResult + .trim() + .split(/\s+/)[0] + ?.trim() as typeof path.page | undefined; + if (langEntry.pages.some((page) => page.slug === selectedPageSlug)) { + targetPath = { + lang: path.lang, + page: selectedPageSlug, + }; + const routedSections = await getMarkdownSections( + targetPath.lang, + targetPath.page + ); + targetSectionContent = routedSections.map((section) => ({ + ...section, + inView: false, + replacedContent: section.rawContent, + replacedRange: [], + })); + } + } const prompt: string[] = []; @@ -64,16 +131,21 @@ export async function POST(request: NextRequest) { `以下の${langName}チュートリアルのドキュメントの内容を正確に理解し、ユーザーからの質問に対して、初心者にも分かりやすく、丁寧な解説を提供してください。` ); prompt.push(``); - const sectionTitlesInView = sectionContent + const sectionTitlesInView = targetSectionContent .filter((s) => s.inView) - .map((s) => s.title) - .join(", "); - prompt.push( - `ユーザーはドキュメント内の ${sectionTitlesInView} の付近のセクションを閲覧している際にこの質問を行っていると推測されます。` - ); - prompt.push( - `質問に答える際には、ユーザーが閲覧しているセクションの内容を特に考慮してください。` - ); + .map((s) => s.title); + if (sectionTitlesInView.length > 0) { + prompt.push( + `ユーザーはドキュメント内の ${sectionTitlesInView.join(", ")} の付近のセクションを閲覧している際にこの質問を行っていると推測されます。` + ); + prompt.push( + `質問に答える際には、ユーザーが閲覧しているセクションの内容を特に考慮してください。` + ); + } else { + prompt.push( + `ユーザーは特定のセクションを閲覧していない可能性があります。質問全体に最も関連する内容を優先して回答してください。` + ); + } prompt.push(``); prompt.push( `質問への回答はユーザー向けのメッセージに加えて、ドキュメント自体を改訂するという形でも可能です。` @@ -84,7 +156,7 @@ export async function POST(request: NextRequest) { prompt.push(``); prompt.push(`# ドキュメント`); prompt.push(``); - for (const section of sectionContent) { + for (const section of targetSectionContent) { prompt.push(`[セクションid: ${section.id}]`); prompt.push(section.replacedContent.trim()); prompt.push(``); @@ -235,9 +307,9 @@ export async function POST(request: NextRequest) { if ( !targetSectionId || - !sectionContent.some((s) => s.id === targetSectionId) + !targetSectionContent.some((s) => s.id === targetSectionId) ) { - targetSectionId = introSectionId(path); + targetSectionId = introSectionId(targetPath); } if (!title) { @@ -260,7 +332,7 @@ export async function POST(request: NextRequest) { // Create chat record in DB immediately const newChat = await addChat( - path, + targetPath, targetSectionId, title, [{ role: "user", content: userQuestion }], @@ -274,6 +346,7 @@ export async function POST(request: NextRequest) { type: "chat", chatId, sectionId: targetSectionId, + pagePath: `${targetPath.lang}/${targetPath.page}`, }); // Send any content that came after the header in this chunk @@ -313,7 +386,7 @@ export async function POST(request: NextRequest) { for (const m of contentAfterHeader.matchAll(diffRegex)) { const search = m[1]; const replace = m[2]; - const targetSection = sectionContent.find((s) => + const targetSection = targetSectionContent.find((s) => s.replacedContent.includes(search) ); diffRaw.push({ @@ -328,7 +401,7 @@ export async function POST(request: NextRequest) { // Save messages and diffs to DB await addMessagesAndDiffs( chatId, - path, + targetPath, [{ role: "ai", content: cleanMessage }], diffRaw, context From c92c1f85a77137a4770afe3c68d9c2773fee39d4 Mon Sep 17 00:00:00 2001 From: na-trium-144 <100704180+na-trium-144@users.noreply.github.com> Date: Tue, 21 Jul 2026 14:16:28 +0900 Subject: [PATCH 4/7] Revert "Plan chat scope routing flow" This reverts commit 528244fa97163ef032a1a337ff7a478c36c236fc. --- .../cache/miniflare-CacheObject/metadata.sqlite | Bin 4096 -> 0 bytes .../miniflare-CacheObject/metadata.sqlite-shm | Bin 32768 -> 0 bytes .../miniflare-CacheObject/metadata.sqlite-wal | Bin 8272 -> 0 bytes ...le-to-be-interrupted-and-recover-state-1.png | Bin 2901 -> 0 bytes ...hon-Runtime-REPL-should-capture-errors-1.png | Bin 2901 -> 0 bytes ...ould-capture-files-modified-by-command-1.png | Bin 2901 -> 0 bytes ...hon-Runtime-REPL-should-capture-stdout-1.png | Bin 2901 -> 0 bytes ...uld-preserve-variables-across-commands-1.png | Bin 2901 -> 0 bytes 8 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite delete mode 100644 .wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite-shm delete mode 100644 .wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite-wal delete mode 100644 packages/runtime/tests/__screenshots__/vitest-all.tsx/Runtime-Integration-Tests-python-Runtime-REPL-should-be-able-to-be-interrupted-and-recover-state-1.png delete mode 100644 packages/runtime/tests/__screenshots__/vitest-all.tsx/Runtime-Integration-Tests-python-Runtime-REPL-should-capture-errors-1.png delete mode 100644 packages/runtime/tests/__screenshots__/vitest-all.tsx/Runtime-Integration-Tests-python-Runtime-REPL-should-capture-files-modified-by-command-1.png delete mode 100644 packages/runtime/tests/__screenshots__/vitest-all.tsx/Runtime-Integration-Tests-python-Runtime-REPL-should-capture-stdout-1.png delete mode 100644 packages/runtime/tests/__screenshots__/vitest-all.tsx/Runtime-Integration-Tests-python-Runtime-REPL-should-preserve-variables-across-commands-1.png diff --git a/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite b/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite deleted file mode 100644 index 0b58f0dca7d6ce95907cb0b322dc4802f04688c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmWFz^vNtqRY=P(%1ta$FlG>7U}9o$P*7lCU|@t|AVoG{WYDXN;00+HAlr;ljiVtj n8UmvsFd71*Aut*OqaiRF0;3@?8UmvsFd71*Aut*O6ovo**AfQj diff --git a/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite-shm b/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite-shm deleted file mode 100644 index 775cddfb1929a9f23883f7cff213dd55b4977942..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32768 zcmeI)u?fOJ6b9g!2`ns9SPI&>gChh43AQ$_V4o!{EP?|#geznM7m0Z$h;2IIz8@Y3 z$K#Isu7AaAn?+_r&GUYZYL@MzJl551vpU@`i$nc9H|yPXUrg-pkNPCe?0zzCf0wvF zdV~N00t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyKp-W7m^vW@(iAXnCCz{LY61iZ5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK;XXx-fegy A?EnA( diff --git a/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite-wal b/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite-wal deleted file mode 100644 index 20e9df52f9f6c2a22048ae5e0e4663fba1ebf974..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8272 zcmXr7XKP~6eI&uaAiw|ub2U_w7gvgeS#WD_aAU9e0Tg0H7N5I$8Dr^hi9^AGKA9z{ z3TgR8xrrqT#z5UnObiYR3P80?Pz=%r0wDb?U>1Y`n}@{5#$;m9tBc?T$}sYmFaXgg z7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fe{k|jhu|^;_~v0jfo|RNja(U z$!YP9K8``Ya0ZiekgH>et3rsQlaH$cTv$PaO92cLlS}f8;xkheLR=$46as=geI0`$ z6}(*|b)X80lQU9NN^??E;!84fQx!b@LR{TlgTRuS3gMn19{!;r3PJwio-V*Z2lw+~ z;|1%l$SjO#i3;EX#Rg<3VZ_ACs7FUbU^E0qLtr!nMnhmU1V%$(Gz3ONU^E0qLtr!n KMnhnvg#Z92g+zM* diff --git a/packages/runtime/tests/__screenshots__/vitest-all.tsx/Runtime-Integration-Tests-python-Runtime-REPL-should-be-able-to-be-interrupted-and-recover-state-1.png b/packages/runtime/tests/__screenshots__/vitest-all.tsx/Runtime-Integration-Tests-python-Runtime-REPL-should-be-able-to-be-interrupted-and-recover-state-1.png deleted file mode 100644 index f1c5529decfa5731cc68f21093466f2f91c1d674..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2901 zcmeAS@N?(olHy`uVBq!ia0y~yV4TOmz}&#W1QcnFZJNcvz|H09;uumf=gk#HUIqh> z0|uY&>`(o$af{Ng@^Xf#dkjxj@Nxu63oJ2H@W^$TaH~OKE2Co;bJGR0%nX}OaxtWKtgr%# OFnGH9xvX z0|uY&>`(o$af{Ng@^Xf#dkjxj@Nxu63oJ2H@W^$TaH~OKE2Co;bJGR0%nX}OaxtWKtgr%# OFnGH9xvX z0|uY&>`(o$af{Ng@^Xf#dkjxj@Nxu63oJ2H@W^$TaH~OKE2Co;bJGR0%nX}OaxtWKtgr%# OFnGH9xvX z0|uY&>`(o$af{Ng@^Xf#dkjxj@Nxu63oJ2H@W^$TaH~OKE2Co;bJGR0%nX}OaxtWKtgr%# OFnGH9xvX z0|uY&>`(o$af{Ng@^Xf#dkjxj@Nxu63oJ2H@W^$TaH~OKE2Co;bJGR0%nX}OaxtWKtgr%# OFnGH9xvX Date: Wed, 22 Jul 2026 00:57:30 +0900 Subject: [PATCH 5/7] =?UTF-8?q?=E3=82=B9=E3=82=BF=E3=82=A4=E3=83=AB?= =?UTF-8?q?=E3=82=92=E8=AA=BF=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/(docs)/@docs/[lang]/[pageId]/chatForm.tsx | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/app/(docs)/@docs/[lang]/[pageId]/chatForm.tsx b/app/(docs)/@docs/[lang]/[pageId]/chatForm.tsx index e707d047..48109e75 100644 --- a/app/(docs)/@docs/[lang]/[pageId]/chatForm.tsx +++ b/app/(docs)/@docs/[lang]/[pageId]/chatForm.tsx @@ -225,7 +225,6 @@ export function ChatForm({ path, langName, sectionContent, close }: ChatFormProp className="border border-2 border-secondary shadow-lg rounded-box bg-base-100/60 backdrop-blur-xs" style={{ width: "100%", - textAlign: "center", }} onSubmit={handleSubmit} > @@ -247,8 +246,8 @@ export function ChatForm({ path, langName, sectionContent, close }: ChatFormProp onChange={(e) => setInputValue(e.target.value)} disabled={isLoading} > -
-