mirror of
https://github.com/backnotprop/plannotator.git
synced 2026-09-14 14:17:26 +08:00
feat: split worktree/diff-type into separate controls (#248)
* feat: split worktree/diff-type into separate controls The single dropdown that mixed diff type selection (uncommitted, last-commit, branch) with worktree switching was confusing — entering a worktree silently replaced all dropdown options with no persistent indicator of which worktree was active. Split into two controls: - Context dropdown: switches between main repo and worktrees (only shown when worktrees exist, highlighted when a worktree is active) - View dropdown: always shows the same diff type options regardless of context Server changes: - GitContext now exposes worktrees as a separate field - Removed getWorktreeDiffOptions() and back-to-main sentinel handling - Simplified /api/diff/switch (no more diffOptions replacement) Client changes: - New activeWorktreePath state + handleWorktreeSwitch callback - handleDiffSwitch composes worktree prefix from context automatically - Derived activeDiffBase strips worktree prefix for dropdown display Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: derive activeWorktreePath from diffType instead of separate state Eliminates redundant state — activeWorktreePath and activeDiffBase are now both derived in a single useMemo from the composite diffType string. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: move DiffOption, WorktreeInfo, GitContext to @plannotator/shared Eliminates duplicate interface definitions across server and client. Types now live in packages/shared/types.ts and are imported by both packages/server/git.ts and packages/review-editor/. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -10,7 +10,7 @@
|
||||
*/
|
||||
|
||||
import { isRemoteSession, getServerPort } from "./remote";
|
||||
import { type DiffType, type GitContext, runGitDiff, getWorktreeDiffOptions, getFileContentsForDiff } from "./git";
|
||||
import { type DiffType, type GitContext, runGitDiff, getFileContentsForDiff } from "./git";
|
||||
import { getRepoInfo } from "./repo";
|
||||
import { handleImage, handleUpload, handleAgents, handleServerReady, handleDraftSave, handleDraftLoad, handleDraftDelete, type OpencodeClient } from "./shared-handlers";
|
||||
import { contentHash, deleteDraft } from "./draft";
|
||||
@@ -19,7 +19,7 @@ import { createEditorAnnotationHandler } from "./editor-annotations";
|
||||
// Re-export utilities
|
||||
export { isRemoteSession, getServerPort } from "./remote";
|
||||
export { openBrowser } from "./browser";
|
||||
export { type DiffType, type DiffOption, type GitContext } from "./git";
|
||||
export { type DiffType, type DiffOption, type GitContext, type WorktreeInfo } from "./git";
|
||||
export { handleServerReady as handleReviewServerReady } from "./shared-handlers";
|
||||
|
||||
// --- Types ---
|
||||
@@ -153,13 +153,6 @@ export async function startReviewServer(
|
||||
}
|
||||
|
||||
const defaultBranch = gitContext?.defaultBranch || "main";
|
||||
const previousDiffType = currentDiffType;
|
||||
|
||||
// Handle "back to main repo" sentinel
|
||||
const isBackToMain = newDiffType === ("back-to-main" as DiffType);
|
||||
if (isBackToMain) {
|
||||
newDiffType = "uncommitted" as DiffType;
|
||||
}
|
||||
|
||||
// Run the new diff
|
||||
const result = await runGitDiff(newDiffType, defaultBranch);
|
||||
@@ -170,27 +163,12 @@ export async function startReviewServer(
|
||||
currentDiffType = newDiffType;
|
||||
currentError = result.error;
|
||||
|
||||
// Build response — include diffOptions on worktree mode transitions
|
||||
const response: Record<string, unknown> = {
|
||||
return Response.json({
|
||||
rawPatch: currentPatch,
|
||||
gitRef: currentGitRef,
|
||||
diffType: currentDiffType,
|
||||
...(currentError && { error: currentError }),
|
||||
};
|
||||
|
||||
if (isBackToMain) {
|
||||
// Exiting worktree mode: restore original dropdown options
|
||||
response.diffOptions = gitContext?.diffOptions;
|
||||
} else if (
|
||||
newDiffType.startsWith("worktree:") &&
|
||||
!previousDiffType.startsWith("worktree:")
|
||||
) {
|
||||
// Entering worktree mode: send worktree-scoped dropdown options
|
||||
const wtPath = newDiffType.slice("worktree:".length).replace(/:(?:uncommitted|last-commit|branch)$/, "");
|
||||
response.diffOptions = getWorktreeDiffOptions(wtPath, defaultBranch);
|
||||
}
|
||||
|
||||
return Response.json(response);
|
||||
});
|
||||
} catch (err) {
|
||||
const message =
|
||||
err instanceof Error ? err.message : "Failed to switch diff";
|
||||
|
||||
Reference in New Issue
Block a user