Browse Source

Fix vscode returning invalid array object for history state on certain devices

Saoud Rizwan 1 year ago
parent
commit
4f00f89bf3

+ 1 - 1
package.json

@@ -2,7 +2,7 @@
   "name": "claude-dev",
   "displayName": "Claude Dev",
   "description": "Autonomous coding agent right in your IDE, capable of creating/editing files, executing commands, and more with your permission every step of the way.",
-  "version": "1.3.2",
+  "version": "1.3.3",
   "icon": "icon.png",
   "engines": {
     "vscode": "^1.84.0"

+ 1 - 1
src/providers/ClaudeDevProvider.ts

@@ -447,7 +447,7 @@ export class ClaudeDevProvider implements vscode.WebviewViewProvider {
 				customInstructions,
 				themeName: vscode.workspace.getConfiguration("workbench").get<string>("colorTheme"),
 				claudeMessages: this.claudeDev?.claudeMessages || [],
-				taskHistory: (taskHistory || []).sort((a, b) => b.ts - a.ts),
+				taskHistory: (taskHistory || []).filter((item) => item.ts && item.task).sort((a, b) => b.ts - a.ts),
 				shouldShowAnnouncement: lastShownAnnouncementId !== this.latestAnnouncementId,
 			},
 		})

+ 49 - 43
webview-ui/src/components/HistoryPreview.tsx

@@ -69,54 +69,60 @@ const HistoryPreview = ({ taskHistory, showHistoryView }: HistoryPreviewProps) =
 			</div>
 
 			<div style={{ padding: "0px 20px 0 20px" }}>
-				{taskHistory.slice(0, 3).map((item) => (
-					<div key={item.id} className="history-preview-item" onClick={() => handleHistorySelect(item.id)}>
-						<div style={{ padding: "12px" }}>
-							<div style={{ marginBottom: "8px" }}>
-								<span
+				{taskHistory
+					.filter((item) => item.ts && item.task && item.totalCost)
+					.slice(0, 3)
+					.map((item) => (
+						<div
+							key={item.id}
+							className="history-preview-item"
+							onClick={() => handleHistorySelect(item.id)}>
+							<div style={{ padding: "12px" }}>
+								<div style={{ marginBottom: "8px" }}>
+									<span
+										style={{
+											color: "var(--vscode-descriptionForeground)",
+											fontWeight: 500,
+											fontSize: "0.85em",
+											textTransform: "uppercase",
+										}}>
+										{formatDate(item.ts)}
+									</span>
+								</div>
+								<div
 									style={{
+										fontSize: "var(--vscode-font-size)",
 										color: "var(--vscode-descriptionForeground)",
-										fontWeight: 500,
-										fontSize: "0.85em",
-										textTransform: "uppercase",
+										marginBottom: "8px",
+										display: "-webkit-box",
+										WebkitLineClamp: 3,
+										WebkitBoxOrient: "vertical",
+										overflow: "hidden",
+										whiteSpace: "pre-wrap",
+										wordBreak: "break-word",
+										overflowWrap: "anywhere",
 									}}>
-									{formatDate(item.ts)}
-								</span>
-							</div>
-							<div
-								style={{
-									fontSize: "var(--vscode-font-size)",
-									color: "var(--vscode-descriptionForeground)",
-									marginBottom: "8px",
-									display: "-webkit-box",
-									WebkitLineClamp: 3,
-									WebkitBoxOrient: "vertical",
-									overflow: "hidden",
-									whiteSpace: "pre-wrap",
-									wordBreak: "break-word",
-									overflowWrap: "anywhere",
-								}}>
-								{item.task}
-							</div>
-							<div style={{ fontSize: "0.85em", color: "var(--vscode-descriptionForeground)" }}>
-								<span>
-									Tokens: ↑{item.tokensIn?.toLocaleString()} ↓{item.tokensOut?.toLocaleString()}
-								</span>
-								{" • "}
-								{item.cacheWrites && item.cacheReads && (
-									<>
-										<span>
-											Cache: +{item.cacheWrites?.toLocaleString()} →{" "}
-											{item.cacheReads?.toLocaleString()}
-										</span>
-										{" • "}
-									</>
-								)}
-								<span>API Cost: ${item.totalCost?.toFixed(4)}</span>
+									{item.task}
+								</div>
+								<div style={{ fontSize: "0.85em", color: "var(--vscode-descriptionForeground)" }}>
+									<span>
+										Tokens: ↑{item.tokensIn?.toLocaleString()} ↓{item.tokensOut?.toLocaleString()}
+									</span>
+									{" • "}
+									{item.cacheWrites && item.cacheReads && (
+										<>
+											<span>
+												Cache: +{item.cacheWrites?.toLocaleString()} →{" "}
+												{item.cacheReads?.toLocaleString()}
+											</span>
+											{" • "}
+										</>
+									)}
+									<span>API Cost: ${item.totalCost?.toFixed(4)}</span>
+								</div>
 							</div>
 						</div>
-					</div>
-				))}
+					))}
 				<div style={{ display: "flex", alignItems: "center", justifyContent: "center" }}>
 					<VSCodeButton
 						appearance="icon"

