From 043a1aab21d5f0caa0503608ae71709e7d306cba Mon Sep 17 00:00:00 2001 From: ZyGuo Date: Tue, 19 May 2026 16:12:12 +0800 Subject: [PATCH 01/12] update git ignore --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 1b033763..22ab8329 100644 --- a/.gitignore +++ b/.gitignore @@ -75,4 +75,7 @@ offline-backend-20260512/backend/skill_evolution.json skills/ hermes-agent-main/ .gitignore -offline-backend-20260512/backend/tests/* \ No newline at end of file +offline-backend-20260512/backend/tests/* + +.codegraph +codegraph.mdc \ No newline at end of file From ffee030548d2faa170a0794ce6f6db0376966163 Mon Sep 17 00:00:00 2001 From: ZyGuo Date: Wed, 27 May 2026 10:01:15 +0800 Subject: [PATCH 02/12] chore: ignore --- .gitignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 846eca50..5cc03e44 100644 --- a/.gitignore +++ b/.gitignore @@ -84,4 +84,6 @@ deploy .codegraph -codegraph.mdc \ No newline at end of file +codegraph.mdc + +docs/aidev-docs \ No newline at end of file From a2cc1832f287e68a066af37233c1c62ab8ca9b50 Mon Sep 17 00:00:00 2001 From: ZyGuo Date: Mon, 1 Jun 2026 10:27:31 +0800 Subject: [PATCH 03/12] chore: ignore --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 5cc03e44..31d50b52 100644 --- a/.gitignore +++ b/.gitignore @@ -86,4 +86,5 @@ deploy .codegraph codegraph.mdc -docs/aidev-docs \ No newline at end of file +docs/aidev-docs +docs/backups \ No newline at end of file From 0922c8299ff83493df3e14f0e470e7f14967a11f Mon Sep 17 00:00:00 2001 From: ZyGuo Date: Mon, 1 Jun 2026 14:16:13 +0800 Subject: [PATCH 04/12] feat: iframe page --- .../plans/2026-06-01-iframe-chat-page.md | 139 ++++++++ .../components/workspace/chats/chat-box.tsx | 26 +- frontend-web/src/core/api/api-client.ts | 36 ++- frontend-web/src/core/api/canvas-client.ts | 9 +- frontend-web/src/core/api/csrf.ts | 42 +++ frontend-web/src/core/api/fetch-client.ts | 32 +- frontend-web/src/core/threads/hooks.ts | 9 +- frontend-web/src/pages/IframeChatPage.tsx | 301 ++++++++++++++++++ frontend-web/src/pages/WorkspaceRoutes.tsx | 21 ++ 9 files changed, 574 insertions(+), 41 deletions(-) create mode 100644 docs/superpowers/plans/2026-06-01-iframe-chat-page.md create mode 100644 frontend-web/src/core/api/csrf.ts create mode 100644 frontend-web/src/pages/IframeChatPage.tsx diff --git a/docs/superpowers/plans/2026-06-01-iframe-chat-page.md b/docs/superpowers/plans/2026-06-01-iframe-chat-page.md new file mode 100644 index 00000000..0eec0d6a --- /dev/null +++ b/docs/superpowers/plans/2026-06-01-iframe-chat-page.md @@ -0,0 +1,139 @@ +# Iframe Chat Page Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Add a standalone `/page/workspace/chats_iframe/*` chat page that reuses the existing thread system and history, while showing only `你好` and no input box before the first user message. + +**Architecture:** Keep the existing workspace shell and chat runtime intact, then add a new route pair and a copied page component dedicated to the iframe path. The new page keeps the original chat behavior once a thread already has messages, but it owns its empty-state rendering and URL transition to `/page/workspace/chats_iframe/:thread_id`. + +**Tech Stack:** React, TypeScript, React Router, Next navigation shim, existing LangGraph thread hooks + +--- + +### Task 1: Add the iframe chat routes + +**Files:** +- Modify: `frontend-web/src/pages/WorkspaceRoutes.tsx` + +- [ ] **Step 1: Add `chats_iframe/new` and `chats_iframe/:thread_id` routes that render the new page inside the existing workspace layout and chat runtime** + +```tsx + + + + + + } + /> + + + + + + } + /> +``` + +- [ ] **Step 2: Ensure the new route imports compile cleanly** + +Run: `rg -n "IframeChatPage|chats_iframe" frontend-web/src/pages/WorkspaceRoutes.tsx` +Expected: `WorkspaceRoutes.tsx` contains one import for `IframeChatPage` and both `chats_iframe` route entries. + +### Task 2: Add a standalone iframe chat page + +**Files:** +- Create: `frontend-web/src/pages/IframeChatPage.tsx` +- Reference: `frontend-web/src/pages/ChatPage.tsx` + +- [ ] **Step 1: Copy the current `ChatPage` implementation into `IframeChatPage` and preserve the existing chat runtime integration** + +```tsx +export default function IframeChatPage() { + const routeBase = useRouteBase(); + const router = useRouter(); + const [showFollowups, setShowFollowups] = useState(false); + const [hasStartedConversation, setHasStartedConversation] = useState(false); + const { threadId, setThreadId, isNewThread, setIsNewThread, isMock } = + useThreadChat(); + // keep the rest of the existing chat hooks and handlers aligned with ChatPage +} +``` + +- [ ] **Step 2: Change the thread creation URL replacement to stay on the iframe route family** + +```tsx + onStart: (createdThreadId) => { + setThreadId(createdThreadId); + setIsNewThread(false); + history.replaceState( + null, + "", + `${window.location.pathname}${window.location.search}#${routeBase}/chats_iframe/${createdThreadId}`, + ); + }, +``` + +- [ ] **Step 3: Replace the default landing state with a simple `你好` view and do not render the input box while the iframe page is still a brand-new untouched chat** + +```tsx + {isLandingState && mounted ? ( +
+
你好
+
+ ) : null} + {!isLandingState && + (mounted ? ( +
+ setSettings("context", context)} + promptPrefix={promptPrefixProp} + onFollowupsVisibilityChange={setShowFollowups} + onSubmit={handleSubmit} + onStop={handleStop} + /> +
+ ) : ( +