Build a Word Game with Windsurf's Cascade AI Agent

I've been using Cursor as my primary editor for over a year now, but recently I've heard wonderful things about Windsurf AI Agent features. I decided to record myself building out something I've always wanted to make, but never made the time for.

In this lesson, I demonstrate how to leverage Windsurf's powerful agent process to create a fun word-guessing game inspired by Heads Up. Watch as I build an interactive application featuring category selection and word navigation, complete with data hosting on GitHub Gists and deployment to GitHub Pages - all in under 30 minutes (before editing the lesson down to 12 minutes)!

What makes this project particularly exciting is how Windsurf eliminates the typical friction points of development. While this game was always on my project wishlist, the overhead of setup, configuration, and deployment made it hard to justify the time investment. Windsurf's agent process handles all these pain points seamlessly, from managing URLs to orchestrating deployment.

This lesson perfectly showcases how AI agents can help developers bring their backlog of project ideas to life, transforming what would typically be time-consuming tasks into efficient, enjoyable development experiences.

Share with a coworker

Transcript

[00:00] Let's try using Cascade. I'm going to select my John Lindquist dev folder and we'll attempt a prompt of... The goal is to create a web app very similar to the game Heads Up, where its only features are to select a category of words as the initial UI, and then after you select a category of words it presents a single word full screen on the page. The user scenario there is that someone will be holding their phone up to their forehead for other people to read that one word, so the word needs to be huge, and if someone taps on the screen then it goes to the next word. The only options on the screen should be previous and next word and also go back to selecting a category.

[00:49] So the game is broken down into a home screen of selecting a category and then when the game is live displaying a single randomized word based on that category. I would like to host this somewhere where it's freely accessible. I do have a GitHub account if GitHub Pages works, otherwise I'm open to other ideas if you have suggestions. This just needs to be a web app so that anyone with a phone can open the URL and play the game. We'll let this process and paste in.

[01:17] We'll hit enter and see what happens. Looks like it's not using a framework just a plain old index.html with styles and some javascript. It doesn't look like it started a server to host this so that's my next request, because it obviously didn't take it all the way to deploying this or anything. Please start up a local web server to host this page so I can test it out. All right it's going to use Python, that's fine.

[01:45] Let's go ahead and run that command. We'll allow Python to use our local network and then it should be on port 8000. That's not a clickable link so I'm going to copy and paste it. I'm going to drag this over from my other screen and let's see if it works. Let's choose animals.

[02:03] That looks great. Next, next, next, previous, previous. That looks pretty great and let's try going back. Movies. This is actually exactly what I wanted.

[02:18] I highly doubt it's using a database or an API of any kind. So I'm going to search the project for one of the movies was Parasite and you can see it does just have hard-coded values. So let's say I notice that all of the categories are hard-coded values inside of a JavaScript file. Is there any sort of API that I could use that's freely available or just some way of externalizing to a separate file or a database or a JSON file or something. Something that's really easy if I want to add new words to it or remove words from it.

[02:56] Essentially just build me something that'll let me add and remove categories and add or remove words to those categories. So we'll let this run. Looks like a UI glitch here. Try hitting, there we go. All right it did do quite a bit.

[03:13] It said that something failed to apply. You may ask Cascade to tell you to edit to apply it manually. So please manually update index.html by replacing the categories button section with this simpler version. I'm going to click insert and see if that does it. Oh so that expected me.

[03:32] I'll undo that. That expected me to select all of this, delete it, and manually insert it. I'll format this quickly. But it looks like these successfully applied. Or I'm actually not sure.

[03:46] I think I have to accept all changes. So I'll do that on the categories.json as well. Accept all. And then let's run the command again. It's interesting it told me to start a new server rather than just open my localhost and refresh.

[04:03] Like if I switch back over to Chrome it's still here. So we can try animals, next, next, previous, previous. Let's try editing line and putting something in front of that. Categories, switch back to Chrome, we'll refresh, animals, and now dogs in the front. So we didn't need to do this, so I'm going to reject, and now let's ask it make sure and create the UI that will allow me to automatically update this JSON file.

[04:34] Now this is where I'm very curious what it's going to do since we will have to write to the JSON file and have it stored somewhere. My mind kind of goes to either some of the free options would be like a Google Sheets thing but that's pretty complicated, or just a gist that you read and write to, or even like a Cloudflare key value or one of the key value services that could just host an object for free like this since it's just a tiny object. We'll see what it does. It looks like it's creating a server and my issue with creating a server is that I just don't want to host a server anywhere. I just want to host some raw HTML and JavaScript.

[05:16] So let's try to steer it in a different direction. I don't want to create a server because I just want to be able to host the raw HTML and JavaScript files. Can you come up with a more creative different solution that wouldn't require a server just hosting the JavaScript file somewhere where we can modify it from our static site. It looks like it came up the GitHub gist as well. I do like that idea.

