In this lecture I am going to give a demonstration of a new tool that I will make available for you to use in this course, an AI coding assistant.
I will show a couple of a examples of how I used the coding assistant to write a new version of the mail example I showed in the last lecture.
The coding assistant we will be using makes use of a free extension you can install in Visual Studio Code coupled with a large language model we have running on a server in the department. This tool is free, you will have unlimited access to the LLM.
The extension we are going to make use of is called Cline. Here are instructions on how to get Cline set up:
tab on the left side bar to bring up the extensions view.
on the left side bar. I recommend that you drag that tab all the way over to the right side of the main window to place the Cline view in the right side bar.
icon in the top right corner of the main window to make it visible.
Click this to go to Cline settings.http://143.44.10.188:1234/ in the field below that checkbox.To use Cline to write code for you can either open the folder for an existing project, or you can create an new, empty folder and open that instead. For today's example I will be creating a project from scratch: if you would like to follow along and try these steps yourself, you should start by making a new, empty project folder.
The first step in getting ready to use Cline is giving Cline some ground rules. These rules will guide Cline through the process of writing code for you, and will help guarantee that Cline writes code that you can understand.
The primary mechanism we will use to steer Cline is a configuration file named agents.md. We are going to put this file in a standard location where Cline will know to look for it.
Start by creating a new folder inside your project folder. Name that folder .clinerules Note the dot at the start of the folder name - that has to be part of the name.
Inside the .clinerules folder create a new file and name it agents.md This is a standard file that coding agents look for in projects. Inside this file we will give the agent some guidelines on how to write code for a project.
Paste the following text into the agents.md file:
# Project Type
This is a web project using HTML, CSS and JavaScript
This project also works with a REST server as its back end. In the initial prompt I will specify the base URL for that server application and supply documentation for the server's API
## Project structure
The project will consist of a single HTML file and a single JavaScript file.
Place JavaScript code in a separate .js file and link it into the HTML file.
Use Bootstrap 5 to style the HTML page. Link in Bootstrap from a CDN.
This is a single page application that uses multiple divs that will get shown and hidden as the user progresses through the application.
## Coding rules
Use plain JavaScript only - no libraries
Try to avoid the use of arrow functions or anonymous functions - use named functions whereever possible instead.
Use for-of loops for iteration instead of traditional for loops.
Do not use the HTML form element. Instead, use text input elements coupled with button elements to implement interactivity. You will write click listeners for those buttons to carry out user actions.
Use fetch() with promises for all interactions with the back end server.
Put code in a setup() function at the bottom of the JavaScript file that attaches click listeners to any buttons in the HTML. Use the code
window.addEventListener('load',setup,false);
below the setup() function.
## Testing
After writing code do not attempt to run any tests. I will test the code myself by loading it into a browser.
Next, we are going to go through a step-by-step process in which we have Cline write out the mail application one part at a time.
The code we are about to ask the agent to write for us will feature some interactions with a back end server. Before the agent can write this code for us, it will need to have some more information about how the back end works.
Fortunately, we can obtain this information from the back end in a form that Cline can work with.
Start by opening a new browser tab and going to the documentation page for the mail back end:
https://cmsc106.net/mail/swagger-ui/index.html
Near the top of the page you will see a small link /mail/v3/api-docs Click this link to go to a page that displays documentation for the back end server in a structured format. If you are using the Chrome browser you can click the Pretty-print checkbox at the top of the page to format this information nicely. Select all of the information in the page and copy it. Then, make a new file in your project folder named api.json and paste that information into it. (Make sure to put the api.json file in the project folder, and not inside the .clinerules subfolder.)
In the Cline pane on the right side of Visual Studio Code you will see a text box where you can type prompts for Cline.
Here is the initial prompt I used used to get Cline started on writing my solution:
I want to start work on a web application that will be a front end for a simple email system. This project is being written as a demonstration project for an introductory course on web development. The base URL for the back end server for this project is https://cmsc106.net/mail/ The server's API is documented in the file api.json. Create a mail.html file and set it up with two initial divs: a login div and a div to display a list of messages. For this first version don't try to display anything other than a loading message in the second div. Set up the login div with what the user needs to either log in or create a new account. Upon successful login or new account creation, hide the first div and show the second div.
Cline will think about the problem for a little bit and then generate some code. Before saving that code to a file Cline will prompt you to approve the changes. You should then look over the code and make sure that you approve, and then you can go ahead and click the save button to approve the changes.
Note that I have not asked for a lot in this first round. My approach is going to be to write the application a little bit at a time. After each round where Cline writes some code for me I am going to open the mail.html file in a browser and run it to make sure that the code that Cline just wrote does what I expect. If at any point the code does not work correctly, I can type a message into the prompt box in Cline to tell Cline about the problem and ask it to fix it before going on.
Below are the prompts that I used for successive rounds in the process of building the app.
After successful login we want to display a list of handles in the second div. Add the fetch code needed to download the handles. In the callback function for that fetch call display the name of the sender and the message subject for each of the handles.
Next we want to make the items in the handle list selectable. When a user clicks on one of the handles I want that handle highlighted to show that it has been selected. You will need to add a global variable to track which list item is currently selected. When the user clicks on a new item you should unhighlight the previously selected item and highlight the item they clicked on.
When a user clicks on one of the handles they are not just selecting a handle - they are also selecting a message to operate on. When you build the list to display the items you need to associate each list item with a particular message. Do this by reading the messageid from the handle and storing that as a data-message attribute in the item. Then, when the user clicks on an item to select it you should read that attribute back from the item and use it to update the value of a selectedMessageId global variable.
Next I want to add three buttons to the bottom of the second div: a 'Read' button, a 'Delete' button, and a 'Compose' button. Do not write any of the click handlers for these buttos yet - we will work through those one at a time in later rounds.
Now lets add a click handler for the read button. Clicking this button should hide the second div and show a third div. The third div will display the details of the currently selected message, including the sender, timestamp, subject, and body of the message.
Next, implement the click handler for the delete button, which should delete the currently selected message and then rebuild the handles list. Use the user id of the currently logged in user as the recipient id for the delete request.
Next we need a click handler for the compose button. This button should hide the second div and show a fourth div. The fourth div will have input elements for composing a new message: the subject, a comma separated list of recipients for the messsage, and the body of the message itself. Put a 'Cancel' button and a 'Send' button at the bottom of the fourth div, but do not write any click handlers for those buttons in this round.
Now lets write the click handlers for the Cancel and Send buttons for the fourth div. The cancel button should hide the fouth div and show the second one again. The send button should send the message and then go back to the second div after the message is sent. Sending a message is a multistep process. The first step is to post the message details to the server. The sender property in the message object should be set to the id of the currently logged in user. In response to posting the message, the server will send you back an id for the newly created message. The second step is to post each of the recipients of the message one at a time.
The approach I used above to build my solution is very careful and systematic.
In order to test the capabilities of the system I did a second experiment in which I asked Cline to write the entire solution in one go. This is commonly referred to as one-shot prompting.
Here is the prompt I started with:
I would like to build a front end for a simple email system. This web application will communicate with a back end server whose base URL is https://cmsc106.net/mail/ In the api.json file you will find documentation on the server's API. I would like for my app to be a single page application with four divs: 1) A div where the user can log in to an existing account or create a new account 2) A div that displays a list of message handles along with Read and Compose buttons. 3) A div to display a message the user has asked to read. This div will have Close and Delete buttons. 4) A div for composing a new message. This div will have Cancel and Send buttons. The list of message handles in the second div should display the sender and subject for each message. Items in this list should be selectable: the user should be able to click on an item to select it. Selected items should be highlighted. When the user selects an item and clicks the Read button the app will take them to the third div to display the full message. If you require any further details or clarification on the requirements, please ask me.
Because I am asking Cline to write an entire program at once, it is a good idea to ask Cline to start by making an implementation plan. Before hitting enter to launch the prompt, you should click the Plan tab below the text box to put Cline in plan mode.
For the purposes of this experiment I skipped the planning step and had Cline jump straight to implementation.
Not surprisingly, the intial version was missing a key detail that I left out of the prompt. Here is a follow-up prompt I had to give Cline:
There is one thing in the application that needs to be fixed. In the div where the user can compose an email the To field should allow the user to type a comma separated list of recipient names. When the user does that you will need to post each recipient to the server separately.
Finally, I had to have Cline fix a small issue in the second div:
There is one small problem remaining. At the top of the second div you are displaying the user id of the logged in user. It would be much more user friendly to display the name of the logged in user instead.
After convincing myself that the app worked correctly I also did a code review to make sure that Cline did not sneak in any programming tricks that were overly exotic or advanced. Thanks to the guidelines that I put in place in the agents.md file, the result tracked the techniques we are using in this class pretty closely.
As an added bonus Cline also added more error checking code than the first version had. Cline systematically anticipated things that could go wrong at various places in the application and added code to catch and respond to those errors.