diff --git a/frontend/app/app/assistant.tsx b/frontend/app/app/assistant.tsx
index cd2e6d0..2513665 100644
--- a/frontend/app/app/assistant.tsx
+++ b/frontend/app/app/assistant.tsx
@@ -28,6 +28,7 @@ import {
readPendingWorkspaceSessionId,
writeActiveSessionId,
} from "@/lib/claw-active-session";
+import { pushSessionUrl } from "@/lib/claw-session-url";
import { ClawSessionReplayProvider } from "@/lib/claw-session-replay";
import { ClawAccountGate, useClawAccount } from "./claw-account-gate";
@@ -112,6 +113,7 @@ export const Assistant = ({ initialSessionId }: AssistantProps = {}) => {
targetSessionId,
toReplayRepository(payload, targetSessionId, runStatus),
);
+ pushSessionUrl(targetSessionId);
} catch {
if (!cancelled) {
loadedInitialSessionRef.current = null;
diff --git a/frontend/app/components/assistant-ui/thread-list.tsx b/frontend/app/components/assistant-ui/thread-list.tsx
index 03aa413..d447cba 100644
--- a/frontend/app/components/assistant-ui/thread-list.tsx
+++ b/frontend/app/components/assistant-ui/thread-list.tsx
@@ -24,6 +24,7 @@ import {
readActiveSessionId,
writeActiveSessionId,
} from "@/lib/claw-active-session";
+import { pushHomeUrl, pushSessionUrl } from "@/lib/claw-session-url";
import { useClawSessionReplay } from "@/lib/claw-session-replay";
type ClawSession = {
@@ -121,6 +122,7 @@ const ThreadListNew: FC = () => {
{
clearActiveSessionId();
+ pushHomeUrl();
window.dispatchEvent(new Event("claw-active-session-cleared"));
}}
>
@@ -262,6 +264,7 @@ const ClawSessionList: FC = () => {
onClick={async () => {
setOpenMenuSessionId(null);
writeActiveSessionId(session.session_id);
+ pushSessionUrl(session.session_id);
setActiveSessionId(session.session_id);
setLoadingSessionId(session.session_id);
try {
diff --git a/frontend/app/components/assistant-ui/threadlist-sidebar.tsx b/frontend/app/components/assistant-ui/threadlist-sidebar.tsx
index 2efce1e..98f2661 100644
--- a/frontend/app/components/assistant-ui/threadlist-sidebar.tsx
+++ b/frontend/app/components/assistant-ui/threadlist-sidebar.tsx
@@ -51,6 +51,7 @@ import {
writeActiveSessionId,
} from "@/lib/claw-active-session";
import { useClawSessionReplay } from "@/lib/claw-session-replay";
+import { pushHomeUrl, pushSessionUrl } from "@/lib/claw-session-url";
type ThreadListSidebarProps = React.ComponentProps
& {
account: ClawAccount;
@@ -201,6 +202,7 @@ function CollapsedSidebarRail({
{
clearActiveSessionId();
+ pushHomeUrl();
window.dispatchEvent(new Event("claw-active-session-cleared"));
}}
>
@@ -404,6 +406,7 @@ function useSidebarSessions(open: boolean) {
const cleanSessionId = normalizeSessionId(sessionId);
if (!cleanSessionId) return;
writeActiveSessionId(cleanSessionId);
+ pushSessionUrl(cleanSessionId);
setLoadingSessionId(sessionId);
try {
const response = await fetch(`/api/claw/sessions/${cleanSessionId}`, {
diff --git a/frontend/app/lib/claw-session-url.ts b/frontend/app/lib/claw-session-url.ts
new file mode 100644
index 0000000..4beb3d2
--- /dev/null
+++ b/frontend/app/lib/claw-session-url.ts
@@ -0,0 +1,14 @@
+"use client";
+
+export function pushSessionUrl(sessionId: string) {
+ if (typeof window === "undefined") return;
+ const target = `/session/${encodeURIComponent(sessionId)}`;
+ if (window.location.pathname === target) return;
+ window.history.pushState(null, "", target);
+}
+
+export function pushHomeUrl() {
+ if (typeof window === "undefined") return;
+ if (window.location.pathname === "/") return;
+ window.history.pushState(null, "", "/");
+}