From 7eb2326a76cf80eede7a640802d1e48bf2e063bb Mon Sep 17 00:00:00 2001 From: Linghong Date: Mon, 14 Sep 2026 06:30:07 +0000 Subject: [PATCH] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E9=80=80=E5=BD=B9=E7=AD=96?= =?UTF-8?q?=E5=88=92=20V2=20=E8=BF=90=E8=A1=8C=E6=80=81=E5=88=B7=E6=96=B0?= =?UTF-8?q?=E5=85=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 删除旧版策划状态随项目总控运行态刷新的专用 effect 移除仅服务该 effect 的 planningLane 判定模块 --- apps/ai-game-creator-shell/src/App.tsx | 34 ----------- .../project-workspace/planningLane.ts | 61 ------------------- 2 files changed, 95 deletions(-) delete mode 100644 apps/ai-game-creator-shell/src/features/project-workspace/planningLane.ts diff --git a/apps/ai-game-creator-shell/src/App.tsx b/apps/ai-game-creator-shell/src/App.tsx index d8d0ad655..3f3d82c13 100644 --- a/apps/ai-game-creator-shell/src/App.tsx +++ b/apps/ai-game-creator-shell/src/App.tsx @@ -229,7 +229,6 @@ import { parseRememberInput, } from './features/project-workspace/memoryCommands'; import { pendingCommandDetail } from './features/project-workspace/pendingCommandPresentation'; -import { planningStateNeedsRuntimeRefresh } from './features/project-workspace/planningLane'; import { type PlanningApprovalCommandResultV2, planningMessagesToChatMessages, @@ -1202,39 +1201,6 @@ export function App({ void hydratePlanGddState(targetProjectPath); }, [hydratePlanGddState, localProject?.projectPath]); - useEffect(() => { - // 存在性判据故意走 `status`(必选字段,为 `undefined` 当且仅当 runtime 为 null)而不是整个 - // 对象:依赖里只挖 phase/status/updatedAt 三个标量,是为了只在监工状态真的动了时 - // 重灌。把 `projectSupervisorRuntime` 本体写进依赖会让每一轮轮询新建的对象身份都触发一次 - // hydrate,白烧 IPC。 - if ( - !localProject?.projectPath || - projectSupervisorRuntime?.status === undefined - ) { - return; - } - // 后端 hydrate 会抢项目写锁并扫 authority,不是纯内存读。没有这道门,做游戏和做 - // 素材链路的每一拍监工心跳都会去抢一次项目写锁——而那两条链路根本不产生策划状态。 - // 策划状态读 ref 而不进依赖:hydrate 成功就会换一个 `planGddState` 对象身份,写进 - // 依赖等于 hydrate 触发 hydrate。 - if ( - !planningStateNeedsRuntimeRefresh( - projectSupervisorRuntime?.source, - planGddStateRef.current, - ) - ) { - return; - } - void hydratePlanGddState(localProject.projectPath); - }, [ - hydratePlanGddState, - localProject?.projectPath, - projectSupervisorRuntime?.phase, - projectSupervisorRuntime?.source, - projectSupervisorRuntime?.status, - projectSupervisorRuntime?.updatedAt, - ]); - useEffect(() => { const hydrateOnResume = () => { if (document.visibilityState === 'hidden' || !localProject?.projectPath) { diff --git a/apps/ai-game-creator-shell/src/features/project-workspace/planningLane.ts b/apps/ai-game-creator-shell/src/features/project-workspace/planningLane.ts deleted file mode 100644 index f69dbf7cd..000000000 --- a/apps/ai-game-creator-shell/src/features/project-workspace/planningLane.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { PROJECT_SUPERVISOR_PLAN_SOURCE } from '../../app/constants'; -import type { AgentRuntimeState, PlanGddStateViewV1 } from '../../app/types'; - -/** - * 当前总控 run 是否属于立项策划链路。 - * - * 判据是 run 的 `source`,不是 `planGddState`:做游戏链路在策划批准之后照样带着 - * 一份 approved 的策划状态,但它的总控 run 是 autonomous 源,必须继续拿完整面板。 - */ -export function isPlanningLaneRuntime( - runtime: AgentRuntimeState | null | undefined, -) { - return isPlanningLaneSource(runtime?.source); -} - -/** - * 同一个判据的标量入口。 - * - * `App.tsx` 里那条按监工状态重灌策划状态的 effect,依赖里只放 phase/status/updatedAt - * 这类标量——轮询每拍都会新建 runtime 对象,把本体写进依赖会让每一拍都重跑。要在那 - * 条 effect 里用上链路判据,就只能拿 `source` 这一个标量进去。 - */ -export function isPlanningLaneSource(source: string | null | undefined) { - return source === PROJECT_SUPERVISOR_PLAN_SOURCE; -} - -/** 策划状态里还会继续变的那几个态。`approved` / `rejected` 是终态。 */ -const PLAN_GDD_LIVE_STATES: ReadonlySet = new Set([ - 'draft', - 'ready_for_approval', - 'revision_requested', -]); - -/** - * 监工状态每次变动时,要不要重新 hydrate 策划状态。 - * - * hydrate 不是纯内存读:后端会抢项目写锁、扫 authority、必要时修投影。把它挂在 - * 「任意 run 的任意一次更新」上,等于让做游戏和做素材链路的每一拍心跳都去抢一次 - * 项目写锁。 - * - * 但也不能简单地只看 `isPlanningLaneRuntime`:审批卡的可见性判据是 - * `displayGdd && (pendingApproval || recoveryPending)`,跟当前 run 的 source 无关, - * 而非策划分支的监工面板还要靠 `planGddState.pendingApproval` 点亮等待审批位。所以 - * 策划状态自身还没落定时,即便当前 run 不是策划链路也必须继续跟。 - */ -export function planningStateNeedsRuntimeRefresh( - runtimeSource: string | null | undefined, - planGddState: PlanGddStateViewV1 | null | undefined, -) { - if (isPlanningLaneSource(runtimeSource)) { - return true; - } - if (!planGddState) { - return false; - } - return Boolean( - planGddState.pendingApproval || - planGddState.recoveryPending || - PLAN_GDD_LIVE_STATES.has(planGddState.state), - ); -}