[05:41] And now I'm going to be curious what it's going to do with the API keys and such so we don't expose them. All right so this is pretty standard create a gist, copy the content, get the ID, get an access token, and it looks like our gist ID will be in the script. And let's ask it about security since it didn't call it out explicitly, which is definitely a huge concern if you are a non-developer here. I'm concerned about storing credentials on a static website. Can you review how we're storing the GitHub token and are there any other ways to make this more secure without introducing a server.

[06:17] All right storing the token in local storage. I should have looked that up. I could have found that but I actually do like this solution where it's thinking outside the box of just removing the token completely and just working with a public gist where we edit the public gist manually. I think this is a completely fine approach rather than having some sort of CMS around it since it's such a simple file. So I'm just going to go ahead with this approach.

[06:39] I like it. I can work with this. This is probably what I would have done next, use some sort of GitHub actions to store and secure keys and work from a repo, considering I'm just going for free here. I do like what this says here, I agree with this, although I wish it would have called this out without me having to prompt for it. All right so let's go ahead and refresh.

[06:58] I don't see it asking me for the gist ID anywhere. I open the site in a browser and I don't see it asking me for a gist ID. Can you show me exactly where I need to add the gist ID? All right it says your gist ID on line 9, so right here. I guess this didn't load.

[07:16] Looks like it since it failed to load it fell back to that, which is actually kind of nice. I didn't think about that. I should have checked the logs. So it did fail to load it and it fell back to the local categories. So I'm going to go ahead and copy and paste this.

[07:30] I'm going to gist.new, paste this in, say categories.json, and we'll make this a public gist, grab the id here, come back and copy and paste it. And now let's go into our app, let's reload, and if we check our network you can see it loaded categories JSON from the gist this time which is awesome. Animals, elephant, animals, elephant was first. Let's go to our gist and tweak a category just to make sure that it's working. So click edit.

[08:03] We'll just type animals test, take public gist, then refresh. Refresh again. Is this caching? Why didn't that change? Check our network, refresh, categories.

[08:17] Oh sometimes the raw takes a bit longer. So animals test is in the raw, categories, response. Oh it must be caching since that's animals. Before I check that Let me actually ask it. I made changes to my categories.json in the gist, but when I refresh the site changes didn't show up.

[08:40] Can you explain why? And I want to see if it comes up with maybe it's caching or doing something else. I'm curious why it thinks that's wrong. Well, let's try it. I don't see why that's any different than what it was before.

[08:54] But let's refresh it. It has animals test now. Let's swap over here, edit, animals test again, update, refresh, refresh, refresh. Maybe it's a hard refresh. Yeah there's definitely some caching going on.

[09:10] Let's check. I had to hard reload the browser to get it to retrieve the new content. Is there some sort of caching enabled here or some workaround to disable the caching. Alright so cache busting parameters, let's accept all. This is pretty standard here, disable the caching.

[09:25] And this should be fine since it should only be like one or two people with this open. We're not really worried about caching on this. So let's swap back, make an edit, let's say animals, go back, refresh once, and we're back to animals. All right I'm gonna stop there, I think this looks pretty great as far as what I needed. The last thing I want to try is what it would do if I ask it to deploy this on GitHub Pages.

[09:50] Please walk me through deploying this to GitHub Pages. I do have the GitHub CLI installed so you can use the gh commands to make this happen. All right Let's see what happens now. Looks good to me except it looks like I'm not currently logged in. Let's try and log in.

[10:06] I do need to go here in my browser. Let's copy this, paste it here, continue, authorize, use my phone, And let's see that automatically continued. You need to initialize this project. This should create the repo. I am concerned that there's no gitignore here.

[10:25] There's nothing sensitive, but I'm still gonna say I would like to add a gitignore here in case I start adding node modules or other packages. Can you please help me add that first before we start committing anything. So let's interrupt with that. All right we now have a git ignore. Looks pretty solid.

[10:43] Now we can accept git add. It's a solid commit message, better than what I would have typed. Then let's see if it pushes. Let's push to main. Oh, it looks like my auth isn't set up for this.

[10:54] Let's try gh-repo-sync. I've never run that command before. This is brand new territory for me, I've never used a CLI for running git commands. I guess we'll try it again. And now it can even create github pages.

[11:07] Okay so I wish it would make this link clickable. I'm going to jump over to Chrome, go here, scroll down to pages, and I'm going to make sure and follow its settings. Source, select main branch, so none, main, we'll hit save. It says it should be available here now. So let's go over here, open a new tab, go to this URL, and do I need to save any more changes?

[11:32] Let's just check that the code is in there and it looks like it's fine. Maybe it just hadn't deployed yet. Oh I guess that was it, just hadn't deployed yet. So let's go to movies, next, next, next, previous, previous, categories, And looks great. All in all I never looked at the JavaScript, never looked at the CSS, it's not even using the server.

[11:52] I could probably ask it to delete stray files but I'm not going to worry about that for now. And the cool thing about this is this is definitely a project I've wanted to make for a while but as a more experienced developer it was both kind of too easy and just took a little bit too much time in that weird space where I knew how to do everything myself but it felt more like a chore, more like work to get it done, and this was actually kind of fun and it did go way way faster than I would have done. So two thumbs up to Windsurf for my initial impressions.