Compare commits

...
4 changed files with 46 additions and 12 deletions
+1 -1
View File
@@ -42,7 +42,7 @@ buildNpmPackage rec {
# To update: run `nix build` with lib.fakeHash, copy the `got:` hash.
# CI auto-updates this when package-lock.json changes (see .github/workflows/).
npmDepsHash = "sha256-O5AxXbwGJO52gvmVTzJqgy7nb2dxoVAaikBni3Gtu/s=";
npmDepsHash = "sha256-0Izp63gVeBO9Efo4Uf8/EB3TkQ9FXJ4Td2Fe5UHm9eE=";
# Prevent onnxruntime-node's install script from running during automatic
# npm rebuild (it tries to download from api.nuget.org, which fails in the sandbox).
@@ -584,7 +584,9 @@ const DiffFileHeader = memo(function DiffFileHeader({
onPress={toggleExpanded}
>
<View style={styles.fileHeaderLeft}>
<Text style={styles.fileName}>{file.path.split("/").pop()}</Text>
<Text style={styles.fileName} numberOfLines={1}>
{file.path.split("/").pop()}
</Text>
<Text style={styles.fileDir} numberOfLines={1}>
{file.path.includes("/") ? ` ${file.path.slice(0, file.path.lastIndexOf("/"))}` : ""}
</Text>
@@ -2504,11 +2506,11 @@ const styles = StyleSheet.create((theme) => ({
fileHeader: {
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
paddingLeft: theme.spacing[3],
paddingRight: theme.spacing[2],
paddingVertical: theme.spacing[2],
gap: theme.spacing[1],
minWidth: 0,
zIndex: 2,
elevation: 2,
},
@@ -2532,13 +2534,15 @@ const styles = StyleSheet.create((theme) => ({
fontSize: theme.fontSize.sm,
fontWeight: theme.fontWeight.normal,
color: theme.colors.foreground,
flexShrink: 0,
flexShrink: 1,
minWidth: 0,
},
fileDir: {
fontSize: theme.fontSize.sm,
fontWeight: theme.fontWeight.normal,
color: theme.colors.foregroundMuted,
flex: 1,
minWidth: 0,
},
newBadge: {
backgroundColor: "rgba(46, 160, 67, 0.2)",
@@ -97,7 +97,11 @@ const {
const hoistedMockClient = {
isConnected: true,
getCheckoutStatus: vi.fn(async () => ({ currentBranch: "main" })),
getCheckoutStatus: vi.fn(
async (): Promise<{ currentBranch: string | null }> => ({
currentBranch: "main",
}),
),
getBranchSuggestions: vi.fn(async () => ({ branches: ["main", "dev", "feat/x"] })),
searchGitHub: vi.fn(async () => ({
items: [hoistedPrItem, hoistedPrItemB],
@@ -672,7 +676,7 @@ describe("NewWorkspaceScreen picker payload", () => {
});
});
it("sends no new fields when nothing is selected (default)", async () => {
it("uses the loaded current branch as the selected branch", async () => {
renderScreen();
await flush();
@@ -684,12 +688,24 @@ describe("NewWorkspaceScreen picker payload", () => {
expect(call).toMatchObject({
cwd: "/repo",
worktreeSlug: "gentle-slug",
action: "branch-off",
refName: "main",
});
expect(call).not.toHaveProperty("refName");
expect(call).not.toHaveProperty("action");
expect(call).not.toHaveProperty("githubPrNumber");
});
it("requires a branch selection when the current branch is unavailable", async () => {
mockClient.getCheckoutStatus.mockResolvedValueOnce({ currentBranch: null });
renderScreen();
await flush();
click(await findByTestId("test-composer-submit"));
await flush();
expect(mockClient.createPaseoWorktree).not.toHaveBeenCalled();
expect(document.body.textContent).toContain("Choose a branch to start from");
});
it("opens the new workspace draft tab as soon as the worktree is ready", async () => {
initialDraftState.text = "please review this change";
renderScreen();
@@ -194,6 +194,15 @@ function pickerItemTriggerLabel(item: PickerItem): string {
return item.kind === "branch" ? item.name : formatPrLabel(item.item);
}
function resolveSelectedPickerItem(input: {
pickerSelection: PickerSelection | null;
currentBranch: string | null | undefined;
}): PickerItem | null {
if (input.pickerSelection) return input.pickerSelection.item;
const currentBranch = input.currentBranch?.trim();
return currentBranch ? { kind: "branch", name: currentBranch } : null;
}
function syncPickerPrAttachment(input: {
attachments: ComposerAttachment[];
previousPickerPrNumber: number | null;
@@ -436,7 +445,6 @@ export function NewWorkspaceScreen({
const displayName = displayNameProp?.trim() ?? "";
const workspace = createdWorkspace;
const selectedItem = pickerSelection?.item ?? null;
const isPending = pendingAction !== null;
const client = useHostRuntimeClient(serverId);
const isConnected = useHostRuntimeIsConnected(serverId);
@@ -476,7 +484,10 @@ export function NewWorkspaceScreen({
refetchOnWindowFocus: false,
});
const currentBranch = checkoutStatusQuery.data?.currentBranch ?? null;
const selectedItem = resolveSelectedPickerItem({
pickerSelection,
currentBranch: checkoutStatusQuery.data?.currentBranch,
});
const branchSuggestionsQuery = useQuery({
queryKey: ["branch-suggestions", serverId, sourceDirectory, debouncedPickerSearchQuery],
@@ -527,8 +538,8 @@ export function NewWorkspaceScreen({
const triggerLabel = useMemo(() => {
if (selectedItem) return pickerItemTriggerLabel(selectedItem);
return currentBranch ?? "main";
}, [currentBranch, selectedItem]);
return "Select branch";
}, [selectedItem]);
const selectedOptionId = useMemo(() => {
if (!selectedItem) return "";
@@ -588,6 +599,9 @@ export function NewWorkspaceScreen({
const buildCreateWorktreeInput = useCallback(
(input: { cwd: string; attachments: AgentAttachment[] }) => {
const checkoutRequest = pickerItemToCheckoutRequest(selectedItem);
if (!checkoutRequest) {
throw new Error("Choose a branch to start from");
}
return {
cwd: input.cwd,