diff --git a/.changeset/fn-7614-planning-badge.md b/.changeset/fn-7614-planning-badge.md
new file mode 100644
index 0000000000..e0a2555063
--- /dev/null
+++ b/.changeset/fn-7614-planning-badge.md
@@ -0,0 +1,7 @@
+---
+"@runfusion/fusion": patch
+---
+
+summary: Planning Mode "needs input" now shows a yellow nav badge instead of a top banner.
+category: fix
+dev: Excludes planning `awaiting_input` sessions from SessionNotificationBanner and adds a `status-dot--pending` dot to the Planning nav destination (LeftSidebarNav + MobileNavBar More item/tab), driven by a new `planningNeedsInput` flag.
diff --git a/docs/dashboard-guide.md b/docs/dashboard-guide.md
index 6de422c05d..0e71295775 100644
--- a/docs/dashboard-guide.md
+++ b/docs/dashboard-guide.md
@@ -415,6 +415,10 @@ Use **Show worktree grouping on the board** in **Settings → Worktrees** when y
Planning is a desktop/tablet left-sidebar main-content destination after **Command Center**. It opens the planning-session list and composer in the main content region; mobile continues to use the compact planning entry points. Planning Mode now includes branch controls on the summary screen before you create a task.
+
+
+When a Planning session is awaiting your input, look for the yellow needs-input dot on the Planning nav destination (desktop left sidebar; mobile More sheet item and More tab icon) rather than a banner — clicking Planning always opens the correct docked Planning view.
+
Before Planning Mode shows **Planning Complete!** or the final plan summary, it first asks **Would you like to go deeper?**. Select one or more suggested themes to continue the interview, use **Other** to add a custom topic, or choose **No, continue to final summary** to reveal the pending summary and task-creation actions.
diff --git a/packages/dashboard/app/App.tsx b/packages/dashboard/app/App.tsx
index 8264e175c1..14c135e307 100644
--- a/packages/dashboard/app/App.tsx
+++ b/packages/dashboard/app/App.tsx
@@ -92,6 +92,7 @@ import {
requiresNativeShellOnboarding,
shouldShowFirstEverBootLoader,
isSessionNeedingInputForBanner,
+ isPlanningAwaitingInput,
getCliActionDisabledReasonForBanner,
executeCliSessionBannerAction,
} from "./utils/appLifecycle";
@@ -103,6 +104,7 @@ export {
requiresNativeShellOnboarding,
shouldShowFirstEverBootLoader,
isSessionNeedingInputForBanner,
+ isPlanningAwaitingInput,
getCliActionDisabledReasonForBanner,
executeCliSessionBannerAction,
} from "./utils/appLifecycle";
@@ -365,9 +367,16 @@ function AppInner() {
/*
* FNXC:SessionBanner 2026-06-14-19:32:
* CLI agent sessions use `waiting_on_input` and `needs_attention` to represent user-actionable states. The banner feed must include those statuses in addition to the legacy planning-session statuses so visible CLI actions cannot be silently hidden from users.
+ *
+ * FNXC:SessionBanner 2026-07-05-00:00:
+ * Planning `awaiting_input` sessions are excluded from the banner feed: the banner's Resume button did not
+ * reliably redirect into Planning Mode. That signal now surfaces as a yellow `status-dot--pending` nav badge
+ * (see `planningNeedsInput` below) whose click target is the already-correct `planning` view navigation.
+ * Planning sessions in `error` status are unaffected and still render in the banner.
*/
- const sessionsNeedingInput = bgSessions.filter(isSessionNeedingInputForBanner);
+ const sessionsNeedingInput = bgSessions.filter((s) => isSessionNeedingInputForBanner(s) && !isPlanningAwaitingInput(s));
const sessionBannersHidden = useSessionBannersHidden();
+ const planningNeedsInput = bgPlanningSessions.some((s) => s.status === "awaiting_input");
// Modal state/handlers - required before useViewState
const modalManager = useModalManager({
@@ -1586,6 +1595,7 @@ function AppInner() {
mailboxUnreadCount={mailboxUnreadCount}
mailboxPendingApprovalCount={mailboxPendingApprovalCount}
chatHasUnreadResponse={chatHasUnreadResponse}
+ planningNeedsInput={planningNeedsInput}
experimentalFeatures={{
insights: insightsEnabled,
memoryView: memoryEnabled,
@@ -1668,6 +1678,7 @@ function AppInner() {
onOpenPlanning={openPlanningWithNav}
onResumePlanning={resumePlanningWithNav}
activePlanningSessionCount={bgPlanningSessions.length}
+ planningNeedsInput={planningNeedsInput}
onOpenUsage={() => openUsageWithNav(null)}
onViewAllProjects={handleViewAllProjects}
onRunScript={runScriptWithNav}
diff --git a/packages/dashboard/app/components/LeftSidebarNav.tsx b/packages/dashboard/app/components/LeftSidebarNav.tsx
index b3c726adc3..219c0e8abb 100644
--- a/packages/dashboard/app/components/LeftSidebarNav.tsx
+++ b/packages/dashboard/app/components/LeftSidebarNav.tsx
@@ -109,6 +109,13 @@ export interface LeftSidebarNavProps {
mailboxUnreadCount?: number;
mailboxPendingApprovalCount?: number;
chatHasUnreadResponse?: boolean;
+ /*
+ FNXC:Navigation 2026-07-05-00:00:
+ Planning Mode "awaiting input" no longer shows a top-of-board banner (its Resume button did not reliably
+ redirect). Instead this flag drives a yellow `status-dot--pending` dot on the Planning nav destination,
+ mirroring `chatHasUnreadResponse` exactly, so the click target is always the working `planning` nav item.
+ */
+ planningNeedsInput?: boolean;
experimentalFeatures?: LeftSidebarExperimentalFeatures;
pluginDashboardViews?: PluginDashboardViewEntry[];
showAgentsTab?: boolean;
@@ -156,6 +163,7 @@ export function LeftSidebarNav({
mailboxUnreadCount = 0,
mailboxPendingApprovalCount = 0,
chatHasUnreadResponse = false,
+ planningNeedsInput = false,
experimentalFeatures,
pluginDashboardViews = [],
showAgentsTab = false,
@@ -324,6 +332,8 @@ export function LeftSidebarNav({
isActive: view === "planning",
icon: Lightbulb,
testId: "sidebar-nav-planning",
+ // FNXC:Navigation 2026-07-05-00:00: mirrors the chat item's `dot` below — replaces the broken-Resume banner.
+ dot: planningNeedsInput && view !== "planning" ? "pending" : undefined,
onSelect: () => onChangeView("planning"),
},
{
diff --git a/packages/dashboard/app/components/MobileNavBar.css b/packages/dashboard/app/components/MobileNavBar.css
index 68ab6b80ac..95cdb5d50f 100644
--- a/packages/dashboard/app/components/MobileNavBar.css
+++ b/packages/dashboard/app/components/MobileNavBar.css
@@ -263,6 +263,26 @@ Wrap every tab icon in the same token-sized icon slot and keep unread/pending do
color: var(--text-muted);
}
+/*
+FNXC:Navigation 2026-07-05-00:00:
+Planning "awaiting input" moved from a top-of-board banner (broken Resume redirect) to a yellow needs-input dot on
+this More-sheet item, mirroring the mobile-nav-tab icon-wrapper pattern so the dot positions relative to the icon
+rather than the full-width row.
+*/
+.mobile-more-item-icon-wrapper {
+ position: relative;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ flex: 0 0 auto;
+}
+
+.mobile-more-item-icon-dot {
+ position: absolute;
+ top: -2px;
+ right: -2px;
+}
+
.mobile-more-item-badge {
margin-left: auto;
min-width: 20px;
diff --git a/packages/dashboard/app/components/MobileNavBar.tsx b/packages/dashboard/app/components/MobileNavBar.tsx
index 9b8556a84d..b27467449c 100644
--- a/packages/dashboard/app/components/MobileNavBar.tsx
+++ b/packages/dashboard/app/components/MobileNavBar.tsx
@@ -88,6 +88,14 @@ export interface MobileNavBarProps {
onOpenPlanning?: () => void;
onResumePlanning?: () => void;
activePlanningSessionCount?: number;
+ /*
+ FNXC:Navigation 2026-07-05-00:00:
+ Planning Mode "awaiting input" no longer shows a top-of-board banner (its Resume button did not reliably
+ redirect). Instead this flag drives a yellow `status-dot--pending` dot on the Planning More-sheet item and the
+ More tab icon, mirroring `chatHasUnreadResponse`'s `mobile-nav-chat-unread-dot`, so the click target is always
+ the working Planning navigation.
+ */
+ planningNeedsInput?: boolean;
onOpenUsage?: () => void;
onRunScript?: (name: string, command: string) => void;
projectId?: string;
@@ -149,6 +157,7 @@ export function MobileNavBar({
onOpenPlanning,
onResumePlanning,
activePlanningSessionCount = 0,
+ planningNeedsInput = false,
onOpenUsage,
onRunScript,
projectId,
@@ -469,6 +478,9 @@ export function MobileNavBar({
>
+ {planningNeedsInput && view !== "planning" && !isMoreOpen && (
+
+ )}
{t("nav.more", "More")}
@@ -613,7 +625,12 @@ export function MobileNavBar({
data-testid="mobile-more-item-planning"
onClick={() => handleMoreAction(planningHandler)}
>
-
+
+
+ {planningNeedsInput && (
+
+ )}
+
{t("nav.planning", "Planning")}
{activePlanningSessionCount > 0 && (
{formatCount(activePlanningSessionCount)}
diff --git a/packages/dashboard/app/components/__tests__/LeftSidebarNav.test.tsx b/packages/dashboard/app/components/__tests__/LeftSidebarNav.test.tsx
index efbb08a26e..403b89e675 100644
--- a/packages/dashboard/app/components/__tests__/LeftSidebarNav.test.tsx
+++ b/packages/dashboard/app/components/__tests__/LeftSidebarNav.test.tsx
@@ -647,4 +647,32 @@ describe("LeftSidebarNav", () => {
expect(() => fireEvent.click(screen.getByTestId("sidebar-nav-settings"))).not.toThrow();
});
+
+ /*
+ FNXC:Navigation 2026-07-05-00:00:
+ FN-7614: planning-awaiting-input moved from a top-of-board banner (broken Resume redirect) to a yellow
+ `status-dot--pending` dot on this Planning nav destination, mirroring `chatHasUnreadResponse` exactly.
+ */
+ describe("planningNeedsInput dot (FN-7614)", () => {
+ it("shows the pending status dot on the Planning item when planningNeedsInput is true and not on the planning view", () => {
+ renderSidebar({ planningNeedsInput: true, view: "board" });
+
+ const planningButton = screen.getByTestId("sidebar-nav-planning");
+ expect(planningButton.querySelector(".status-dot.status-dot--pending")).toBeTruthy();
+ });
+
+ it("hides the dot when the user is already on the planning view", () => {
+ renderSidebar({ planningNeedsInput: true, view: "planning" });
+
+ const planningButton = screen.getByTestId("sidebar-nav-planning");
+ expect(planningButton.querySelector(".status-dot.status-dot--pending")).toBeNull();
+ });
+
+ it("hides the dot when planningNeedsInput is false", () => {
+ renderSidebar({ planningNeedsInput: false, view: "board" });
+
+ const planningButton = screen.getByTestId("sidebar-nav-planning");
+ expect(planningButton.querySelector(".status-dot.status-dot--pending")).toBeNull();
+ });
+ });
});
diff --git a/packages/dashboard/app/components/__tests__/MobileNavBar.test.tsx b/packages/dashboard/app/components/__tests__/MobileNavBar.test.tsx
index 1ca8148688..b7794bc14c 100644
--- a/packages/dashboard/app/components/__tests__/MobileNavBar.test.tsx
+++ b/packages/dashboard/app/components/__tests__/MobileNavBar.test.tsx
@@ -557,6 +557,47 @@ describe("MobileNavBar", () => {
expect(screen.queryByLabelText("Unread chat response")).toBeNull();
});
+ /*
+ FNXC:Navigation 2026-07-05-00:00:
+ FN-7614: planning-awaiting-input moved from a top-of-board banner (broken Resume redirect) to a yellow
+ needs-input dot on the Planning More-sheet item and the More tab icon, mirroring the chat unread dot pattern.
+ The existing activePlanningSessionCount count badge must remain unaffected.
+ */
+ describe("planningNeedsInput dot (FN-7614)", () => {
+ it("shows a needs-input dot on the More tab icon when planningNeedsInput is true and the sheet is closed", () => {
+ render();
+ expect(screen.getByLabelText("Planning needs your input")).toBeInTheDocument();
+ });
+
+ it("hides the More tab dot when planningNeedsInput is false", () => {
+ render();
+ expect(screen.queryByLabelText("Planning needs your input")).toBeNull();
+ });
+
+ it("hides the More tab dot while already on the planning view", () => {
+ render();
+ expect(screen.queryByLabelText("Planning needs your input")).toBeNull();
+ });
+
+ it("shows a needs-input dot on the Planning More-sheet item and keeps the count badge unaffected", () => {
+ render();
+ fireEvent.click(screen.getByTestId("mobile-nav-tab-more"));
+
+ const planningItem = screen.getByTestId("mobile-more-item-planning");
+ expect(planningItem.querySelector(".status-dot.status-dot--pending")).toBeTruthy();
+ expect(planningItem).toHaveTextContent("2");
+ });
+
+ it("hides the Planning More-sheet dot when planningNeedsInput is false while the count badge still renders", () => {
+ render();
+ fireEvent.click(screen.getByTestId("mobile-nav-tab-more"));
+
+ const planningItem = screen.getByTestId("mobile-more-item-planning");
+ expect(planningItem.querySelector(".status-dot.status-dot--pending")).toBeNull();
+ expect(planningItem).toHaveTextContent("3");
+ });
+ });
+
it("skills More-sheet item calls onChangeView with 'skills'", () => {
const props = createDefaultProps();
render();
diff --git a/packages/dashboard/app/components/__tests__/SessionNotificationBanner.test.tsx b/packages/dashboard/app/components/__tests__/SessionNotificationBanner.test.tsx
index 0fbaec0893..afcfa49864 100644
--- a/packages/dashboard/app/components/__tests__/SessionNotificationBanner.test.tsx
+++ b/packages/dashboard/app/components/__tests__/SessionNotificationBanner.test.tsx
@@ -2,6 +2,7 @@ import { describe, expect, it, vi, beforeEach } from "vitest";
import { fireEvent, render, screen } from "@testing-library/react";
import type { AiSessionSummary } from "../../api";
import { SessionNotificationBanner, dismissedIds } from "../SessionNotificationBanner";
+import { isPlanningAwaitingInput, isSessionNeedingInputForBanner } from "../../utils/appLifecycle";
function buildSession(overrides: Partial): AiSessionSummary {
return {
@@ -283,6 +284,49 @@ describe("SessionNotificationBanner", () => {
expect(onDismissSession).toHaveBeenCalledWith("error-dismiss");
});
+ /*
+ FNXC:SessionBanner 2026-07-05-00:00:
+ Symptom Verification (FN-7614): the production banner feed (App.tsx `sessionsNeedingInput`) filters via
+ `isSessionNeedingInputForBanner(s) && !isPlanningAwaitingInput(s)` before it ever reaches this component. Given a
+ lone planning awaiting_input session, that filter yields an empty array, so the banner must render NO entry
+ (and no banner region at all) — reproducing the original broken-Resume-button symptom being fixed by the nav badge.
+ */
+ it("renders no banner entry (and no banner region) for a lone planning awaiting_input session, using the production banner filter", () => {
+ const planningAwaitingInput = buildSession({ id: "planning-solo", type: "planning", status: "awaiting_input", title: "Solo planning session" });
+ const filtered = [planningAwaitingInput].filter((s) => isSessionNeedingInputForBanner(s) && !isPlanningAwaitingInput(s));
+
+ const { container } = render(
+ ,
+ );
+
+ expect(filtered).toEqual([]);
+ expect(screen.queryByText("Solo planning session")).not.toBeInTheDocument();
+ expect(container.firstChild).toBeNull();
+ });
+
+ it("keeps a mixed non-planning awaiting-input session visible while excluding planning-awaiting-input via the production filter", () => {
+ const planningAwaitingInput = buildSession({ id: "planning-solo2", type: "planning", status: "awaiting_input", title: "Excluded planning session" });
+ const cliAwaitingInput = buildSession({ id: "cli-mixed", type: "cli-agent", status: "waiting_on_input", title: "Visible CLI session" });
+ const filtered = [planningAwaitingInput, cliAwaitingInput].filter((s) => isSessionNeedingInputForBanner(s) && !isPlanningAwaitingInput(s));
+
+ render(
+ ,
+ );
+
+ expect(screen.queryByText("Excluded planning session")).not.toBeInTheDocument();
+ expect(screen.getByText("Visible CLI session")).toBeInTheDocument();
+ });
+
it("preserves dismissed error sessions when session status changes", () => {
const { rerender } = render(
& Pick): AiSessionSummary {
+ return {
+ id: overrides.id,
+ type: overrides.type ?? "planning",
+ status: overrides.status ?? "generating",
+ title: overrides.title ?? overrides.id,
+ projectId: overrides.projectId ?? null,
+ lockedByTab: overrides.lockedByTab ?? null,
+ updatedAt: overrides.updatedAt ?? "2026-04-08T00:00:00.000Z",
+ };
+}
+
+/*
+FNXC:SessionBanner 2026-07-05-00:00:
+Symptom Verification (FN-7614): planning `awaiting_input` sessions must be excluded from the banner feed
+(`isSessionNeedingInputForBanner(s) && !isPlanningAwaitingInput(s)`), while planning `error` and non-planning
+awaiting-input sessions must remain — this is the invariant the App.tsx `sessionsNeedingInput` filter relies on.
+*/
+describe("isPlanningAwaitingInput", () => {
+ it("is true only for planning sessions awaiting input", () => {
+ expect(isPlanningAwaitingInput(makeSession({ id: "p1", type: "planning", status: "awaiting_input" }))).toBe(true);
+ });
+
+ it("is false for planning sessions in other statuses", () => {
+ expect(isPlanningAwaitingInput(makeSession({ id: "p2", type: "planning", status: "generating" }))).toBe(false);
+ expect(isPlanningAwaitingInput(makeSession({ id: "p3", type: "planning", status: "error" }))).toBe(false);
+ });
+
+ it("is false for non-planning sessions even when awaiting input", () => {
+ expect(isPlanningAwaitingInput(makeSession({ id: "c1", type: "cli-agent", status: "awaiting_input" }))).toBe(false);
+ });
+});
+
+describe("sessionsNeedingInput banner filter (isSessionNeedingInputForBanner + !isPlanningAwaitingInput)", () => {
+ function bannerFilter(sessions: AiSessionSummary[]): AiSessionSummary[] {
+ return sessions.filter((s) => isSessionNeedingInputForBanner(s) && !isPlanningAwaitingInput(s));
+ }
+
+ it("excludes a lone planning awaiting_input session from the banner feed", () => {
+ const sessions = [makeSession({ id: "p1", type: "planning", status: "awaiting_input" })];
+ expect(bannerFilter(sessions)).toEqual([]);
+ });
+
+ it("keeps planning error sessions in the banner feed", () => {
+ const errorSession = makeSession({ id: "p2", type: "planning", status: "error" });
+ expect(bannerFilter([errorSession])).toEqual([errorSession]);
+ });
+
+ it("keeps non-planning awaiting-input sessions in the banner feed", () => {
+ const cliSession = makeSession({ id: "c1", type: "cli-agent", status: "awaiting_input" });
+ expect(bannerFilter([cliSession])).toEqual([cliSession]);
+ });
+
+ it("excludes planning-awaiting-input while keeping a mixed non-planning awaiting-input session", () => {
+ const planningAwaiting = makeSession({ id: "p3", type: "planning", status: "awaiting_input" });
+ const cliAwaiting = makeSession({ id: "c2", type: "cli-agent", status: "awaiting_input" });
+ expect(bannerFilter([planningAwaiting, cliAwaiting])).toEqual([cliAwaiting]);
+ });
+
+ it("excludes generating planning sessions (never in the banner or badge input)", () => {
+ const generating = makeSession({ id: "p4", type: "planning", status: "generating" });
+ expect(bannerFilter([generating])).toEqual([]);
+ });
+});
describe("resolveDesktopShellRedirectTarget", () => {
const remoteProfile = {
diff --git a/packages/dashboard/app/utils/appLifecycle.ts b/packages/dashboard/app/utils/appLifecycle.ts
index c0887f5016..94f32e9855 100644
--- a/packages/dashboard/app/utils/appLifecycle.ts
+++ b/packages/dashboard/app/utils/appLifecycle.ts
@@ -176,6 +176,18 @@ export function isSessionNeedingInputForBanner(session: AiSessionSummary): boole
);
}
+/*
+FNXC:SessionBanner 2026-07-05-00:00:
+Planning-Mode "awaiting input" is no longer a SessionNotificationBanner entry: the banner's Resume button did not
+reliably redirect into the Planning Mode interface, so awaiting-input planning sessions are now surfaced as a yellow
+`status-dot--pending` badge on the Planning nav destination instead (LeftSidebarNav + MobileNavBar), whose click
+target is the already-correct `planning` view navigation. Planning sessions in `error` status are unaffected and
+still render in the banner via `isSessionNeedingInputForBanner` above.
+*/
+export function isPlanningAwaitingInput(session: AiSessionSummary): boolean {
+ return session.type === "planning" && session.status === "awaiting_input";
+}
+
export function getCliActionDisabledReasonForBanner(session: AiSessionSummary, action: CliActionId): string | null {
if ((action === "advance" || action === "relaunch") && !session.cliSessionId) {
return "CLI session id is missing.";
diff --git a/packages/i18n/locales/en/app.json b/packages/i18n/locales/en/app.json
index 7a99694cf5..8edc2e5be9 100644
--- a/packages/i18n/locales/en/app.json
+++ b/packages/i18n/locales/en/app.json
@@ -4031,6 +4031,7 @@
"moreSheetTitle": "Navigate",
"noScriptsAddOne": "No scripts — add one…",
"planning": "Planning",
+ "planningNeedsInputAriaLabel": "Planning needs your input",
"primaryNavAriaLabel": "Primary navigation",
"projects": "Projects",
"research": "Research",
diff --git a/packages/i18n/locales/es/app.json b/packages/i18n/locales/es/app.json
index a23b2ead5a..0d267e2222 100644
--- a/packages/i18n/locales/es/app.json
+++ b/packages/i18n/locales/es/app.json
@@ -4021,6 +4021,7 @@
"moreSheetTitle": "Navegar",
"noScriptsAddOne": "Sin scripts — agregar uno…",
"planning": "Planificación",
+ "planningNeedsInputAriaLabel": "Planificación necesita tu entrada",
"primaryNavAriaLabel": "Navegación principal",
"projects": "Proyectos",
"research": "Investigación",
diff --git a/packages/i18n/locales/fr/app.json b/packages/i18n/locales/fr/app.json
index 69f21a1337..fb79ee6e70 100644
--- a/packages/i18n/locales/fr/app.json
+++ b/packages/i18n/locales/fr/app.json
@@ -4021,6 +4021,7 @@
"moreSheetTitle": "Naviguer",
"noScriptsAddOne": "Aucun script — en ajouter un…",
"planning": "Planification",
+ "planningNeedsInputAriaLabel": "La planification nécessite votre saisie",
"primaryNavAriaLabel": "Navigation principale",
"projects": "Projets",
"research": "Recherche",
diff --git a/packages/i18n/locales/ko/app.json b/packages/i18n/locales/ko/app.json
index a3ad02d39c..476df6d1e0 100644
--- a/packages/i18n/locales/ko/app.json
+++ b/packages/i18n/locales/ko/app.json
@@ -4021,6 +4021,7 @@
"moreSheetTitle": "탐색",
"noScriptsAddOne": "스크립트 없음 — 추가하세요…",
"planning": "계획",
+ "planningNeedsInputAriaLabel": "계획에 입력이 필요합니다",
"primaryNavAriaLabel": "기본 탐색",
"projects": "프로젝트",
"research": "연구",
diff --git a/packages/i18n/locales/zh-CN/app.json b/packages/i18n/locales/zh-CN/app.json
index 6c7dee07c5..2f20fc338f 100644
--- a/packages/i18n/locales/zh-CN/app.json
+++ b/packages/i18n/locales/zh-CN/app.json
@@ -4021,6 +4021,7 @@
"moreSheetTitle": "导航",
"noScriptsAddOne": "无脚本 — 添加一个…",
"planning": "规划",
+ "planningNeedsInputAriaLabel": "规划需要您的输入",
"primaryNavAriaLabel": "主导航",
"projects": "项目",
"research": "研究",
diff --git a/packages/i18n/locales/zh-TW/app.json b/packages/i18n/locales/zh-TW/app.json
index 133c43ac49..3f1ed69a98 100644
--- a/packages/i18n/locales/zh-TW/app.json
+++ b/packages/i18n/locales/zh-TW/app.json
@@ -4021,6 +4021,7 @@
"moreSheetTitle": "導覽",
"noScriptsAddOne": "無腳本 — 新增一個…",
"planning": "規劃",
+ "planningNeedsInputAriaLabel": "規劃需要您的輸入",
"primaryNavAriaLabel": "主導覽",
"projects": "專案",
"research": "研究",
diff --git a/packages/i18n/src/resources.d.ts b/packages/i18n/src/resources.d.ts
index a85f6426be..d2b638fc01 100644
--- a/packages/i18n/src/resources.d.ts
+++ b/packages/i18n/src/resources.d.ts
@@ -4032,6 +4032,7 @@ export default interface Resources {
"moreSheetTitle": "Navigate",
"noScriptsAddOne": "No scripts — add one…",
"planning": "Planning",
+ "planningNeedsInputAriaLabel": "Planning needs your input",
"primaryNavAriaLabel": "Primary navigation",
"projects": "Projects",
"research": "Research",