Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
} from "@src/store/session/dataSourceConfigAtom";
import { getInstrumentedStore } from "@src/util/core/state/instrumentedStore";

/** Rescan every enabled external source, then reload the sidebar from cache. */

Check failure on line 15 in src/scaffold/NavigationSidebar/connectors/WorkstationSidebarConnector/sidebarSessionRefresh.ts

View workflow job for this annotation

GitHub Actions / Frontend (typecheck · lint · test)

Insert `import·{⏎··SIDEBAR_SESSION_ACTIVE_REFRESH_INTERVAL_MS,⏎··SIDEBAR_SESSION_IDLE_REFRESH_INTERVAL_MS,⏎}·from·"../sidebarConnectorUtils";⏎⏎`
export async function rescanSidebarSessions(): Promise<void> {
const store = getInstrumentedStore();
if (!store.get(externalSessionsEnabledAtom)) {
Expand Down Expand Up @@ -42,8 +42,59 @@
});
}

import {

Check failure on line 45 in src/scaffold/NavigationSidebar/connectors/WorkstationSidebarConnector/sidebarSessionRefresh.ts

View workflow job for this annotation

GitHub Actions / Frontend (typecheck · lint · test)

Delete `import·{⏎··SIDEBAR_SESSION_ACTIVE_REFRESH_INTERVAL_MS,⏎··SIDEBAR_SESSION_IDLE_REFRESH_INTERVAL_MS,⏎}·from·"../sidebarConnectorUtils";⏎⏎`
SIDEBAR_SESSION_ACTIVE_REFRESH_INTERVAL_MS,
SIDEBAR_SESSION_IDLE_REFRESH_INTERVAL_MS,
} from "../sidebarConnectorUtils";

export function useSidebarSessionRefreshEffects(): void {
useEffect(() => {
void loadSidebarSessions({ forceRefresh: true });
}, []);

Check failure on line 53 in src/scaffold/NavigationSidebar/connectors/WorkstationSidebarConnector/sidebarSessionRefresh.ts

View workflow job for this annotation

GitHub Actions / Frontend (typecheck · lint · test)

Delete `⏎`


useEffect(() => {
let sidebarIntervalId: number | null = null;

const getSidebarRefreshInterval = () =>
document.hasFocus()
? SIDEBAR_SESSION_ACTIVE_REFRESH_INTERVAL_MS
: SIDEBAR_SESSION_IDLE_REFRESH_INTERVAL_MS;

const refreshAllSidebarSessions = () => {
if (document.visibilityState !== "visible") return;
void loadSidebarSessions({ forceRefresh: true });
};

const scheduleRefresh = () => {
if (sidebarIntervalId !== null) {
window.clearInterval(sidebarIntervalId);
sidebarIntervalId = null;
}
if (document.visibilityState !== "visible") return;
sidebarIntervalId = window.setInterval(
refreshAllSidebarSessions,
getSidebarRefreshInterval()
);
};

const handleActivityStateChange = () => {
refreshAllSidebarSessions();
scheduleRefresh();
};

scheduleRefresh();
document.addEventListener("visibilitychange", handleActivityStateChange);
window.addEventListener("focus", handleActivityStateChange);
window.addEventListener("blur", scheduleRefresh);
return () => {
if (sidebarIntervalId !== null) window.clearInterval(sidebarIntervalId);
document.removeEventListener(
"visibilitychange",
handleActivityStateChange
);
window.removeEventListener("focus", handleActivityStateChange);
window.removeEventListener("blur", scheduleRefresh);
};
}, []);
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,15 @@ import type { SessionCreatorDraft } from "@src/store/session";

// ── Constants ─────────────────────────────────────────────────────────────────

/** Poll interval for Cursor IDE session list refresh. */
/** Poll intervals for sidebar session list refresh. */
export const CURSOR_IDE_ACTIVE_REFRESH_INTERVAL_MS = 60_000;
export const CURSOR_IDE_IDLE_REFRESH_INTERVAL_MS = 5 * 60_000;

// ORG2 channel sessions can be created from external surfaces (Feishu, etc.)
// without any frontend action. Refresh the full sidebar list while focused so
// `/newsession ...` appears in ORG2 without a manual page reload.
export const SIDEBAR_SESSION_ACTIVE_REFRESH_INTERVAL_MS = 15_000;
export const SIDEBAR_SESSION_IDLE_REFRESH_INTERVAL_MS = 60_000;

export const NEW_SESSION_MENU_ITEM_ID = "new-session";
export const PROJECTS_NEW_PROJECT_MENU_ITEM_ID = "projects-new-project";
Expand Down
8 changes: 6 additions & 2 deletions src/store/session/sessionAtom/loaders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ interface FetchPageResult {
}

async function fetchAggregatePage(
wireCategory: "cli" | "agent",
wireCategory: "cli" | "agent" | "agent,os",
offset: number,
pageSize: number
): Promise<FetchPageResult> {
Expand Down Expand Up @@ -419,7 +419,11 @@ async function loadCategoryPage(
case "cli_agent":
return fetchAggregatePage("cli", offset, pageSize);
case "rust_agent":
return fetchAggregatePage("agent", offset, pageSize);
// Rust-native sessions include both SDE/custom agent rows (category=agent)
// and channel/desktop OS rows (category=os, e.g. osagent-feishu-*).
// The sidebar groups them under one Rust Agent bucket, so fetch both;
// otherwise Feishu channel sessions exist in DB but never appear/open.
return fetchAggregatePage("agent,os", offset, pageSize);
}
}

Expand Down
Loading