diff --git a/README.md b/README.md index 963a694..2fcfe8e 100644 --- a/README.md +++ b/README.md @@ -2,23 +2,33 @@ Thanks to [Claude 3.5 Sonnet's agentic coding capabilities](https://www-cdn.anthropic.com/fed9cc193a14b84131812372d8d5857f8f304c52/Model_Card_Claude_3_Addendum.pdf) Claude Dev can handle complex software development tasks step-by-step. With tools that let him read & write files, create entire projects from scratch, and execute terminal commands (after you grant permission), he can assist you in ways that go beyond simple code completion or tech support. -This project was developed for the [Build with Claude June 2024](https://docs.anthropic.com/en/build-with-claude-contest/overview) contest by Anthropic. +Claude Dev bridges the gap between complex python scripting and simple chat websites. With its intuitive GUI, it offers a safe and accessible platform for exploring the potential of agentic AI. + +- Keep track of total tokens and API usage cost for the current task loop +- View edit diffs or new files in beautifully syntax highlighted previews +- Streams command execution output into the chat, so you never have to open a terminal yourself +- Presents permission buttons (i.e. 'Approve CLI command') before tool use or sending information to the API +- Set a maximum # of API requests allowed for a task before being prompted for permission to proceed +- View the JSON of API requests when they are made and track individal API request costs +- When a task is completed, Claude Dev determines if he can present the result to you with a CLI command like `open -a "Google Chrome" index.html`, which you run with a click of a button + +This project was developed for Anthropic's [Build with Claude June 2024](https://docs.anthropic.com/en/build-with-claude-contest/overview) contest. ## How it works -Claude Dev uses an agentic loop style implementation with chain-of-thought prompting and access to powerful tools that give him the ability to accomplish nearly any task. From building software projects to running system operations, Claude Dev is only limited by your imagination. +Claude Dev uses an agentic loop style implementation with chain-of-thought prompting and access to powerful tools that give him the ability to accomplish nearly any task. From building software projects to running system operations, Claude Dev is only limited by your imagination. Start by providing a task and the agentic loop fires off, where it might use certain tools (with your permission) to accomplish each step in its thought process. ### Tools -Claude Dev has access to the following tools: +Claude Dev has access to the following capabilities: 1. **execute_command**: Execute CLI commands on the system. 2. **list_files**: List all files and directories at the top level of the specified directory. 3. **read_file**: Read the contents of a file at the specified path. 4. **write_to_file**: Write content to a file at the specified path. 5. **ask_followup_question**: Ask the user a question to gather additional information needed to complete a task. -6. **attempt_completion**: Present the result to the user after completing a task. +6. **attempt_completion**: Present the result to the user after completing a task, potentially with a CLI command to kickoff a demonstration. ### Only With Your Permission @@ -26,7 +36,7 @@ Claude always asks for your permission first before any tools are executed or in ![image](https://github.com/saoudrizwan/claude-dev/assets/7799382/e6435441-9400-41c9-98a9-63f75c5d45be) -## Screenshots +## Demo ### 1. Give Claude Dev any task! diff --git a/src/ClaudeDev.ts b/src/ClaudeDev.ts index e77610d..4f9e31c 100644 --- a/src/ClaudeDev.ts +++ b/src/ClaudeDev.ts @@ -487,6 +487,7 @@ ${openDocuments}` async askFollowupQuestion(question: string): Promise { const { text } = await this.ask("followup", question) + await this.say("user_feedback", text ?? "") return `User's response:\n\"${text}\"` } @@ -501,6 +502,7 @@ ${openDocuments}` if (response === "yesButtonTapped") { return "" } + await this.say("user_feedback", text ?? "") return `The user is not pleased with the results. Use the feedback they provided to successfully complete the task, and then attempt completion again.\nUser's feedback:\n\"${text}\"` } diff --git a/src/shared/ExtensionMessage.ts b/src/shared/ExtensionMessage.ts index 78a3b8c..d26ad44 100644 --- a/src/shared/ExtensionMessage.ts +++ b/src/shared/ExtensionMessage.ts @@ -17,7 +17,7 @@ export interface ClaudeMessage { } export type ClaudeAsk = "request_limit_reached" | "followup" | "command" | "completion_result" | "tool" -export type ClaudeSay = "task" | "error" | "api_req_started" | "api_req_finished" | "text" | "command_output" | "completion_result" +export type ClaudeSay = "task" | "error" | "api_req_started" | "api_req_finished" | "text" | "command_output" | "completion_result" | "user_feedback" export interface ClaudeSayTool { tool: "editedExistingFile" | "newFileCreated" | "readFile" | "listFiles" diff --git a/webview-ui/src/components/ChatRow.tsx b/webview-ui/src/components/ChatRow.tsx index 5194669..aaaa233 100644 --- a/webview-ui/src/components/ChatRow.tsx +++ b/webview-ui/src/components/ChatRow.tsx @@ -39,7 +39,9 @@ const ChatRow: React.FC = ({ message }) => { , - Claude wants to execute this command:, + + Claude wants to execute this command: + , ] case "completion_result": return [ @@ -115,6 +117,18 @@ const ChatRow: React.FC = ({ message }) => { return null // Hide this message type case "text": return

{message.text}

+ case "user_feedback": + return ( +
+ {message.text} +
+ ) case "error": return ( <> @@ -180,7 +194,9 @@ const ChatRow: React.FC = ({ message }) => { <>
{toolIcon("new-file")} - Claude wants to create a new file: + + Claude wants to create a new file: +
@@ -200,7 +216,9 @@ const ChatRow: React.FC = ({ message }) => { <>
{toolIcon("folder-opened")} - Claude wants to view this directory: + + Claude wants to view this directory: +
@@ -248,10 +266,7 @@ const ChatRow: React.FC = ({ message }) => {

{COMMAND_OUTPUT_STRING}

- + )} @@ -306,7 +321,10 @@ const ChatRow: React.FC = ({ message }) => { {renderContent()} {isExpanded && message.say === "api_req_started" && (
- +
)} diff --git a/webview-ui/src/components/ChatView.tsx b/webview-ui/src/components/ChatView.tsx index 6527ada..dff773d 100644 --- a/webview-ui/src/components/ChatView.tsx +++ b/webview-ui/src/components/ChatView.tsx @@ -38,7 +38,7 @@ const ChatView = ({ messages, isHidden }: ChatViewProps) => { const options = { containerId: "chat-view-container", duration: instant ? 0 : 500, - smooth: !instant, + smooth: instant ? false : 'easeOutQuint', } scroll.scrollToBottom(options) } diff --git a/webview-ui/src/components/CodeBlock.tsx b/webview-ui/src/components/CodeBlock.tsx index 53122ec..6845ab8 100644 --- a/webview-ui/src/components/CodeBlock.tsx +++ b/webview-ui/src/components/CodeBlock.tsx @@ -104,7 +104,7 @@ const CodeBlock = ({ code, diff, language, path }: CodeBlockProps) => { onClick={() => setIsExpanded(!isExpanded)}>