Skip to content

fix(tasks): sync cloud-started tasks into local workspace registry#2146

Merged
oliverb123 merged 3 commits into
mainfrom
posthog-code/sync-cloud-tasks-to-local-workspaces
May 14, 2026
Merged

fix(tasks): sync cloud-started tasks into local workspace registry#2146
oliverb123 merged 3 commits into
mainfrom
posthog-code/sync-cloud-tasks-to-local-workspaces

Conversation

@oliverb123
Copy link
Copy Markdown
Contributor

Summary

  • Tasks started outside the desktop app (web, CLI, another machine — same user) were already returned by the /api/projects/{id}/tasks/ poll, but the sidebar filter in useSidebarData.ts hides any task without a matching local SQLite workspace row, so they never appeared.
  • Mirror the API task list into the local workspace registry: when useTasks() yields a new list, create an idempotent mode: "cloud" workspace row for each missing task, then invalidate the workspaces query so the existing filter passes them through. WorkspaceService.doCreateWorkspace already short-circuits when a row exists, and createWorkspaceInput permits empty paths for cloud mode (same shape task-creation.ts uses for pure cloud tasks today).
  • Reconciliation runs from MainLayout.tsx where useTasks() already lives; a useRef<Set> prevents duplicate in-flight calls between polls.

Test plan

  • pnpm --filter code typecheck passes
  • pnpm --filter code test passes (one pre-existing unrelated git integration timeout)
  • Manual: start a task via the web app or CLI as the same user, wait <30s, confirm the task appears in the desktop sidebar with the correct title and that clicking it opens TaskDetail without errors
  • Restart the app and confirm the cloud workspace row persists (SQLite-backed)
  • Spot-check logs for Workspace already exists for task ... on subsequent polls — no duplicate row creation

Tasks created on other surfaces (web, CLI, another machine for the same
user) were already returned by the /tasks/ API but hidden in the sidebar
because useSidebarData filters to tasks with a matching local workspace
row. Reconcile the local workspace registry against the polled task list
by creating an idempotent cloud-mode workspace row for any task missing
one, then invalidate the workspaces query so the sidebar picks them up.

Generated-By: PostHog Code
Task-Id: bad6d25e-1cb8-4bfe-b323-7c79f6654944
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 14, 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/components/MainLayout.tsx:110-121
**Workspace query invalidated even when all mutations failed**

`queryClient.invalidateQueries` is called unconditionally in `.then()`, including when every mutation in the batch was rejected. This triggers a workspace refetch even though no new row was written. With React Query's default structural sharing the refetch won't change the `workspaces` reference, so the effect likely won't re-run; but if structural sharing is ever disabled, or tRPC's serialization returns a fresh object, the refetch would bump `workspaces`, re-trigger the effect, and start another mutation batch immediately — bypassing the intended 30-second poll cadence.

### Issue 2 of 2
apps/code/src/renderer/components/MainLayout.tsx:100-110
**`workspaceApi.create` already wraps this call**

`workspaceApi` (exported from `useWorkspace.ts`) exists specifically to provide an imperative surface over `trpcClient.workspace.create.mutate` with the same signature. Using it here would follow the OnceAndOnlyOnce principle and makes it easier to trace the mutation through the codebase.

```suggestion
    void Promise.allSettled(
      missing.map((t) =>
        workspaceApi.create({
          taskId: t.id,
          mainRepoPath: "",
          folderId: "",
          folderPath: "",
          mode: "cloud",
        }),
      ),
    ).then((results) => {
```

Reviews (1): Last reviewed commit: "fix(tasks): sync cloud-started tasks int..." | Re-trigger Greptile

Comment thread apps/code/src/renderer/components/MainLayout.tsx
Comment thread apps/code/src/renderer/components/MainLayout.tsx
- Use workspaceApi.create wrapper instead of trpcClient directly
- Only invalidate workspaces query when at least one mutation succeeded

Generated-By: PostHog Code
Task-Id: bad6d25e-1cb8-4bfe-b323-7c79f6654944
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 14, 2026

Reviews (2): Last reviewed commit: "refactor: address review on cloud worksp..." | Re-trigger Greptile

Wraps the new workspace reconciliation effect in MainLayout behind the
posthog-code-sync-cloud-tasks flag so it only runs for users explicitly
enrolled. Avoids surprising external users with unfamiliar cloud tasks
that may have been created by surfaces other than the desktop app.

Generated-By: PostHog Code
Task-Id: bad6d25e-1cb8-4bfe-b323-7c79f6654944
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 14, 2026

Reviews (3): Last reviewed commit: "feat: gate cloud task reconciliation beh..." | Re-trigger Greptile

@oliverb123 oliverb123 merged commit 57a6677 into main May 14, 2026
15 checks passed
@oliverb123 oliverb123 deleted the posthog-code/sync-cloud-tasks-to-local-workspaces branch May 14, 2026 02:41
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.

2 participants