import { Anthropic } from "@anthropic-ai/sdk" import os from "os" import * as path from "path" import * as vscode from "vscode" export async function downloadTask(dateTs: number, conversationHistory: Anthropic.MessageParam[]) { // File name const date = new Date(dateTs) const month = date.toLocaleString("en-US", { month: "short" }).toLowerCase() const monthLong = date.toLocaleString("en-US", { month: "long" }) const day = date.getDate() const year = date.getFullYear() let hours = date.getHours() const minutes = date.getMinutes().toString().padStart(2, "0") const seconds = date.getSeconds().toString().padStart(2, "0") const ampm = hours >= 12 ? "pm" : "am" hours = hours % 12 hours = hours ? hours : 12 // the hour '0' should be '12' const fileName = `claude_dev_task_${month}-${day}-${year}_${hours}-${minutes}-${seconds}-${ampm}.md` // Generate markdown const markdownContent = conversationHistory .map((message) => { const role = message.role === "user" ? "**User:**" : "**Assistant:**" const content = Array.isArray(message.content) ? message.content.map(formatContentBlockToMarkdown).join("\n") : message.content const timestamp = `# ${monthLong} ${day},${year} ${hours}:${minutes}:${seconds}${ampm}`; return `${timestamp}\n${role}\n\n${content}\n\n` }) .join("---\n\n") // Prompt user for save location const saveUri = await vscode.window.showSaveDialog({ filters: { Markdown: ["md"] }, defaultUri: vscode.Uri.file(path.join(os.homedir(), "Downloads", fileName)), }) if (saveUri) { // Write content to the selected location await vscode.workspace.fs.writeFile(saveUri, Buffer.from(markdownContent)) vscode.window.showTextDocument(saveUri, { preview: true }) } } export function formatContentBlockToMarkdown( block: | Anthropic.TextBlockParam | Anthropic.ImageBlockParam | Anthropic.ToolUseBlockParam | Anthropic.ToolResultBlockParam ): string { switch (block.type) { case "text": return block.text case "image": return `[Image]` case "tool_use": let input: string if (typeof block.input === "object" && block.input !== null) { input = Object.entries(block.input) .map(([key, value]) => `${key.charAt(0).toUpperCase() + key.slice(1)}: ${value}`) .join("\n") } else { input = String(block.input) } return `[Tool Use: ${block.name}]\n${input}` case "tool_result": if (typeof block.content === "string") { return `[Tool Result${block.is_error ? " (Error)" : ""}]\n${block.content}` } else if (Array.isArray(block.content)) { return `[Tool Result${block.is_error ? " (Error)" : ""}]\n${block.content .map(formatContentBlockToMarkdown) .join("\n")}` } else { return `[Tool Result${block.is_error ? " (Error)" : ""}]` } default: return "[Unexpected content type]" } }