History

Move worktree branch auto-rename into provider turn reactor

- Generate and rename temporary `t3code/*` worktree branches on first user turn in `ProviderCommandReactor` - Remove websocket/client branch-generation RPCs and related contract/API surface - Update Codex text-generation prompt to include attachment metadata only when attachments exist, with expanded tests

Julius Marminge committed 8 months ago

Commit 5e55aa31 parent a21095b12 files · +405 −264Browse files

Showing the changes to apps/web/src (2 of 12 files). Show all

Unified · Split

2 files
  1. apps/web/src/components/ChatView.tsx +0 −72
  2. apps/web/src/wsNativeApi.ts +0 −3
apps/web/src/components/ChatView.tsx+0−72
@@ -247,43 +247,6 @@ function buildTemporaryWorktreeBranchName(message: string): string { · 246 unmodified lines
247 return `${WORKTREE_BRANCH_PREFIX}/${hashBranchSeed(seed)}`;247 return `${WORKTREE_BRANCH_PREFIX}/${hashBranchSeed(seed)}`;
248}248}
249 249
250function imageReferenceForBranchNaming(image: ComposerImageAttachment): string {
251 const maybePath = (image.file as File & { path?: unknown }).path;
252 if (typeof maybePath === "string" && maybePath.trim().length > 0) {
253 return maybePath.trim();
254 }
255 return image.name;
256}
257
258function buildBranchNameGenerationMessage(
259 text: string,
260 images: ReadonlyArray<ComposerImageAttachment>,
261): string {
262 const trimmedText = text.trim();
263 const imageReferences = Array.from(
264 new Set(
265 images
266 .map((image) => imageReferenceForBranchNaming(image).trim())
267 .filter((reference) => reference.length > 0),
268 ),
269 );
270 const attachmentsSection =
271 imageReferences.length > 0
272 ? `Attached images:\n${imageReferences.map((reference) => `- ${reference}`).join("\n")}`
273 : "";
274
275 if (trimmedText.length > 0 && attachmentsSection.length > 0) {
276 return `${trimmedText}\n\n${attachmentsSection}`;
277 }
278 if (trimmedText.length > 0) {
279 return trimmedText;
280 }
281 if (attachmentsSection.length > 0) {
282 return attachmentsSection;
283 }
284 return "New worktree change";
285}
286
287const VscodeEntryIcon = memo(function VscodeEntryIcon(props: {250const VscodeEntryIcon = memo(function VscodeEntryIcon(props: {
288 pathValue: string;251 pathValue: string;
289 kind: "file" | "directory";252 kind: "file" | "directory";
@@ -1530,7 +1493,6 @@ export default function ChatView({ threadId }: ChatViewProps) { · 1240 unmodified lines
1530 const composerImagesSnapshot = [...composerImages];1493 const composerImagesSnapshot = [...composerImages];
1531 const messageIdForSend = newMessageId();1494 const messageIdForSend = newMessageId();
1532 const messageCreatedAt = new Date().toISOString();1495 const messageCreatedAt = new Date().toISOString();
1533 const branchNameMessage = buildBranchNameGenerationMessage(trimmed, composerImagesSnapshot);
1534 const turnAttachmentsPromise = Promise.all(1496 const turnAttachmentsPromise = Promise.all(
1535 composerImagesSnapshot.map(1497 composerImagesSnapshot.map(
1536 async (1498 async (
@@ -1578,7 +1540,6 @@ export default function ChatView({ threadId }: ChatViewProps) { · 41 unmodified lines
1578 setComposerHighlightedItemId(null);1540 setComposerHighlightedItemId(null);
1579 1541
1580 let attemptedTurnStart = false;1542 let attemptedTurnStart = false;
1581 let pendingWorktreeBranchRename: Promise<void> | null = null;
1582 try {1543 try {
1583 // On first message: lock in branch + create worktree if needed.1544 // On first message: lock in branch + create worktree if needed.
1584 if (baseBranchForWorktree) {1545 if (baseBranchForWorktree) {
@@ -1604,36 +1565,6 @@ export default function ChatView({ threadId }: ChatViewProps) { · 19 unmodified lines
1604 branch: result.worktree.branch,1565 branch: result.worktree.branch,
1605 worktreePath: result.worktree.path,1566 worktreePath: result.worktree.path,
1606 });1567 });
1607 pendingWorktreeBranchRename = (async () => {
1608 const turnAttachments = await turnAttachmentsPromise;
1609 const renamed = await api.git.generateAndRenameBranch({
1610 cwd: result.worktree.path,
1611 oldBranch: result.worktree.branch,
1612 message: branchNameMessage,
1613 attachments: turnAttachments,
1614 });
1615 if (!renamed.branch || renamed.branch === result.worktree.branch) {
1616 return;
1617 }
1618 await api.orchestration.dispatchCommand({
1619 type: "thread.meta.update",
1620 commandId: newCommandId(),
1621 threadId: threadIdForSend,
1622 branch: renamed.branch,
1623 worktreePath: result.worktree.path,
1624 });
1625 dispatch({
1626 type: "SET_THREAD_BRANCH",
1627 threadId: threadIdForSend,
1628 branch: renamed.branch,
1629 worktreePath: result.worktree.path,
1630 });
1631 })().catch((error) => {
1632 console.warn("Failed to rename generated worktree branch", {
1633 threadId: threadIdForSend,
1634 error: error instanceof Error ? error.message : String(error),
1635 });
1636 });
1637 const setupScript = setupProjectScript(activeProject.scripts);1568 const setupScript = setupProjectScript(activeProject.scripts);
1638 if (setupScript) {1569 if (setupScript) {
1639 await runProjectScript(setupScript, {1570 await runProjectScript(setupScript, {
@@ -1683,9 +1614,6 @@ export default function ChatView({ threadId }: ChatViewProps) { · 43 unmodified lines
1683 sandboxMode,1614 sandboxMode,
1684 createdAt: messageCreatedAt,1615 createdAt: messageCreatedAt,
1685 });1616 });
1686 if (pendingWorktreeBranchRename) {
1687 void pendingWorktreeBranchRename;
1688 }
1689 } catch (err) {1617 } catch (err) {
1690 if (1618 if (
1691 !attemptedTurnStart &&1619 !attemptedTurnStart &&
apps/web/src/wsNativeApi.ts+0−3
@@ -164,9 +164,6 @@ export function createWsNativeApi(): NativeApi { · 163 unmodified lines
164 runStackedAction: (input) => transport.request(WS_METHODS.gitRunStackedAction, input),164 runStackedAction: (input) => transport.request(WS_METHODS.gitRunStackedAction, input),
165 listBranches: (input) => transport.request(WS_METHODS.gitListBranches, input),165 listBranches: (input) => transport.request(WS_METHODS.gitListBranches, input),
166 createWorktree: (input) => transport.request(WS_METHODS.gitCreateWorktree, input),166 createWorktree: (input) => transport.request(WS_METHODS.gitCreateWorktree, input),
167 generateBranchName: (input) => transport.request(WS_METHODS.gitGenerateBranchName, input),
168 generateAndRenameBranch: (input) =>
169 transport.request(WS_METHODS.gitGenerateAndRenameBranch, input),
170 renameBranch: (input) => transport.request(WS_METHODS.gitRenameBranch, input),167 renameBranch: (input) => transport.request(WS_METHODS.gitRenameBranch, input),
171 removeWorktree: (input) => transport.request(WS_METHODS.gitRemoveWorktree, input),168 removeWorktree: (input) => transport.request(WS_METHODS.gitRemoveWorktree, input),
172 createBranch: (input) => transport.request(WS_METHODS.gitCreateBranch, input),169 createBranch: (input) => transport.request(WS_METHODS.gitCreateBranch, input),