Skip to content

Inbox + sessions: replay by export ID, stacked report logs, cloud workspace bootstrap#2011

Open
Twixes wants to merge 1 commit intomainfrom
inbox/exported-asset-session-video-prune
Open

Inbox + sessions: replay by export ID, stacked report logs, cloud workspace bootstrap#2011
Twixes wants to merge 1 commit intomainfrom
inbox/exported-asset-session-video-prune

Conversation

@Twixes
Copy link
Copy Markdown
Member

@Twixes Twixes commented May 4, 2026

Summary

PostHog Code (this PR)

Session-problem rasterized replay in the inbox trusts exported_asset_id on the signal and loads export content directly—no extras client-side lookups.

In signal report detail, stacked report/remediation rows each mount their logs panel under that row, with layout fixes so the docked pane scrolls cleanly.

Opening cloud-backed task logs can bootstrap a minimal cloud workspace row when the workspace catalog exists but none is persisted yet. Session view routing treats a task as cloud when a workspace row exists with mode: cloud, otherwise falls back on latest_run.environment === "cloud".


Depends on companion: PostHog/posthog #57541 — export retrieve/content allowed for teammates in the project (RBAC on linked resources unchanged; listings stay per-user).

…bootstrap

- Signal session_problem replay loads export by ID only (no list fallback)
- Per-relationship TaskLogs panels in inbox report detail
- Cloud workspace bootstrap in TaskLogsPanel for cloud runs
- useSessionViewState isCloud aligns with workspace row + latest_run env
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 4, 2026

Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 2
apps/code/src/renderer/features/task-detail/components/TaskLogsPanel.tsx:130-134
**Cache invalidation skipped on early unmount**

If the component unmounts while `workspaceApi.create` is still in flight, the cleanup sets `cancelled = true`, the creation still succeeds on the server, but `queryClient.invalidateQueries` is never called. On the next mount, `persistedWorkspace` is still `null` (the query's `staleTime` is 60 s so it won't re-fetch), the effect fires again, and a second create is attempted.

`invalidateQueries` updates the shared cache — it is safe to call even after the component that triggered it has unmounted. The guard should be removed:

```ts
      } catch (error) {
        bootstrapCloudLog.warn("Cloud workspace bootstrap failed", { taskId, error });
      }
      // Always invalidate — cache updates are safe after unmount and prevent
      // a stale null workspace from causing a duplicate-create on next mount.
      void queryClient.invalidateQueries(
        trpcReact.workspace.getAll.pathFilter(),
      );
    })();
```

### Issue 2 of 2
apps/code/src/renderer/features/task-detail/components/TaskLogsPanel.tsx:107-113
**No in-flight guard for concurrent bootstrap calls**

The effect fires whenever any of its dependencies change (e.g., `isSuspended` toggling). If a dependency change triggers the cleanup and immediately re-fires the effect while the previous `workspaceApi.create` call is still awaiting a response, two creates are in flight simultaneously — `persistedWorkspace` is still `null` for both, so neither guard catches the other.

Bypassing the `useMutation` path also means `isCreatingWorkspace` doesn't reflect the bootstrap's pending state. Consider a `useRef` in-flight flag or using the existing mutation hook to serialise concurrent bootstrap attempts.

Reviews (1): Last reviewed commit: "feat(inbox): Session video via exported_..." | Re-trigger Greptile

Comment on lines +130 to +134
if (!cancelled) {
void queryClient.invalidateQueries(
trpcReact.workspace.getAll.pathFilter(),
);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Cache invalidation skipped on early unmount

If the component unmounts while workspaceApi.create is still in flight, the cleanup sets cancelled = true, the creation still succeeds on the server, but queryClient.invalidateQueries is never called. On the next mount, persistedWorkspace is still null (the query's staleTime is 60 s so it won't re-fetch), the effect fires again, and a second create is attempted.

invalidateQueries updates the shared cache — it is safe to call even after the component that triggered it has unmounted. The guard should be removed:

      } catch (error) {
        bootstrapCloudLog.warn("Cloud workspace bootstrap failed", { taskId, error });
      }
      // Always invalidate — cache updates are safe after unmount and prevent
      // a stale null workspace from causing a duplicate-create on next mount.
      void queryClient.invalidateQueries(
        trpcReact.workspace.getAll.pathFilter(),
      );
    })();
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/code/src/renderer/features/task-detail/components/TaskLogsPanel.tsx
Line: 130-134

Comment:
**Cache invalidation skipped on early unmount**

If the component unmounts while `workspaceApi.create` is still in flight, the cleanup sets `cancelled = true`, the creation still succeeds on the server, but `queryClient.invalidateQueries` is never called. On the next mount, `persistedWorkspace` is still `null` (the query's `staleTime` is 60 s so it won't re-fetch), the effect fires again, and a second create is attempted.

`invalidateQueries` updates the shared cache — it is safe to call even after the component that triggered it has unmounted. The guard should be removed:

```ts
      } catch (error) {
        bootstrapCloudLog.warn("Cloud workspace bootstrap failed", { taskId, error });
      }
      // Always invalidate — cache updates are safe after unmount and prevent
      // a stale null workspace from causing a duplicate-create on next mount.
      void queryClient.invalidateQueries(
        trpcReact.workspace.getAll.pathFilter(),
      );
    })();
```

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +107 to +113
useEffect(() => {
if (!isWorkspaceLoaded) return;
if (persistedWorkspace) return;
if (task.latest_run?.environment !== "cloud") return;
if (isSuspended) return;
if (isProvisioning) return;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 No in-flight guard for concurrent bootstrap calls

The effect fires whenever any of its dependencies change (e.g., isSuspended toggling). If a dependency change triggers the cleanup and immediately re-fires the effect while the previous workspaceApi.create call is still awaiting a response, two creates are in flight simultaneously — persistedWorkspace is still null for both, so neither guard catches the other.

Bypassing the useMutation path also means isCreatingWorkspace doesn't reflect the bootstrap's pending state. Consider a useRef in-flight flag or using the existing mutation hook to serialise concurrent bootstrap attempts.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/code/src/renderer/features/task-detail/components/TaskLogsPanel.tsx
Line: 107-113

Comment:
**No in-flight guard for concurrent bootstrap calls**

The effect fires whenever any of its dependencies change (e.g., `isSuspended` toggling). If a dependency change triggers the cleanup and immediately re-fires the effect while the previous `workspaceApi.create` call is still awaiting a response, two creates are in flight simultaneously — `persistedWorkspace` is still `null` for both, so neither guard catches the other.

Bypassing the `useMutation` path also means `isCreatingWorkspace` doesn't reflect the bootstrap's pending state. Consider a `useRef` in-flight flag or using the existing mutation hook to serialise concurrent bootstrap attempts.

How can I resolve this? If you propose a fix, please make it concise.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant