Skip to content

Commit 71c63f9

Browse files
committed
language files, theming, bug fix, Test improvements
- updated language files for settings to include FilesChangedOverview. - made Files changed overview match closer to Todo list since that is the theming now. (nice and slim) - small bug fix and added test procedure for the added todo feature and working with it properly.
1 parent 8ea8926 commit 71c63f9

40 files changed

+435
-134
lines changed

src/core/checkpoints/index.ts

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -161,12 +161,27 @@ export function getCheckpointService(cline: Task) {
161161
const checkpointFileChangeManager = provider?.getFileChangeManager()
162162
if (checkpointFileChangeManager) {
163163
// Get the initial baseline (preserve for cumulative diff tracking)
164-
const initialBaseline = checkpointFileChangeManager.getChanges().baseCheckpoint
164+
let initialBaseline = checkpointFileChangeManager.getChanges().baseCheckpoint
165+
166+
// Validate that the baseline exists in the shadow repository before attempting diff
167+
// If the baseline doesn't exist (e.g., from a previous task session), fall back to shadow repo base
168+
try {
169+
await service.getDiff({ from: initialBaseline, to: initialBaseline })
170+
} catch (baselineValidationError) {
171+
const shadowBase = service.baseHash || toHash
172+
log(
173+
`[Task#checkpointCreated] Initial baseline ${initialBaseline} not found in shadow repo, falling back to shadow base ${shadowBase}`,
174+
)
175+
initialBaseline = shadowBase
176+
// Update FileChangeManager baseline to match shadow repository
177+
await checkpointFileChangeManager.updateBaseline(initialBaseline)
178+
}
179+
165180
log(
166-
`[Task#checkpointCreated] Calculating cumulative changes from initial baseline ${initialBaseline} to ${toHash}`,
181+
`[Task#checkpointCreated] Calculating cumulative changes from validated baseline ${initialBaseline} to ${toHash}`,
167182
)
168183

169-
// Calculate cumulative diff from initial baseline to new checkpoint using checkpoint service
184+
// Calculate cumulative diff from validated baseline to new checkpoint using checkpoint service
170185
const changes = await service.getDiff({ from: initialBaseline, to: toHash })
171186

172187
if (changes && changes.length > 0) {
@@ -319,10 +334,16 @@ export async function checkpointSave(cline: Task, force = false, files?: vscode.
319334
const savePromise = service
320335
.saveCheckpoint(`Task: ${cline.taskId}, Time: ${Date.now()}`, { allowEmpty: force, files })
321336
.then(async (result: any) => {
337+
// Handle case where no checkpoint was created (e.g., no changes to commit)
338+
if (!result || !result.commit) {
339+
console.log(`[checkpointSave] No checkpoint created (no changes to commit)`)
340+
return result
341+
}
342+
322343
console.log(`[checkpointSave] New checkpoint created: ${result.commit}`)
323344

324345
// Notify FCO that checkpoint was created
325-
if (provider && result) {
346+
if (provider) {
326347
try {
327348
provider.postMessageToWebview({
328349
type: "checkpoint_created",

webview-ui/src/components/chat/ChatView.tsx

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ import SystemPromptWarning from "./SystemPromptWarning"
4747
import ProfileViolationWarning from "./ProfileViolationWarning"
4848
import { CheckpointWarning } from "./CheckpointWarning"
4949
import { getLatestTodo } from "@roo/todo"
50-
import FilesChangedOverview from "../file-changes/FilesChangedOverview"
5150

5251
export interface ChatViewProps {
5352
isHidden: boolean
@@ -1569,10 +1568,6 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
15691568
<CheckpointWarning />
15701569
</div>
15711570
)}
1572-
1573-
<div className="px-3">
1574-
<FilesChangedOverview />
1575-
</div>
15761571
</>
15771572
) : (
15781573
<div className="flex-1 min-h-0 overflow-y-auto flex flex-col gap-4 relative">

webview-ui/src/components/chat/TaskHeader.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { ShareButton } from "./ShareButton"
2121
import { ContextWindowProgress } from "./ContextWindowProgress"
2222
import { Mention } from "./Mention"
2323
import { TodoListDisplay } from "./TodoListDisplay"
24+
import FilesChangedOverview from "../file-changes/FilesChangedOverview"
2425

2526
export interface TaskHeaderProps {
2627
task: ClineMessage
@@ -220,6 +221,7 @@ const TaskHeader = ({
220221
</>
221222
)}
222223
</div>
224+
<FilesChangedOverview />
223225
<TodoListDisplay todos={todos ?? (task as any)?.tool?.todos ?? []} />
224226
</div>
225227
)

webview-ui/src/components/file-changes/FilesChangedOverview.tsx

Lines changed: 86 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ const FilesChangedOverview: React.FC<FilesChangedOverviewProps> = () => {
3131

3232
// Performance optimization: Use virtualization for large file lists
3333
const VIRTUALIZATION_THRESHOLD = 50
34-
const ITEM_HEIGHT = 60 // Approximate height of each file item
34+
const ITEM_HEIGHT = 32 // Approximate height of each file item
3535
const MAX_VISIBLE_ITEMS = 10
3636
const [scrollTop, setScrollTop] = React.useState(0)
3737

@@ -198,29 +198,19 @@ const FilesChangedOverview: React.FC<FilesChangedOverviewProps> = () => {
198198
}, [checkInit, updateChangeset, handleCheckpointCreated, handleCheckpointRestored])
199199

200200
/**
201-
* Formats line change counts for display based on file type
201+
* Formats line change counts for display - shows only plus/minus numbers
202202
* @param file - The file change to format
203-
* @returns Formatted string describing the changes
203+
* @returns Formatted string with just the line change counts
204204
*/
205205
const formatLineChanges = (file: FileChange): string => {
206206
const added = file.linesAdded || 0
207207
const removed = file.linesRemoved || 0
208208

209-
if (file.type === "create") {
210-
return t("file-changes:line_changes.added", { count: added })
211-
} else if (file.type === "delete") {
212-
return t("file-changes:line_changes.deleted")
213-
} else {
214-
if (added > 0 && removed > 0) {
215-
return t("file-changes:line_changes.added_removed", { added, removed })
216-
} else if (added > 0) {
217-
return t("file-changes:line_changes.added", { count: added })
218-
} else if (removed > 0) {
219-
return t("file-changes:line_changes.removed", { count: removed })
220-
} else {
221-
return t("file-changes:line_changes.modified")
222-
}
223-
}
209+
const parts = []
210+
if (added > 0) parts.push(`+${added}`)
211+
if (removed > 0) parts.push(`-${removed}`)
212+
213+
return parts.length > 0 ? parts.join(", ") : ""
224214
}
225215

226216
// Memoize expensive total calculations
@@ -245,9 +235,10 @@ const FilesChangedOverview: React.FC<FilesChangedOverviewProps> = () => {
245235
data-testid="files-changed-overview"
246236
style={{
247237
border: "1px solid var(--vscode-panel-border)",
248-
borderRadius: "4px",
249-
padding: "12px",
250-
margin: "8px 0",
238+
borderTop: 0,
239+
borderRadius: 0,
240+
padding: "6px 10px",
241+
margin: 0,
251242
backgroundColor: "var(--vscode-editor-background)",
252243
}}>
253244
{/* Collapsible header */}
@@ -256,9 +247,10 @@ const FilesChangedOverview: React.FC<FilesChangedOverviewProps> = () => {
256247
display: "flex",
257248
justifyContent: "space-between",
258249
alignItems: "center",
259-
marginBottom: isCollapsed ? "0" : "12px",
250+
marginTop: "0 2px",
251+
//marginBottom: isCollapsed ? "0" : "6px",
260252
borderBottom: isCollapsed ? "none" : "1px solid var(--vscode-panel-border)",
261-
paddingBottom: "8px",
253+
// paddingBottom: "0px",
262254
cursor: "pointer",
263255
userSelect: "none",
264256
}}
@@ -311,7 +303,7 @@ const FilesChangedOverview: React.FC<FilesChangedOverviewProps> = () => {
311303
border: "none",
312304
borderRadius: "3px",
313305
padding: "4px 8px",
314-
fontSize: "12px",
306+
fontSize: "13px",
315307
cursor: isProcessing ? "not-allowed" : "pointer",
316308
opacity: isProcessing ? 0.6 : 1,
317309
}}
@@ -329,7 +321,7 @@ const FilesChangedOverview: React.FC<FilesChangedOverviewProps> = () => {
329321
border: "none",
330322
borderRadius: "3px",
331323
padding: "4px 8px",
332-
fontSize: "12px",
324+
fontSize: "13px",
333325
cursor: isProcessing ? "not-allowed" : "pointer",
334326
opacity: isProcessing ? 0.6 : 1,
335327
}}
@@ -348,6 +340,7 @@ const FilesChangedOverview: React.FC<FilesChangedOverviewProps> = () => {
348340
transition: "opacity 0.2s ease-in-out",
349341
opacity: isCollapsed ? 0 : 1,
350342
position: "relative",
343+
paddingTop: "8px",
351344
}}
352345
onScroll={handleScroll}>
353346
{shouldVirtualize && (
@@ -425,89 +418,94 @@ const FileItem: React.FC<FileItemProps> = React.memo(
425418
justifyContent: "space-between",
426419
alignItems: "center",
427420
padding: "6px 8px",
428-
marginBottom: "4px",
421+
marginBottom: "3px",
429422
backgroundColor: "var(--vscode-list-hoverBackground)",
430423
borderRadius: "3px",
431424
fontSize: "13px",
432-
minHeight: "60px", // Consistent height for virtualization
425+
minHeight: "32px", // Thinner rows
426+
lineHeight: "1.3",
433427
}}>
434428
<div style={{ flex: 1, minWidth: 0 }}>
435429
<div
436430
style={{
437431
fontFamily: "var(--vscode-editor-font-family)",
438-
fontSize: "12px",
432+
fontSize: "13px",
439433
color: "var(--vscode-editor-foreground)",
440434
overflow: "hidden",
441435
textOverflow: "ellipsis",
442436
whiteSpace: "nowrap",
437+
fontWeight: 500,
443438
}}>
444439
{file.uri}
445440
</div>
441+
</div>
442+
443+
<div style={{ display: "flex", alignItems: "center", gap: "8px", marginLeft: "8px" }}>
446444
<div
447445
style={{
448-
fontSize: "11px",
446+
fontSize: "12px",
449447
color: "var(--vscode-descriptionForeground)",
450-
marginTop: "2px",
448+
whiteSpace: "nowrap",
449+
flexShrink: 0,
451450
}}>
452-
{t(`file-changes:file_types.${file.type}`)}{formatLineChanges(file)}
451+
{formatLineChanges(file)}
452+
</div>
453+
<div style={{ display: "flex", gap: "4px" }}>
454+
<button
455+
onClick={() => handleWithDebounce(() => onViewDiff(file.uri))}
456+
disabled={isProcessing}
457+
title={t("file-changes:actions.view_diff")}
458+
data-testid={`diff-${file.uri}`}
459+
style={{
460+
backgroundColor: "transparent",
461+
color: "var(--vscode-button-foreground)",
462+
border: "1px solid var(--vscode-button-border)",
463+
borderRadius: "3px",
464+
padding: "2px 6px",
465+
fontSize: "11px",
466+
cursor: isProcessing ? "not-allowed" : "pointer",
467+
minWidth: "50px",
468+
opacity: isProcessing ? 0.6 : 1,
469+
}}>
470+
{t("file-changes:actions.view_diff")}
471+
</button>
472+
<button
473+
onClick={() => handleWithDebounce(() => onRejectFile(file.uri))}
474+
disabled={isProcessing}
475+
title={t("file-changes:actions.reject_file")}
476+
data-testid={`reject-${file.uri}`}
477+
style={{
478+
backgroundColor: "var(--vscode-button-secondaryBackground)",
479+
color: "var(--vscode-button-secondaryForeground)",
480+
border: "1px solid var(--vscode-button-border)",
481+
borderRadius: "3px",
482+
padding: "2px 6px",
483+
fontSize: "11px",
484+
cursor: isProcessing ? "not-allowed" : "pointer",
485+
minWidth: "20px",
486+
opacity: isProcessing ? 0.6 : 1,
487+
}}>
488+
489+
</button>
490+
<button
491+
onClick={() => handleWithDebounce(() => onAcceptFile(file.uri))}
492+
disabled={isProcessing}
493+
title={t("file-changes:actions.accept_file")}
494+
data-testid={`accept-${file.uri}`}
495+
style={{
496+
backgroundColor: "var(--vscode-button-background)",
497+
color: "var(--vscode-button-foreground)",
498+
border: "1px solid var(--vscode-button-border)",
499+
borderRadius: "3px",
500+
padding: "2px 6px",
501+
fontSize: "11px",
502+
cursor: isProcessing ? "not-allowed" : "pointer",
503+
minWidth: "20px",
504+
opacity: isProcessing ? 0.6 : 1,
505+
}}>
506+
507+
</button>
453508
</div>
454-
</div>
455-
456-
<div style={{ display: "flex", gap: "4px", marginLeft: "8px" }}>
457-
<button
458-
onClick={() => handleWithDebounce(() => onViewDiff(file.uri))}
459-
disabled={isProcessing}
460-
title={t("file-changes:actions.view_diff")}
461-
data-testid={`diff-${file.uri}`}
462-
style={{
463-
backgroundColor: "transparent",
464-
color: "var(--vscode-button-foreground)",
465-
border: "1px solid var(--vscode-button-border)",
466-
borderRadius: "3px",
467-
padding: "2px 6px",
468-
fontSize: "11px",
469-
cursor: isProcessing ? "not-allowed" : "pointer",
470-
minWidth: "50px",
471-
opacity: isProcessing ? 0.6 : 1,
472-
}}>
473-
{t("file-changes:actions.view_diff")}
474-
</button>
475-
<button
476-
onClick={() => handleWithDebounce(() => onRejectFile(file.uri))}
477-
disabled={isProcessing}
478-
title={t("file-changes:actions.reject_file")}
479-
data-testid={`reject-${file.uri}`}
480-
style={{
481-
backgroundColor: "var(--vscode-button-secondaryBackground)",
482-
color: "var(--vscode-button-secondaryForeground)",
483-
border: "1px solid var(--vscode-button-border)",
484-
borderRadius: "3px",
485-
padding: "2px 6px",
486-
fontSize: "11px",
487-
cursor: isProcessing ? "not-allowed" : "pointer",
488-
minWidth: "20px",
489-
opacity: isProcessing ? 0.6 : 1,
490-
}}>
491-
492-
</button>
493-
<button
494-
onClick={() => handleWithDebounce(() => onAcceptFile(file.uri))}
495-
disabled={isProcessing}
496-
title={t("file-changes:actions.accept_file")}
497-
data-testid={`accept-${file.uri}`}
498-
style={{
499-
backgroundColor: "var(--vscode-button-background)",
500-
color: "var(--vscode-button-foreground)",
501-
border: "1px solid var(--vscode-button-border)",
502-
borderRadius: "3px",
503-
padding: "2px 6px",
504-
fontSize: "11px",
505-
cursor: isProcessing ? "not-allowed" : "pointer",
506-
minWidth: "20px",
507-
opacity: isProcessing ? 0.6 : 1,
508-
}}>
509-
510-
</button>
511509
</div>
512510
</div>
513511
),

0 commit comments

Comments
 (0)