Get startedGet started for free

Video: Useful hooks

1. Video: Useful hooks

In this video, I'd like to show you some really useful hooks that you might want to use on your own projects. These hooks are intended to address some common weak points in Claude Code. To help you understand how the first one works, let me give you a quick demonstration of a problem that Claude Code sometimes runs into, especially on larger projects. So inside the src directory, I'm going to find schema.ts. Inside of here, there's just one single function called createSchema. This function is called from the main.ts file, specifically right here. Now I'm going to go back to the schema.ts file, and I'm going to update the function definition. I'm going to say that if you ever want to call this function, you must also pass in a verbose argument that must be of type boolean. Now, as soon as I add in this change, if I go back over to the main.ts file, I'm going to get a type error because I just updated the definition of this function, but I have not actually added in a value for verbose. So the error right here says specifically argument for verbose was not provided. Now I'm going to undo that change very quickly. I'm going to close the main.ts file. I'm then going to open up Claude Code and ask it to make the exact same change. Now, if I run this, Claude Code is going to have absolutely no issue making this edit whatsoever, but it's going to update this file. And then unfortunately, after making that change, so there's the new verbose true right there. Unfortunately, Claude won't go around the project and try to find where that function is actually called and try to update any of the different call sites. So if I now open up main.ts, we'll see that we do in fact have an error over here and Claude didn't really catch this, unfortunately. So the first hook that I want to show you will fix this solution super easily. In case you're not familiar with TypeScript, if you're not, that's totally fine. If I close out of Claude Code and run the command tsc dash dash no emit, it's going to run a type check on my entire project. And in this type check, we can see that the error is very evident right here. So it's complaining about our call to create schema from that main.ts file. So my idea for a hook is really simple. I think that any time that we edit a TypeScript file, we should run the TypeScript type checker and see if there are any distinct errors. If there are, we should attempt to feed these errors back into Claude immediately inside of a post tool use hook. And hopefully this will give Claude a signal and tell it that there is a type error that it just introduced that it probably needs to go and fix somewhere else inside of our project. Now, I already put this hook together for us, fortunately, just to save us a little bit of time inside the hooks tsc.js file. So inside this file, I've got a bunch of logic put together to run TypeScript type checker, take any errors that it found and pass them back into Claude. At present, I disabled this hook just so I can give you that demonstration you just saw. So I disabled it by adding the process exit zero right there. I'm going to delete that. And now this hook should be working a okay. So if I now go back to the schema.ts file, remove that verbose flag. Restart Claude code and ask it to make the same change once again. It will make the change and then hopefully this time it will immediately gets that feedback from the TypeScript type checker saying, Hey, you've got an error somewhere else in the project that you just introduced and hopefully Claude will go and fix it. So we can see right here, there's the edit that was made. We got some edit operation feedback from the hook that we put together. So it found an issue inside of one of our different files. And Claude is now saying, okay, I understand. I introduced an error. I need to fix the call to create schema inside of main.ts. And then the next update it makes is going to attempt to go into that file and update that function call to add in that missing argument. So this is a hook that you might want to try implementing on your own personal projects. Now, even though this hook was implemented specifically for TypeScript, it still works for any other kind of typed language where you can run a type checker very easily. Even if you're using an untyped language, you might even implement the same idea of functionality using tests instead of running a type checker. So every time an edit is made, you could run your tests to make sure that the edit is okay. Now, the next hook that I would like to show you is a little bit more challenging to explain. But once you get the idea behind it, I think that you will definitely find this next one really helpful, particularly in larger projects. To help you understand this other hook, I want to give you a little bit of background on this project. Inside of the src query directory, there are many different files. Each of these different files contains many different SQL queries written inside of different functions. Inside of the order queries dot ts file in particular, I want to point out that there is a function inside of here called get pending orders. This query goes through a database that contains some e-commerce related data. And in theory, it's going to find all the different orders that have been created that are in a pending state. So just keep that function in mind for a moment. OK, so I'm going to show you a couple of diagrams really quickly to help you understand a common problem that starts to arise inside of larger projects. So in this diagram, I've got my list of different query files on the left hand side. And as we saw, each of those different query files contains many different queries inside of that order queries file in particular is the get pending orders function. So we've already got a query put together that will attempt to find some different pending orders. Now, if I go to Claude and ask it to update the main dot ts file to print out all the different orders that have been in a pending state for longer than three days in a perfect world, Claude would find the order queries dot ts file. It would find that existing query and it would make use of it as opposed to writing out a brand new query. So that's what we want. And we'll see that if we make use of Claude right now and ask it to do exactly that, we're going to get exactly the result we want. So I'm going to ask Claude in the main dot ts file, print out orders that have been pending. Now, to Claude's credit, it is going to take a look at the different query files that exist. It's going to find the order queries file and then inside there, it's going to recognize that there is already a query called get pending orders and it's going to attempt to use that function as opposed to creating a new query. We didn't want a new query. We wanted Claude to use the existing function. So when we gave Claude a very focused and directed task, it was able to understand that, yeah, it probably shouldn't write a new query. It should at least take a look at some of the ones that already exist. And that was definitely good. Now I'm going to give Claude a little bit of a curve ball. I'm going to purposefully make this task a little bit more difficult. First, I'm going to run slash clear to clear out all the context that we've gained. Then I'd like you to take a look at the task dot md file. Inside this file, I put together a prompt that is still going to ask Claude to find orders that have been pending for a while. But I've also wrapped it up in some larger project. I'm asking Claude to write out a slack integration that's going to message a specific channel once a day with all the different orders that have been pending for too long. So in this scenario, we still want to find orders have been pending for too long. But now I've wrapped it inside this larger task. And if I take this task and then feed it into Claude again after doing that slash clear operation, we're going to see that this time around. Unfortunately, it's not going to stay quite as focused and it's going to end up trying to write out a brand new get pending orders query, which is again not what we want, because that would be duplicating code throughout our project. If I let this run for a bit, I will eventually see that yes, it does in fact make a brand new query called get orders pending too long. So this is an example of where Claude kind of lost focus and decided to write a brand new query as opposed to reusing an existing one. Again, we've got some duplicate code here, which is probably not what we want. In addition, it didn't only create the new query. It also created a brand new file, which is also probably something we don't want. We probably want this order related query to be added to the order queries file. So now that we understand the issue here, let me show you how we could fix this potentially by making use of a hook. All right. So whenever Claude attempts to write, edit or use the multi edit tool to modify something inside the queries directory specifically, I'm going to run the following hook. First inside this hook, I'm going to launch a brand new separate copy of Claude code. I'm going to ask this new copy to take a look at the change that was just made and take a look at some of the existing code inside the queries directory and see if a similar query is already inside there. Then if there is an existing query, then I'm going to take that feedback and send it back to the original copy of Claude. And I'm going to ask Claude to maybe decide to fix the situation. So remove the added query and make use of the one that already exists. So this is going to allow us to make sure that the queries folder generally stays clean and doesn't have a bunch of duplicate code inside of it. So let me show you how this would work in action. First, I'm going to flip back over here. I'm going to delete the brand new order alerts queries dot t s file that was made and the slack dot t s file that was made as well. Then I'm going to find inside the hooks directory the query hook file. So I already put this hook together for us. Right now it is currently disabled because I got a process dot exit at the very top. So let's walk through this hook really quickly. First, I'm going to tell this thing that it's only going to review changes to the src queries directory. Then a little bit lower, I'm going to check and see if the change that was just made was made to the queries directory. After that, I've then got a long prompt here that is asking Claude to do a review on the change that was just made. And then after that is where I'm launching Claude code programmatically, specifically these lines right here. This is making use of the Claude code TypeScript SDK. I can give you a lot more information on it in just a little bit. For right now, just understand that this right here is essentially the same as us making use of Claude code at the terminal. Once Claude code runs and I get a response back out of it, I check and see if Claude decides that, yeah, the changes look OK, or maybe we've got a duplicate query. And if we do, then we're going to exit early with an exit code of two, which is going to give this feedback back to Claude and hopefully tell it that needs to make a change. So now that I've got this additional hook put together and enabled by removing that process exit zero at the top, I'm going to again restart Claude code. And then run the same query again. And hopefully this time it might initially put in that duplicate query. But then our hook right here is going to run and hopefully tell it, hey, we don't want that duplicate code. You should make use of some already existing query to implement this functionality. Now Claude code is once again going to attempt to create a brand new, completely separate query file, not making use of the old query that already existed. When it tries to create that file, however, our hook is going to run. It's going to launch that separate copy of Claude code, which is going to do some research and find that there is in fact an existing query that can be reused. It's going to provide some advice and say, hey, you could probably go and update this other existing query to suit your purposes perfectly. And we'll see some feedback from Claude, our primary instance that we are interacting with saying, ah, yes, there is this existing query. Let's just modify that existing query rather than attempting to write out a brand new one. Now, the downside to this hook is that it's going to take some additional time and expense to run every single time that I want to edit something inside the queries directory. But the upside is that I'm going to end up with a lot less duplicate code inside my queries directory. So it really comes down to a set of tradeoffs for you deciding whether or not you want to implement something like this in your own project. If you do, I would at least recommend doing what I showed you inside of the query hook. So this one right here and only watching maybe a handful of directories like really important folders inside your project just to minimize the amount of extra work that is being done.

2. Let's practice!

Create Your Free Account

or

By continuing, you accept our Terms of Use, our Privacy Policy and that your data is stored in the USA.