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. A lot of my friends told me they just don’t find managing Claude Code pleasant. I don’t find managing Claude Code pleasant.
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.
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.
I hope this framing can help you find some joy in it too.
I’m gonna keep a list of workflows and behavior patterns I’ve found useful for my work.
Invocations
- 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 14inch macbook. Sounds silly, but I’m internet-rich screen-space-constrained.
- 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.
- Game developers do it all the time. You build a level editor to build the game.
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
ast-grep --pattern 'var code = $PATTERN' --rewrite 'let code = new $PATTERN' --lang tsExamples:
Rewrite code in null coalescing operator
ast-grep -p '$A && $A()' -l ts -r '$A?.()'
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
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 useuseCallback
. Never tightly coupleuseState
withuseEffect
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}/>);};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 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.
The beginning wisdom is the statement ‘I don’t know’. The person who cannot make that statement is one who will never learn anything.”
—Thrall (or actually Keith R.A. DeCandido) in Cycle of Hatred
