How to actually force Claude Code to use the right CLI (don't use CLAUDE.md)
203 segments
One of the most common questions I get
about agents and about claw code is how
do I force it to use the right CLI
command? How do I force it to adopt my
workflow instead of the workflow that it
knows best? For instance, how do I get
it to use uh PNPM instead of npm? How do
I get it to call this wrapper script
that we wrote instead of calling the
thing directly with npx? How do I
prevent it from using certain commands
and only allow it to use other commands?
If you're interested in these kind of
questions, this is the stuff that I
answer on my newsletter. And I'm working
on a Claude code course right now for
real engineers, not vibe coders. So, if
you dig that stuff, the link is down
below. The first thing that you probably
think about when you think about
steering Claude in one direction, but
not another, is to put information in a
clawed MD file. In other words, to
proactively tell it to use PNPM, not
npm. Now, this will be pretty effective
most of the time, especially if like
this you have a claw.md file that is
nearly empty apart from that one
instruction. However, in various places,
including in the previous video I just
posted, I've advocated almost always
deleting your claw.md because if you
think about it, this instruction here is
only relevant for certain tasks. And
putting it in claw.md makes it global
for every action that you're going to do
in the repo. LLMs have an instruction
budget that you can really only put
about 500 instructions in before it
starts getting less and less powerful
and more and more confused. And we want
our LLM thinking about the complicated
plans and the implementation that it's
going to put together, not having
irrelevant instructions about using npm
or PNPM. And the final thing that makes
me uncomfortable about this is the fact
that it's not a deterministic way of
preventing a command. For instance, we
may want to disallow it from running
destructive commands. for instance, we
never want it to get pushed. These kind
of negative instructions to the LLM are
really bad, I think, because they burn
instruction budget in something that
we're not actually using the instruction
budget to prevent deterministically. By
adding this, we're reducing our chances
of running git push or reducing our
chances of running npm, but we're not
preventing it. So, instead, I'm going to
show you an approach that prevents it
deterministically and guides the LLM
towards the correct solution. The way to
do this is via clawed code hooks. Hooks
allow you to run deterministic code at
certain points during claw code's
execution cycle. When one of these
events fire, all matching hooks run in
parallel. So for instance, you can run a
hook when the session starts. You can
run a hook when a permission dialogue
appears to automatically approve things.
The one that we're interested in is
pre-tool use before a tool call executes
can block it. Our plan here is to use
this pre-tool use hook to before it
calls uh npm to use PNPM instead. And
the cool thing about this is that Claude
code already knows how to do this. And
I've actually prepared a prompt inside
this file to take the claw.md, turn it
into deterministic hooks, and then put
those hooks into your project. Here's
what it looks like. Take the
instructions in your claw.md file, turn
them into deterministic claude code
hooks in this project directory. Not all
the instructions will be deterministic.
Only do the ones you can, such as
instruction to use one CLI command over
another or disallowing certain CLI
commands. use separate bash scripts for
running the hooks. In other words, this
is its own.sh file and it gives some
syntax here for how to construct that.
This is directly lifted from the claude
code docs. And then finally below here,
first confirm with the user which hooks
will be created. Second, implement the
hooks. Third, provide the user with
instructions on how to test the newly
created hooks. I'll include this in an
article which is linked below for you.
So, I'm going to copy and paste this.
I'm going to go into a fresh clawed code
session here. I'm going to zoom up the
terminal a bit. I'm going to paste it in
and see what happens. All right, it's
given me two options here. It says there
are two rules that can be enforced
deterministically. Block npm commands or
block git push. Now, I've actually
already got some git push blockers in my
global setup. So, I'm just going to say,
yeah, do the npm one only. So, that
sounds good. Let's run this and see what
happens. So, it's now given us something
to review. It's given us a nice version
of the bash command that we saw earlier,
except it just checks if it's npm.
Crucially, it's checking if the command
starts with npm as a command. It echoes
use PNPM, not npm. And then it exits
with an exit code of two. So that is
looking good to me. Let's accept that.
It's then going to make it ex uh
executable by running chimod plus x. So
I'm happy with that. It's then created
the configuration inside settings.json
here where we've got now hooks which is
um you know a property on the settings
pre-tool use which is the one we saw
earlier. It's mashing matching any bash
tools here. And then when it matches any
bash tool, it runs this command block
npm.sh. So that looks good to me. We're
in a good spot. And it's now appearing
to verify that the hook works in line.
I'm just going to try and run this to
see what happens. And you can see here
just up there, it said blocked use PNPM,
not npm. So we're definitely getting
somewhere. And finally, it's given us
some instructions here to test it. to
restart claw code in this project. Try
asking it to run something like npm
install fu. All right, the first thing
I'm going to do is actually remove the
instruction from claw.md here. And then
we're going to pull open a fresh clawed
code instance and we're going to say npm
install let's say react query. Okay,
let's give it something kind of juicy.
And we can see that the pre-tool use
here it said bash hook error blocked.
Use pnpm not npm. And now it's running
pnpm install tenstack react query
instead. So that's it. We have prevented
one command and we've automatically
steered it to use another command. And
crucially, we've managed to kill an
instruction inside our global claw.md
file. This is what I love so much about
this approach. You get to take
instructions out of your instruction
budget and enforce them
deterministically. This means that the
instructions that we have in claude.md,
they are available just in time. They
get to hover in the background until
Claude actually progressively kind of
discovers them. And this idea of these
rules just being enforced just in time.
You can take this and apply it to lots
of different things. For instance, I've
been turning my style rules, like I
really hate positional parameters in
functions and turning them into ESLint
rules so that I can lint Claude into the
right thing without needing to warn it
or instruct it. So creating these
feedback loops for Claude is so so
powerful. Now, if you dig this, then
this and all of my ideas are going to be
in my newsletter so you never miss a
trick. and the link for that is below if
you want to click it and sign up. But
thank you so much for watching. I've
been having a blast making these videos
and discovering lots of new ideas about
Claude. What else do you think you can
do with hooks? What else do you want to
see me cover with Claude code? And now,
of course, Claude is not the be all and
end all, right? Like I'm pretty keen to
try out other coding agents, too. And
the hooks idea is not exclusive to
Claude, too. So, you can take this
knowledge and probably take it to Codeex
or whatever you're using. But anyway,
that's enough rambling. Uh, thanks for
watching and I will see you in the next
Ask follow-up questions or revisit key timestamps.
The video addresses a common challenge in steering Claude agents to use specific CLI commands or prevent others. Initially, users often put instructions in `claude.md` files, but this approach is problematic because it makes instructions global, consumes the LLM's limited instruction budget, and doesn't offer deterministic control. The presenter advocates for using Claude code hooks, specifically the `pre-tool-use` hook, which allows for running deterministic code to block or modify tool calls. A demonstration shows how to prompt Claude to convert `claude.md` instructions into bash scripts for hooks and configure `settings.json`, effectively blocking `npm` commands and automatically substituting `pnpm`. This method frees up instruction budget, making Claude more efficient and allowing rules to be enforced just in time.
Videos recently processed by our community