Now, with all those latest changes implemented,
have one problem in this project here though.
Actually, a problem which existed right from the start.
The formatting is not what I wanna have here, and obviously, that will
differ. That might be exactly the formatting you
want single quotes instead of double quotes.
And by default, right now, at the point of time where I'm recording
Code gives me double quotes in my code.
Not a huge issue, but not the code style I want.
If I were writing my code manually, I might have a
formatter installed that automatically formats the code files
them or when I press the appropriate shortcut.
But since I'm using Cloud Code here to write the code, that's not
happening. And that's, therefore, where another important feature comes into
play: hooks. Let's say we have a formatter, in
my case here, OxFormat, which is a relatively new formatter for
the JavaScript ecosystem, and I add a script to
package.json format, where I just
run that package like this. With that saved,
I can also add a configuration file.
I can create one with this command here, using this formatting
package. And in there, I can add my
formatting rules, like for example, that I want single
quotes also in JSX files. Let's say
that's the formatting schema I wanna use.
Now, with that package installed, I can run the format
command, the format script, which I just added to package
JSON, this one here. And that will format
all my files, and for example, use single quotes now
here. Okay, so I can do that. But right now, I would have to
manually do that after every change that's implemented by
Cloud Code, which might not be what I want.
And that's where this hooks feature offered by Cloud Code can
come in handy. The idea behind Cloud Code hooks
react to certain events emitted by Cloud Code,
for example, that it edited a file, and you can then run any code
of your choice in reaction to that change.
And you can add hooks in the local settings
JSON file that's not checked into version control, into the local one
that is, or also in the global one on your system
across projects. Here, I'll use the local one that
control. There, in that JSON object,
you can add a hooks node, and then add as many hooks as
you want. And you do add a new hook by first
to which you wanna react. And attached, you'll find a link to the official
documentation that lists all hook events to which you can react.
You, for example, got pre-tool-use, which is a hook that allows
you to execute code whenever Cloud Code is
about to use a tool, and the tool is something like
doing web search or editing a file or reading of
files. Whenever Cloud Code does anything about
execute some code. There also are a lot of
other events, of course. For example, also,
post-tool-use. And that sounds interesting for us
here, because that is a hook that runs after a tool has been called,
and since, for example, writing to a file or editing a file is
a tool call, that's what we need to format a file after
it has been edited. So, it's post-tool-use and
you must write it exactly as specified in the
documentation. And then this takes an array because you
register multiple hooks, multiple code snippets that should
execute for this event. In that array, you have
one object per code snippet you wanna
execute. And in that code snippet, you then have a
matcher, which allows you to specify which tool was
used for this hook event. And for different hook events, the
matcher expects different things.
The official documentation is the way to go, of course, to learn how
to react to different hook input and set up your matcher for different
hooks. In case of the post-tool-use hook, we
simply specify the kind of tools we wanna react to.
So, after the use of which tools do we want to execute some
In my case, that's edit or write, and you would write it like
this. So, use the pipe symbol here to basically
say that you have multiple matching options.
So, whenever the edit or write tool was used, I want
to do something. So, then you can specify your hooks.
Again, this is an array because you could have
whenever the edit or write tools were used, and you have one
object per thing that should then happen.
And in here, you then have the type.
Type is command, agent, or prompt, and the two you'll typically use are
command or prompt. If you were to choose
prompt, you would have to add a prompt thereafter,
simply be injected into the conversation.
So, if you know that after a certain event,
prompt into the context, into the conversation, you could use such
a prompt hook for that. But we're looking for a command here,
allows us to execute a command
whenever this hook was called or when this event
happened. And the command you specify here is a bash
command, so a command you could execute in your
And behind the scenes, a new terminal session will be opened
command will be executed. So, what I wanna make sure is that in that
session, we navigate with the CD command into this
and I'll get back to that. And then I want to run the
format command here. I'll also
forward any errors into this null channel here, so to
say, and by addingTrue like
this, I ensure that it will always return a
that's not horrible in case of formatting, but I don't want to
break Claude Code or have it stop its work just because formatting
failed. Now, let's get back to the CD part though.
What do we put in here? Thankfully, Claude Code
gives you a special variable you can use here to give you a
dynamic way of resolving the project directory it's
currently working in. And that is CLAUDE
PROJECT DIR, which must be wrapped in
quotes, which we must escape like this.
And this is simply a value you get by Claude Code.
It will be passed into this hook automatically, and that gives us a way of
navigating into the project folder and running this format command
there. And that will now automatically happen in
whenever Claude Code finished working on a file.
And I wanna test this right away. I'll end my current Claude Code session
start a new one to make sure hooks are loaded.
If you enter slash hooks, you can also view hooks
and also set them up. You see, here's the hook I
did set up, but you could also now add hooks through
that mode or through that, uh, tool here.
I just find editing it in an adjacent file a bit easier, but you could use this
interactive approach here too. And therefore, now with the hooks loaded,
we can work on the next feature and check if formatting does happen.
And the next feature I wanna work on is the public sharing feature.
The idea here simply is that we, as the owner of a note, can turn
on public sharing. For a note, this should generate a unique link
which other users can follow. If they follow it, and that includes users
who did not sign in yet, they should be able to see the note,
should not be able to edit or delete it.
And if we turn off sharing, the link should not lead anywhere
anymore. As always, I'll start in plan mode.
And as the agent is working on the code here, if I inspect those public
sharing pages, for example, on which it worked, I can see that in there I
got those single quotes. So the formatting is applied,
applied because we have this post tool use hook
that runs the format script. Now, I can see that now
after creating a note, I indeed have this public sharing option.
If I turn this on, I got a link. If I copy that link
and I open that in an anonymous session of my browser, I
can view that note without editing or deleting it because here, I'm not
authenticated. If I turn sharing off
and I reload this page, now this gives me a 404
error, which is what should happen since sharing
disabled. So that is working.
And most importantly, that is how you can use hooks, for
example, to apply some formatting after every file
creation.