diff --git a/.gitignore b/.gitignore index 663c0f2e..020d34e3 100644 --- a/.gitignore +++ b/.gitignore @@ -91,5 +91,10 @@ deploy frontend-web/.offline-pack-build/ frontend-web/.offline-extract-test/ +.codegraph +codegraph.mdc + +docs/aidev-docs +docs/backups # Frontend skills components must be tracked (excluded from the broad skills/ ignore above) !frontend-web/src/components/workspace/skills/ 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} + /> +
+ ) : ( +