+ 134 - 126
webview-ui/src/components/HistoryView.tsx

@@ -98,114 +98,68 @@ const HistoryView = ({ taskHistory, onDone }: HistoryViewProps) => {
 						</div>
 					)}
 
-					{taskHistory.map((item, index) => (
-						<div
-							key={item.id}
-							className="history-item"
-							style={{
-								cursor: "pointer",
-								borderBottom:
-									index < taskHistory.length - 1 ? "1px solid var(--vscode-panel-border)" : "none",
-							}}
-							onClick={() => handleHistorySelect(item.id)}>
+					{taskHistory
+						.filter((item) => item.ts && item.task && item.totalCost)
+						.map((item, index) => (
 							<div
+								key={item.id}
+								className="history-item"
 								style={{
-									display: "flex",
-									flexDirection: "column",
-									gap: "8px",
-									padding: "12px 20px",
-									position: "relative",
-								}}>
+									cursor: "pointer",
+									borderBottom:
+										index < taskHistory.length - 1
+											? "1px solid var(--vscode-panel-border)"
+											: "none",
+								}}
+								onClick={() => handleHistorySelect(item.id)}>
 								<div
 									style={{
 										display: "flex",
-										justifyContent: "space-between",
-										alignItems: "center",
+										flexDirection: "column",
+										gap: "8px",
+										padding: "12px 20px",
+										position: "relative",
 									}}>
-									<span
-										style={{
-											color: "var(--vscode-descriptionForeground)",
-											fontWeight: 500,
-											fontSize: "0.85em",
-											textTransform: "uppercase",
-										}}>
-										{formatDate(item.ts)}
-									</span>
-									<VSCodeButton
-										appearance="icon"
-										onClick={(e) => {
-											e.stopPropagation()
-											handleDeleteHistoryItem(item.id)
-										}}
-										className="delete-button">
-										<span className="codicon codicon-trash"></span>
-									</VSCodeButton>
-								</div>
-								<div
-									style={{
-										fontSize: "var(--vscode-font-size)",
-										color: "var(--vscode-foreground)",
-										display: "-webkit-box",
-										WebkitLineClamp: 3,
-										WebkitBoxOrient: "vertical",
-										overflow: "hidden",
-										whiteSpace: "pre-wrap",
-										wordBreak: "break-word",
-										overflowWrap: "anywhere",
-									}}>
-									{item.task}
-								</div>
-								<div style={{ display: "flex", flexDirection: "column", gap: "4px" }}>
 									<div
 										style={{
 											display: "flex",
+											justifyContent: "space-between",
 											alignItems: "center",
-											gap: "4px",
-											flexWrap: "wrap",
 										}}>
 										<span
 											style={{
-												fontWeight: 500,
-												color: "var(--vscode-descriptionForeground)",
-											}}>
-											Tokens:
-										</span>
-										<span
-											style={{
-												display: "flex",
-												alignItems: "center",
-												gap: "3px",
-												color: "var(--vscode-descriptionForeground)",
-											}}>
-											<i
-												className="codicon codicon-arrow-up"
-												style={{
-													fontSize: "12px",
-													fontWeight: "bold",
-													marginBottom: "-2px",
-												}}
-											/>
-											{item.tokensIn?.toLocaleString()}
-										</span>
-										<span
-											style={{
-												display: "flex",
-												alignItems: "center",
-												gap: "3px",
 												color: "var(--vscode-descriptionForeground)",
+												fontWeight: 500,
+												fontSize: "0.85em",
+												textTransform: "uppercase",
 											}}>
-											<i
-												className="codicon codicon-arrow-down"
-												style={{
-													fontSize: "12px",
-													fontWeight: "bold",
-													marginBottom: "-2px",
-												}}
-											/>
-											{item.tokensOut?.toLocaleString()}
+											{formatDate(item.ts)}
 										</span>
+										<VSCodeButton
+											appearance="icon"
+											onClick={(e) => {
+												e.stopPropagation()
+												handleDeleteHistoryItem(item.id)
+											}}
+											className="delete-button">
+											<span className="codicon codicon-trash"></span>
+										</VSCodeButton>
+									</div>
+									<div
+										style={{
+											fontSize: "var(--vscode-font-size)",
+											color: "var(--vscode-foreground)",
+											display: "-webkit-box",
+											WebkitLineClamp: 3,
+											WebkitBoxOrient: "vertical",
+											overflow: "hidden",
+											whiteSpace: "pre-wrap",
+											wordBreak: "break-word",
+											overflowWrap: "anywhere",
+										}}>
+										{item.task}
 									</div>
-									{item.cacheWrites && item.cacheReads && (
+									<div style={{ display: "flex", flexDirection: "column", gap: "4px" }}>
 										<div
 											style={{
 												display: "flex",
@@ -218,7 +172,7 @@ const HistoryView = ({ taskHistory, onDone }: HistoryViewProps) => {
 													fontWeight: 500,
 													color: "var(--vscode-descriptionForeground)",
 												}}>
-												Cache:
+												Tokens:
 											</span>
 											<span
 												style={{
@@ -228,14 +182,14 @@ const HistoryView = ({ taskHistory, onDone }: HistoryViewProps) => {
 													color: "var(--vscode-descriptionForeground)",
 												}}>
 												<i
-													className="codicon codicon-database"
+													className="codicon codicon-arrow-up"
 													style={{
 														fontSize: "12px",
 														fontWeight: "bold",
-														marginBottom: "-1px",
+														marginBottom: "-2px",
 													}}
 												/>
-												+{item.cacheWrites?.toLocaleString()}
+												{item.tokensIn?.toLocaleString()}
 											</span>
 											<span
 												style={{
@@ -245,47 +199,101 @@ const HistoryView = ({ taskHistory, onDone }: HistoryViewProps) => {
 													color: "var(--vscode-descriptionForeground)",
 												}}>
 												<i
-													className="codicon codicon-arrow-right"
-													style={{ fontSize: "12px", fontWeight: "bold", marginBottom: 0 }}
+													className="codicon codicon-arrow-down"
+													style={{
+														fontSize: "12px",
+														fontWeight: "bold",
+														marginBottom: "-2px",
+													}}
 												/>
-												{item.cacheReads?.toLocaleString()}
+												{item.tokensOut?.toLocaleString()}
 											</span>
 										</div>
-									)}
-									<div
-										style={{
-											display: "flex",
-											justifyContent: "space-between",
-											alignItems: "center",
-											marginTop: -2,
-										}}>
-										<div style={{ display: "flex", alignItems: "center", gap: "4px" }}>
-											<span
+										{item.cacheWrites && item.cacheReads && (
+											<div
 												style={{
-													fontWeight: 500,
-													color: "var(--vscode-descriptionForeground)",
+													display: "flex",
+													alignItems: "center",
+													gap: "4px",
+													flexWrap: "wrap",
 												}}>
-												API Cost:
-											</span>
-											<span style={{ color: "var(--vscode-descriptionForeground)" }}>
-												${item.totalCost?.toFixed(4)}
-											</span>
-										</div>
-										<VSCodeButton
-											appearance="icon"
-											onClick={(e) => {
-												e.stopPropagation()
-												handleExportMd(item.id)
+												<span
+													style={{
+														fontWeight: 500,
+														color: "var(--vscode-descriptionForeground)",
+													}}>
+													Cache:
+												</span>
+												<span
+													style={{
+														display: "flex",
+														alignItems: "center",
+														gap: "3px",
+														color: "var(--vscode-descriptionForeground)",
+													}}>
+													<i
+														className="codicon codicon-database"
+														style={{
+															fontSize: "12px",
+															fontWeight: "bold",
+															marginBottom: "-1px",
+														}}
+													/>
+													+{item.cacheWrites?.toLocaleString()}
+												</span>
+												<span
+													style={{
+														display: "flex",
+														alignItems: "center",
+														gap: "3px",
+														color: "var(--vscode-descriptionForeground)",
+													}}>
+													<i
+														className="codicon codicon-arrow-right"
+														style={{
+															fontSize: "12px",
+															fontWeight: "bold",
+															marginBottom: 0,
+														}}
+													/>
+													{item.cacheReads?.toLocaleString()}
+												</span>
+											</div>
+										)}
+										<div
+											style={{
+												display: "flex",
+												justifyContent: "space-between",
+												alignItems: "center",
+												marginTop: -2,
 											}}>
-											<div style={{ fontSize: "11px", fontWeight: 500, opacity: 1 }}>
-												EXPORT .MD
+											<div style={{ display: "flex", alignItems: "center", gap: "4px" }}>
+												<span
+													style={{
+														fontWeight: 500,
+														color: "var(--vscode-descriptionForeground)",
+													}}>
+													API Cost:
+												</span>
+												<span style={{ color: "var(--vscode-descriptionForeground)" }}>
+													${item.totalCost?.toFixed(4)}
+												</span>
 											</div>
-										</VSCodeButton>
+											<VSCodeButton
+												appearance="icon"
+												onClick={(e) => {
+													e.stopPropagation()
+													handleExportMd(item.id)
+												}}>
+												<div style={{ fontSize: "11px", fontWeight: 500, opacity: 1 }}>
+													EXPORT .MD
+												</div>
+											</VSCodeButton>
+										</div>
 									</div>
 								</div>
 							</div>
-						</div>
-					))}
+						))}
 				</div>
 			</div>
 		</>