Skip to content

Commit e18a42b

Browse files
committed
Simplify worktree adoption after review
- Validation in createTask now accepts content OR taskDescription instead of enumerating per-flow flags; the worktreeAdoption input flag existed only to gate that check, so it's gone - listAdoptableWorktrees builds occupied-path and registered-folder sets in one pass instead of re-querying workspace tables per worktree candidate - SidebarSection reuses the INDENT_SIZE constant from SidebarItem instead of a third copy of the indent unit Generated-By: PostHog Code Task-Id: 24032eac-82cc-4c5f-a7e9-30ed9278a6e1
1 parent d65413d commit e18a42b

8 files changed

Lines changed: 22 additions & 22 deletions

File tree

packages/core/src/task-detail/taskInput.test.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ describe("buildWorktreeAdoptionInput", () => {
4242
workspaceMode: "worktree",
4343
branch: "feature/orphan",
4444
reuseExistingWorktree: true,
45-
worktreeAdoption: true,
4645
});
4746
// No content: the saga must not build an initial prompt, so the agent
4847
// session starts idle in the adopted worktree.

packages/core/src/task-detail/taskInput.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,6 @@ export function buildWorktreeAdoptionInput(options: {
9898
workspaceMode: "worktree",
9999
branch: options.branch,
100100
reuseExistingWorktree: true,
101-
worktreeAdoption: true,
102101
};
103102
}
104103

packages/core/src/task-detail/taskService.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@ function makeService(): TaskService {
4949
}
5050

5151
describe("TaskService.createTask validation", () => {
52-
it("rejects a promptless input without the adoption or import markers", async () => {
52+
it("rejects an input with neither content nor a taskDescription", async () => {
5353
const result = await makeService().createTask({
54-
taskDescription: "feature/orphan",
54+
content: " ",
5555
repoPath: "/repo",
5656
workspaceMode: "worktree",
5757
});

packages/core/src/task-detail/taskService.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,11 @@ export class TaskService {
6161
hasRepo: !!input.repository,
6262
});
6363

64-
// Imported Claude Code sessions carry a transcript, not a typed prompt, so
65-
// they supply a taskDescription instead of content. Worktree-adoption tasks
66-
// have no prompt either — the user types their first message in the opened
67-
// chat — so they too rely on a synthesized taskDescription.
64+
// Promptless flows (imported Claude Code sessions, worktree adoption)
65+
// synthesize a taskDescription instead of typed content; either one names
66+
// the task, so either satisfies validation.
6867
const hasDescription =
69-
!!input.content?.trim() ||
70-
((!!input.importedClaudeSession || !!input.worktreeAdoption) &&
71-
!!input.taskDescription?.trim());
68+
!!input.content?.trim() || !!input.taskDescription?.trim();
7269
if (!hasDescription) {
7370
return {
7471
success: false,

packages/shared/src/task-creation-domain.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,6 @@ export interface TaskCreationInput {
3131
// When a worktree is already checked out on the branch, opt in to reusing it
3232
// for this task instead of creating a new one (set after the user confirms).
3333
reuseExistingWorktree?: boolean;
34-
/**
35-
* Start-from-worktree flow: the task is created around an existing task-less
36-
* worktree with no typed prompt — the synthesized taskDescription (the branch
37-
* name) names the task and the agent session starts idle. Callers pair this
38-
* with reuseExistingWorktree and branch.
39-
*/
40-
worktreeAdoption?: boolean;
4134
githubIntegrationId?: number;
4235
githubUserIntegrationId?: string;
4336
executionMode?: ExecutionMode;

packages/ui/src/features/sidebar/components/SidebarItem.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
import type { SidebarItemAction } from "@posthog/ui/features/sidebar/types";
1010
import { useCallback } from "react";
1111

12-
const INDENT_SIZE = 8;
12+
export const INDENT_SIZE = 8;
1313

1414
interface SidebarItemProps {
1515
depth: number;

packages/ui/src/features/sidebar/components/SidebarSection.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { CaretDownIcon, CaretRightIcon, Plus } from "@phosphor-icons/react";
22
import { Button } from "@posthog/quill";
3+
import { INDENT_SIZE } from "@posthog/ui/features/sidebar/components/SidebarItem";
34
import { Tooltip } from "@posthog/ui/primitives/Tooltip";
45
import * as Collapsible from "@radix-ui/react-collapsible";
56
import { useState } from "react";
@@ -46,7 +47,7 @@ export function SidebarSection({
4647
className="flex w-full items-center justify-between pl-2 not-hover:aria-expanded:bg-transparent"
4748
style={{
4849
marginTop: addSpacingBefore ? "12px" : undefined,
49-
paddingLeft: depth ? `${depth * 8 + 8}px` : undefined,
50+
paddingLeft: depth ? `${depth * INDENT_SIZE + 8}px` : undefined,
5051
}}
5152
onContextMenu={onContextMenu}
5253
onMouseEnter={() => setIsHovered(true)}

packages/workspace-server/src/services/workspace/workspace.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1487,13 +1487,24 @@ export class WorkspaceService extends TypedEventEmitter<WorkspaceServiceEvents>
14871487
this.getLocalWorktreePathIfExists(mainRepoPath),
14881488
]);
14891489

1490+
// One pass over associations and registered folders up front; per-candidate
1491+
// lookups would re-query the workspace tables once per worktree.
1492+
const occupiedPaths = new Set(
1493+
this.getAllTaskAssociations().flatMap((assoc) =>
1494+
assoc.mode === "worktree" ? [assoc.path] : [],
1495+
),
1496+
);
1497+
const registeredFolderPaths = new Set(
1498+
this.repositoryRepo.findAll().map((repo) => repo.path),
1499+
);
1500+
14901501
return linkedWorktrees
14911502
.filter(
14921503
(wt) =>
14931504
wt.branch !== null &&
14941505
wt.worktreePath !== localStashPath &&
1495-
!this.repositoryRepo.findByPath(wt.worktreePath) &&
1496-
this.getWorktreeTasks(wt.worktreePath).length === 0,
1506+
!registeredFolderPaths.has(wt.worktreePath) &&
1507+
!occupiedPaths.has(wt.worktreePath),
14971508
)
14981509
.map((wt) => ({
14991510
worktreePath: wt.worktreePath,

0 commit comments

Comments
 (0)