# Shaman Update

You might have noticed the game got patched and there's a new class.

If you've been playing a Wizard like me for your entire adult life, you might
find this a bit spooky.

We've been deciphering and crafting spells, learning math and physics, diving
deep into insurmountable complexity.

We've made some money on it. But we also had fun.

The game changed, and a lot of my friends tell me they just don't find managing
Claude Code pleasant. _I_ don't find managing Claude Code pleasant.

<aside>(this was written before Opus 4.5)</aside>

I'm trying to, though. I'm changing my build into Wizard 11, Shaman 1.

I hope I can find joy in wielding multiple genies and demons, (AI agents)
forcing them to do my bidding, defending from their attempts to snitch on me or
worse.

There is some technical complexity to it that might be fun. The idea sounds nice
if you paint it with some fantasy framing or if you look at it through cyberpunk
lens.

<aside>
  TBF we already live in cyberpunk. We have drone warfare, billionaires in
  governments. We're only missing bodymodding.
</aside>

It also helps to notice just _how bad_ the vibe-coded stuff from people who
don't know what they're doing is. My comp sci degree, my decade of experience:
It's not gonna go to waste even if AI writes majority of my code.

<aside>
  Remember Tea app leak? Half the people I hang out with would've told the guy
  to double check Firebase. It's __always__ Firebase.
</aside>

I hope this framing can help you find some joy in it too.

## Invocations

I'm keeping a list of workflows and behavior patterns I've found useful for my
work. A spellbook of sorts. Not everything I'm using, because 1. I'm lazy,
and 2. I'm not sure enough about everything to make it public.

- **Make sure we didn't mess it up.**
  - With Lighthouse and Vercel MCPs I iterated on perf improvements for the new
    GraphQL.org website by running an audit on each new deployment. This was
    faster than doing it manually because the LLM took care of diffing and I
    could focus on the code without leaving the editor, without changing the
    browser tab on my 14-inch macbook. Sounds silly, but I'm internet-rich
    screen-space-constrained.
- **Diff before and after screenshots.**
  - This is as blackbox as you can get. Being able to leave the AI spinning for
    an hour or two trying match a screenshot makes big migrations so much
    easier.
- **Build the thing to build the thing.**
  - Game developers do it all the time. You build a level editor to build the
    game.
    - example: https://x.com/geoffreylitt/status/1960344454348292374
    - I did something similar to Geoffrey's AI HUD but with Ink for a tricky
      migration (lots of global scope, file moves changed paths). Telling the
      genie to JUST DO IT (tm) ended terribly so I needed a workbench with
      before/after preview.

### Favorite rules

It's kinda funny how we all carry bits of markdown with sacred knowledge for the
spirits in the machine. I don't want to be finicky, but some additional guidance
does help them a lot.

Below, you can find excerpts from my spellbook, some of the rules I'm using in
all agent CLIs and editors.

#### ast-grep

> Use `ast-grep` to search for patterns in the codebase and simple refactorings.
>
> Think of it as your old-friend grep, but matching AST nodes instead of text.
> You can write patterns as if you are writing ordinary code. It will match all
> code that has the same syntactical structure. You can use $ sign + upper case
> letters as a wildcard, e.g. $MATCH, to match any single AST node. Think of >
> it as regular expression dot ., except it is not textual.
>
> CLI usage:
>
> ast-grep has following form.
>
> ```
> ast-grep --pattern 'var code = $PATTERN' --rewrite 'let code = new $PATTERN' --lang ts
> ```
>
> Examples:
>
> Rewrite code in null coalescing operator
>
> ```
> ast-grep -p '$A && $A()' -l ts -r '$A?.()'
> ```
>
> Rewrite Zodios
>
> ```
> ast-grep -p 'new Zodios($URL,  $CONF as const,)' -l ts -r 'new Zodios($URL, $CONF)' -i
> ```

#### no-bullshit

Don't list benefits of the work you did. You don't need to advertise yourself.

#### typescript

Never annotate return types of functions, let TypeScript infer them. Never
annotate callback function parameters if TypeScript can infer them.

#### .tsx

> Never use `React.FC`. Never use `useCallback`. Never tightly couple `useState`
> with `useEffect` as this may lead to a infinite loop. Derive values > instead.
>
> ALWAYS accept root element props and spread them like
>
> ```tsx
> interface ButtonProps extends React.HTMLAttributes<HTMLButtonElement> {
>   variant?: "primary" | "secondary";
> }
> const Button = ({ variant, ...rest }: ButtonProps) => {
>   return (
>     <button
>       className={cn(variant === "primary" && "bg-primary", rest.className)}
>       {...rest}
>     />
>   );
> };
> ```

## Disclaimer

I have almost no idea how to get the most out of these new tools. It's AWESOME,
isn't it? I&nbsp;work the best and I have the most fun when diving into deep
water.

If you have some _alpha_ please share it somewhere and send me a link. Like any
new game update, this new class is super buggy and unpolished, but I think we
can all have a lot of fun and _maybe_ become more productive at the end of it.

<figure>

> The beginning wisdom is the statement 'I don't know'. The person who cannot
> make that statement is one who will never learn anything.”

<figcaption>

<div class="p-1" />

—Thrall (or actually Keith R.A. DeCandido) in
[Cycle of Hatred](https://books.google.pl/books/about/World_of_Warcraft_Cycle_of_Hatred.html?id=igIcWvxbobIC&source=kp_book_description&redir_esc=y)

</figcaption>
</figure>

<img
  width={200}
  className="mx-auto"
  src="https://blz-contentstack-images.akamaized.net/v3/assets/bltc965041283bac56c/bltc318338daf7245b0/5e44402fcc8de70b69efa72d/Alt-Heroes_Shaman_Thrall.png?raw=1"
  alt="a picture of Shaman Thrall from Hearthstone/Warcraft"
/>
