---
url: "https://youtu.be/5N-okeDdIuI"
title: "L8 Principal's Agentic Dev Environment From Scratch"
source_kind: youtube
author: Kun Chen
captured: "2026-09-05T02:20:38+00:00"
comment_tree: false
topics: [ai-tools]
summary: A developer walks through setting up a reproducible agentic dev environment from scratch on macOS using Nix and Nix Darwin.
status: ok
---

# L8 Principal's Agentic Dev Environment From Scratch

Channel: Kun Chen

## Transcript

[0s] What's up everyone? I'm still in shock that 
my last video about agentic engineering got  
[5s] hundreds of thousands of views. I'm really happy 
to see many of you are leaning into building with  
[11s] agents and I plan to continue sharing what I found 
that's truly useful for getting real work done.  
[18s] Today, by popular demand, I'm going to be sharing 
my entire development environment by setting up  
[24s] all my config files from scratch, step by step, 
so we can all go from a freshly installed Mac to  
[31s] my complete agentic engineering setup that's 
ready to go. Let's get started. All right,  
[37s] here we are at our starting point, a freshly 
installed Mac OS on my Mac Mini. I have only  
[43s] done some of the most basic things like installing 
Chrome, Git, and set up my SSH key for GitHub. I  
[50s] also downloaded this custom wallpaper here just so 
the video looks a little bit more pleasant. I will  
[56s] drop a link in the description for where I got 
this. And that's all there is right now. We will  
[61s] set up everything else together from this point 
on. Now, the very first problem I want to solve is  
[67s] the reproducibility of my configuration. It means 
once I have things all set up on this machine,  
[74s] can I easily apply it on another machine and get 
the exact same results? Or in the less likely  
[82s] but still very possible scenario, if my AI agent 
did something stupid and completely destroyed my  
[88s] system, can I recover it instantly and get 
everything back exactly the way they were?  
[95s] My solution to this is something called Nyx. 
If you haven't heard of Nyx before, Nyx is a  
[102s] declarative and reproducible configuration 
system primarily designed for Nyx OS,  
[108s] which is an operating system based on Linux. But 
you don't have to use Linux to use Nyx. People  
[114s] have made Nyx portable. And here's an installer 
that works on Mac as well called determinate  
[121s] Nyx. And this is what we will install now by 
following their install command here. So this  
[127s] is what we will copy. We'll just run this command 
in our terminal and finish the installation here.
[136s] We will choose yes.
[141s] Now it says the installation is done. So let's 
follow its instruction and let's copy this command  
[148s] and we will run it. This will basically refresh 
our environment. All right. Now Nyx is properly  
[155s] set up in our environment. Let's start writing our 
actual file config. I'll go create a repo here uh  
[162s] in my GitHub cont. And I'll make a new repo called 
files. And I will initialize git here. This will  
[173s] be the repo I publish on GitHub after this video. 
And I'm going to create a symbolic link at a fixed  
[179s] location here like this. Uh I'll be targeting 
this current directory. and I'll put a symbolic  
[186s] link at this location. I do this so that all my 
scripts later can reference this using a stable  
[192s] path. All right. Now, we have an empty files repo 
and Nyx already set up. The first config we write  
[199s] here is going to be something called Nyx Darwin. 
Nyx Darwin is how I configure my Mac OS settings  
[205s] using Nyx. You will see how it works in a bit, 
but for now, I'm just going to be copying their  
[211s] boilerplate config content here. And then let's 
go create a Nyx uh file called flake.nix. We don't  
[222s] have neo vim just yet. Uh so I'm just going to use 
the vanilla vim that comes with the Mac OS install  
[227s] for now. It's not as good, but uh should be enough 
to carry us through uh the initial phase until we  
[234s] have Neo Vim set up. I'm pasting the boiler place 
in as is. This file uh basically just tells Nyx  
[242s] where to get the packages, where to get uh Nick 
Darwin as well. We don't really need to worry too  
[248s] much about this file. Um the only thing we need to 
change is that I'm not John. So I'm going to call  
[255s] this uh files and there's another John here. 
Uh let's just name this whole thing Mac. Um,  
[262s] and something I do want to change is that uh 
I want to pin the version from the current  
[268s] uh unstable version to a stable version uh to 
a at least a pinned uh version number. So I'm  
[275s] going to copy this uh and I'm going to replace 
that and uh I'll do the same for this as well. Uh
[289s] okay. So this will basically allow us to 
have a um stable version that uh we will  
[295s] be using uh so we don't get surprises and then 
we are going to create this configuration.nix  
[301s] file that's being referenced here. Uh so what 
I'll do is I'll do configuration.nix to save  
[307s] us some time for the rest of this video. I'm 
not going to literally type in every character  
[312s] one by one. That will be too slow. I'm going 
to paste the snippets in uh and talk through  
[317s] how they work. Here's the file content that we 
actually need for now. It's very simple. Um,  
[322s] and we set nyx.enable equals to false because 
we are already letting determinate manage the  
[329s] next installation for us. We don't need to 
repeat a nyx installation here. Allow unfree  
[334s] basically allows us to install programs 
from nyx that are not completely free. Um,  
[340s] and host platform uh refers to the architecture 
of the current system. My Mac here is on Apple  
[346s] silicon. So I set this value. If you 
are running a Mac that uses Intel CPU,  
[351s] then you will set the other value. Primary user 
is basically just my username. And state version  
[357s] here is a version number for the default state 
values. Generally, we just set it at six and  
[362s] just never touch it again. That's it. Our initial 
Nick Darwin configuration. The way to activate it  
[368s] is by uh first tracking everything under git and 
then we will be running this command. This will  
[375s] basically install all the missing dependencies 
and apply the configuration onto the current  
[380s] system. The first time you do this is going 
to take some time. So just be patient and wait  
[385s] for it to be done. This process of applying our 
next configuration onto the system will need to  
[390s] be repeated every time we change our next config. 
So I'm going to create a helper script here um to  
[397s] make that easier. We will call this rebuild.sh. 
And basically it will just repeat what we did  
[405s] earlier. We are going to make this uh executable 
as well. Um rebuild and moving forward every time  
[414s] we want to apply a updated next config we can just 
run it like this and it will do the same thing.
[426s] All right. Although we applied our next config, 
nothing actually changed about our system because  
[432s] we haven't set anything meaningful yet. Time to 
do some real settings. Now, let's get back to our  
[438s] configuration.nix file and we will be pasting this 
snippet in. This will set a lot of my preferences  
[445s] that I would otherwise have to click through 
in the Mac settings. So there's dark theme,  
[451s] there is fast key repeat, uh there's short delay 
before repeat, there's autohiding uh the menu bar,  
[458s] there's uh always showing the file extensions, 
there's autohiding the dock and uh using list view  
[465s] for finder and uh have a clean desktop that shows 
uh nothing on it except the wallpaper and making  
[473s] uh tapping on the trackpad uh click it. You can 
pretty much set anything you want about your Mac  
[478s] system through this configuration and you can 
find all the settings in the next Darwin repo.  
[483s] Now let's uh rebuild and see that apply. You 
can see our doc already changed the behavior  
[490s] as a result. So now the doc is hiding itself. Next 
thing is to install the apps that we need. On Mac,  
[497s] a lot of the useful apps can be installed through 
homebrew. So let's get homerew installed first.  
[504s] We could just go to the homebrew website and 
copy paste uh their install command and get  
[508s] homerew installed, but that's not going to be 
reproducible. Next time we set up a new machine,  
[515s] we would have to manually go do that again. 
To make everything reproducible, we should  
[519s] do it the next way. And the way to do it is to 
install homebrew as a Nyx package. The package  
[526s] is called Nyx Homebrew. And here's the repo. It 
has detailed instructions for how to set it up.  
[532s] We need to modify our flake.next file. Uh so 
we'll come here and uh go to flake.next. And  
[541s] the main pieces we need to add uh is this input 
um here and also add this module. Now we can get  
[553s] back to our configuration.nix file and add homerew 
configuration in. This will basically uh just get  
[562s] homebrew installed. And this cleanup uh setting 
here uh cleanup equals to zap basically says each  
[569s] time we rebuild our next configuration, it will 
remove homebrew packages that aren't listed in  
[575s] our next config. This is a useful setting because 
it's going to force us to install every homebrew  
[581s] package through our next config instead of ad 
hoc. And if everything is installed through Nyx,  
[587s] we know the whole system is reproducible. I 
also listed casks here to install. And for now,  
[594s] I just added Westerm, which is the terminal 
emulator I will be using. Other homebrew  
[599s] casks you want to install should also go 
here as well. Now, let's go run a rebuild,
[606s] which should get homerew set up for us. And we 
can verify by running brew- version. and it's  
[614s] working. We now also have Westerm installed. 
So, let's get it open. So, now it's time to  
[623s] close the default terminal and I'll be using 
western moving forward. Besides homebrew,  
[629s] another very important tool we need to use 
is called home manager. Unlike Nyx Darwin,  
[635s] which manages MacOSS level settings, home 
manager manages everything that belongs  
[640s] to our user directory aka home directory. 
Similar to homebrew, we'll first go to our  
[646s] flakemix file and we will be first adding in 
home manager as an input like this. And then  
[652s] we also need to add it as a module here. Um, and 
we need to make sure it's listed here as well.
[662s] All right. And this last line here, this is the 
key. This is basically saying for this username,  
[669s] we will use the home.nix file to manage it. And 
this reminds me that we actually need to edit the  
[676s] configuration.nix file here as well. And we need 
to make sure uh this section exist. This basically  
[684s] sets the home directory for this user correctly. 
Otherwise uh it will not work. And then we're  
[690s] going to be creating this uh home.nix file that 
we mentioned earlier. Here's the initial contents  
[696s] we'll be putting in. You'll want to update your 
username to whatever you actually use. And the  
[702s] interesting bit here is this line where we created 
a symbolic link for west term's config directory.  
[709s] This basically says we should create a symbolic 
link at the current user's home directoryconfigerm  
[717s] that points to this path in our dotfiles repo. 
This is how we store configuration in our  
[722s] dotfiles repo and have them automatically used 
by the actual programs. And because this whole  
[729s] directory is a symbolic link, if west term update 
any of its configuration at runtime, those updates  
[736s] will reflect in our doiles repo as well. So all 
the config changes will be version controlled,  
[742s] which is really useful. And remember earlier we 
created a symbolic link at this location in our  
[749s] home directory. This is how we make use of it. 
we can just always use this path to find our dot  
[755s] files regardless of where the actual git clone is. 
Now the next set of things we add to home manager  
[762s] is a list of packages that we want to install 
at user level and we can just let home manager  
[768s] install all of them for us. Interestingly even 
fonts can be installed by home manager this way.  
[775s] Here we are installing the hack nerd font which is 
my favorite monospace font for terminal encoding.  
[780s] We install it through home manager here. So we 
don't need to manually click through and download  
[785s] the font from their website. We can also set uh 
environment variables like this. So for example,  
[792s] I want my default editor to to be neoim. So here I 
have this variable set. Let's run another rebuild.  
[799s] And uh remember to add all the files uh to be 
tracked by git as well. and we will be rebuilding.
[810s] Before we go deep into configurations, I 
just want to get one last thing set up,  
[814s] which is our shell. By default, Mac already 
gave us uh the Zshell, which is pretty good,  
[820s] but it's the raw Zshell without any of the 
good stuff, and I need the good stuff. So,  
[826s] we'll come to our home manager config again, um 
home.nix, and we will be dropping this in. This  
[833s] enables auto suggestion which will give us ghost 
text autocomp completion for shell commands based  
[839s] on what is in our command history. It also enables 
syntax highlighting which is very useful. The  
[846s] init content here basically just gets pasted into 
zshells rc file directly. And this line will give  
[852s] me a key bind so that I can press ctrl f to accept 
the ghost text suggestions which I'll show you in  
[858s] a bit. And then I set a bunch of shell aliases 
here. This just makes some of the most common  
[864s] commands I type a lot shorter, which saves a few 
seconds each time and it will add up. When I die,  
[871s] it's going to feel awesome knowing that these 
aliases gave me a few more hours of life. All  
[876s] right, let's go rebuild our next config again. And 
let's now uh start a new Western session. Now you  
[884s] can see this auto suggestions already kicking in 
and uh syntax highlighting is working correctly as  
[890s] well. Another thing that will greatly improve our 
shell experience is Starship. It's a program that  
[896s] lets you customize your shell prompt, which 
is this whole prefix before my cursor here.  
[901s] The system default is just really ugly. Let's 
get back to our home manager config and add in  
[909s] uh this additional snippet. This gets home manager 
to install starship for us and puts in some basic  
[916s] customization. Here I'll just keep it simple for 
now. But Starship is very powerful and you can  
[921s] do a lot more customization on your own. If we 
rebuild now and we start yet another uh clean  
[929s] westm session, we can see we have a much cleaner 
shell prompt here. The next big upgrade that will  
[935s] greatly improve our experience is to configure 
Westerm. I introduced Western briefly in my last  
[942s] video. It's a highly performant terminal emulator 
written in Rust. And the part I like the most  
[947s] about Westerm is that it's truly cross-platform. 
Even if I get forced to use Windows from time to  
[954s] time, I can still bring Westernerm with me and 
it will give me a consistent experience there  
[959s] and it's highly customizable through Lua scripts. 
Let's create the config file for Westerm. First,  
[965s] we should make sure the directory exist. 
Uh so it should be this directory.  
[972s] Uh right. Um and let's uh then create uh the 
file and let's start with just this uh minimal  
[983s] content. Um this westterm.la file basically just 
needs to return an object that contains the config  
[990s] values. This basically just uses the default for 
everything. If we save this and we restart westm,  
[997s] we can see that nothing actually changes. But now 
we can just write whatever logic we want to modify  
[1004s] the config object. Let's start with my favorite 
color scheme rose pie moon. And if we save,  
[1012s] you can see uh western would hot reloads the 
configuration and it will immediately take effect.  
[1018s] Next, I'll change the font to be um hack nerd font 
font size 15 and save. The experience just keeps  
[1026s] getting better as we start to modify more and 
more of the configs. Let's also adjust uh the  
[1032s] window background opacity and blur and save. Let's 
also hide the tab bar when there's only one tab.  
[1040s] And let's get rid of the window frame algether. 
Let's save. Now we have a super clean frameless  
[1048s] terminal window that's basically entirely 
used to render whatever content we care about.  
[1054s] Look how beautiful this is. I really care about 
making my development experience pleasant because  
[1060s] if I enjoy the experience, I will stay focused 
more easily and end up doing better work with it.  
[1066s] Now that our terminal looks good, let's get the 
big boss Neoim. Neov is my primary code editor,  
[1074s] so it's a really important thing to set up. 
Well, its configuration starts with an init.la  
[1079s] Lua file in the config dot uh neoim uh nvm 
directory. So let's make sure the directory  
[1087s] exist. Uh and then let's uh set up the file 
as well. And now we can actually use neoim to  
[1094s] edit neoim config. So let's uh go to create the 
init.la file. Let's leave the file empty for now  
[1103s] and we will go to uh home.nix. And just like 
before, we need to create a symbolic link here
[1114s] so that uh the neoim config can come from our 
files repo. And now let's rebuild the next  
[1122s] config. And we will start neoim to make sure it 
still loads. Let's see. Yep, still loads. Okay.  
[1129s] Now in this uh init.la Lua file. I'll just ask it 
to require other files. I'll start with requiring  
[1138s] vim config. This is how I structure my new 
vim config in a modular way. So different  
[1146s] things live in different files. When you require a 
module in Lua, it will go look for the file under  
[1152s] a directory called Lua. So I'm going to create 
uh this directory um from there. And I'm going  
[1162s] to create uh the actual uh vim config.la file 
that we said we will have. Yep. This is neovim  
[1172s] complaining that the file we are requiring from 
init.la doesn't exist yet which is uh as expected.  
[1180s] I'll be pasting in uh this configuration to start 
with. These are some uh sensible defaults for a  
[1186s] typical neoim experience. Uh the map leader here 
basically configures the leader key and I have set  
[1193s] it to be space key. Uh so later we will when we 
configure key binds we will make use of this. This  
[1199s] line expands tabs into spaces. Should we go down 
this rabbit hole here? Probably not. Uh this makes  
[1206s] each indent level two spaces. This renders the 
current line number and this enables relative line  
[1213s] numbers. Actually let me stop here and uh show you 
what that is. I will restart Neoim and reload this  
[1222s] same config file. You can see now on the left side 
of the editor, we have all these line numbers. The  
[1229s] one on the same line as the cursor is the current 
line number. This is the seventh line of the file.  
[1235s] If I move my cursor to another line uh say GG 
uh which goes to the first line I can go back  
[1242s] to the previous line by typing colon 7 and I will 
arrive at the seventh line again. You can also see  
[1249s] all these relative line numbers above and below 
seven. They indicate how many lines are they away  
[1256s] from the current line. The way I use this is 
when I need to jump to another line. let's say  
[1262s] uh the line with map leader I can see it's 
five lines above the current line so I can  
[1268s] just type 5k which means repeat k five times and 
because k in vin motion is moving the cursor up  
[1278s] 5k just let me arrive at the line very easily 
that's how I actually use relative line numbers  
[1284s] uh to very quickly jump around then we have ignore 
case during search by default smart case means  
[1291s] If I typed a capital letter, then it becomes a 
case-sensitive search. Cliffboard unnamed plus  
[1298s] somehow means using the system clipboard for 
copying and pasting. Scroll off here means at  
[1304s] least reserve 16 lines between my cursor and the 
edge of the screen when I scroll. So I always have  
[1311s] some visibility what's above and below my cursor 
line. This undo file basically allows undo and  
[1318s] redo to be persistent across NeoVim sessions which 
is very useful. There are a lot more Vim options  
[1324s] available. Whenever I need to change something 
that's about the Vim behavior, I set it in this  
[1329s] file. So it's all centralized and easy to find. 
The other file that we will uh require from the  
[1337s] init.la file uh let's go back to init.la lure. 
That's going to be plugins. One of the biggest  
[1346s] advantages of Neo Vim over Vanilla Vim is its rich 
plug-in ecosystem. There are so many great plugins  
[1353s] available. And I use a plug-in manager called 
Lazy to help me install and update them. This is  
[1360s] probably the most widely adopted plug-in manager 
for Neovim right now, written by a legend named  
[1365s] Folky. You can follow this repos instructions to 
set it up. I will just paste uh the boiler plate  
[1371s] into my config here. It's just a short snippet 
of setup script. The last line here tells lazy to  
[1379s] load every file in a subdirectory called plugins. 
So we are going to create that directory. Now
[1390s] and now let's set up the first plugin. One thing 
that's not very convenient in the out of the box  
[1395s] Neovm experience is that if I need to quickly 
jump to another file, even if I know its name,  
[1401s] it's not very easy. The same guy, Folky, wrote 
a lot of other great Neovven plugins as well.  
[1407s] One of which is called Snacks, and it has a bunch 
of really useful utilities that help with things  
[1412s] like that. So here, let's create a file called 
navigation. in the uh plugins directory we just  
[1421s] uh created navigation.la and I'll paste in 
a plug-in spec here to install snacks. This  
[1428s] basically means the plugin is a GitHub repo 
hosted at folky/nax nvim and priority means  
[1437s] it's priority during neoim initialization. I'm 
actually not sure if this is still needed, but at  
[1442s] some point I set it to uh to a thousand. So, I'm 
just going to stick with that for now. Don't fix  
[1448s] something that's working, right? Lazy equals 
false means we don't lazy load this plug-in.  
[1453s] Some plugins can be lazy loaded to minimize the 
burden during Neoim's initial startup sequence,  
[1459s] but this one does need to be loaded up front. OPTS 
uh this is an object where we set options for the  
[1466s] plug-in. This is plug-in dependent. So every 
plug-in has different things you can set for  
[1471s] snacks. This is where we decide which utilities 
we actually need. Here I enabled picker notifier  
[1478s] and input. You can go to its GitHub repo if 
you are curious what they do and what else  
[1484s] it has. And at the end I set some key binds. 
This means if I press leader key and then F,  
[1491s] it will trigger the file picker. Leader S 
will be the grab picker and leader B will be  
[1497s] the buffers picker. Buffers in Neoim are kind of 
like what files you have open kind of. I also use  
[1504s] uh GD to go to definition. Okay. Now if I reload 
Neoim, we'll see uh Lazy knows that we have a new  
[1513s] plug-in configured that's not installed yet. So 
it's installing for us. And after it's installed,  
[1519s] we can use the key binds we set to invoke the the 
plugins. I can use space F to bring up the file  
[1526s] picker here. And here you can see we can filter 
uh by the file name. We can now also use space s  
[1532s] to do grap. Uh so I can find which files contains 
the word nyx. But sometimes I don't remember what  
[1540s] the file names are and what keywords to look for. 
I just need a file tree to browse the file system.  
[1546s] But where is the file tree? That's another plug-in 
we'll go install. Now, if you are new to Neom,  
[1552s] I think by now you are starting to get this 
philosophy. It's a highly extensible system  
[1557s] which comes with a minimal set of features and 
lets you customize and extend it by yourself. So,  
[1564s] everyone's new may look a little bit different 
or very different because everyone's assembling  
[1569s] a different set of plugins with different 
customizations layered on top. My favorite  
[1575s] file tree plug-in is called oil. And because 
this is also about navigation, I'm just going to  
[1581s] uh use the same navigation file here. And I'll 
paste it into this navigation.la file. Very simple  
[1588s] configuration. Basically, I just set it to show 
hidden files and gave a key bind that is leader  
[1595s] key followed by E. Uh so let's restart new to try 
it out. All right, it's installed leader E. And  
[1605s] now we can see this little file explorerish kind 
of view here. The beauty of oil is that it puts  
[1612s] the file system into a normal editable buffer and 
lets you view and modify the file system just like  
[1619s] how you edit any content in neo. So let's look at 
this file and let's say I want to make a copy of  
[1626s] this configuration.nix file. What I can do with 
oil is that I can press Y Y Y Y Y Y Y Y Y Y Y Y  
[1631s] Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y 
Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y  
[1632s] which means copy current line of text in 
Neovven and then P which means paste it.  
[1638s] And now there are two configuration.nix file uh 
which will conflict. So let's give this new one  
[1645s] a different name. Let's say configuration uh-2. 
And now if I do colon w to write this buffer,  
[1653s] you can see it is actually trying to copy this 
file. This is oil.neov recognizing my intent and  
[1662s] I just confirmed. You can see it actually created 
this uh configuration-2.nix file here and it's a  
[1669s] copy paste of the previous one. Similarly, if I 
go to oil and delete this line by typing dd and  
[1678s] I write and the file is gone. If you are used to 
editing in them, you will feel this is a really  
[1685s] natural way to handle the file system. is my 
favorite way to manage files. Now with agentic  
[1691s] engineering becoming my primary way of coding, I 
find that's a very common reason I come to neoim  
[1698s] is to quickly review diffs and manage the state of 
git. But there's nothing out of the box in neoim  
[1704s] that can help me do that. I use two plugins called 
neoit and git signs. I'm going to create another  
[1711s] file uh here called uh git.la Lua and I'm going to 
paste them in. Very straightforward. Uh basically  
[1720s] just giving a key bind to launch uh neoit and an 
option for git science to show the git blame of  
[1727s] the current line. So it's easy for me to see who's 
the person that last touched it. Here you can  
[1733s] also see this event equals buff win enter uh is a 
primitive in the lazy plug-in manager which means  
[1741s] only load this plugin when this event happens. And 
this event means when we actually enter a buffer.  
[1748s] You can do a lot of optimizations like this to 
speed up uh your NeoVim experience by loading  
[1754s] things only when they are needed. If we reload Neo 
Vim and let Lazy install the plug-in for us and  
[1762s] launch Neoit by using the keybind, we can see uh 
we now have a very helpful tool to see and operate  
[1770s] on the code changes tracked by Git. Uh I use this 
a lot to review diffs um and to stage changes uh  
[1778s] I have reviewed and feel good about. Now that we 
have a few plugins that need to be launched by  
[1784s] a keybind. Sometimes we might forget which key 
is for what. This is where I rely on a plugin  
[1790s] called which key. Let's put it under a um UI. Lua 
file and I'll paste it here. Surprise, surprise.  
[1800s] It's also written by our guy Folky. Uh, let's 
just install it and I'll show you what it does.
[1810s] Now, if I press the leader key, which 
is space, you can see this popup at the  
[1816s] bottom that shows what I can press next. 
This is particularly helpful when you just  
[1821s] added a new plugin or a new keybind that you 
haven't built the muscle memory around yet.  
[1827s] Speaking of keybinds, I do have a few special 
key binds that are very convenient. Let me go to  
[1834s] um the uh the init.la file so that we can 
add in one more require which is going to  
[1842s] be keys. Uh and that is going to be where we uh 
store all the key binds related configuration.
[1853s] And these are my favorite keybinds. 
I'll show you after a reload.
[1862s] The first one here makes ESC save the file. The 
reason I really like this is that normally to make  
[1868s] edits in Neoven, you have to enter insert mode 
like this. And then you can type whatever you  
[1874s] want. And after making edit, I typically need 
to come back to normal mode. So I can move my  
[1880s] cursor around to other places, right? Um, and 
the way to get back to normal mode from insert  
[1887s] mode is pressing ESC. And guess what? That is 
the same moment when I typically will want to  
[1893s] save the file. So with this keybind, I can just 
spam ESC whenever I have done some useful edits  
[1900s] and I want to save. That's very convenient. The 
next one is a no-brainer. In almost every editor,  
[1907s] control A is selecting all. So this keybind just 
replicates the same shortcut in new. The last one  
[1913s] here is an interesting one. I um probably uh 
let me keep it disabled so I can show you the  
[1921s] difference. Um it's best that I show you live 
because it's not clear from the command at all.  
[1927s] Let's say I select a few characters here uh vim 
and I press Y which means yank and that's Neo  
[1935s] Vim's way of saying copy. I basically just copied 
those three characters into my clipboard. Now,  
[1942s] if I go select a few other characters and I press 
P, which means paste, you will see that it's done  
[1950s] a replacement. Now, if I go to select a few other 
characters and press P again, what do you think  
[1958s] will happen? It should get replaced by vim again, 
right? Nope. It's all messed up. Now, this is one  
[1966s] of the counterintuitive default behaviors in 
Vim because of how the registers work. So,  
[1972s] this keybind uh here basically just uh fixes that 
behavior by stopping the replacement actions from  
[1979s] messing up with the clipboard. It just makes 
the experience much more intuitive for me.  
[1984s] All right, there is a whole bunch of other things 
I can go into about Neoim like LSP and Treitter,  
[1991s] but there are actually plenty of good videos 
out there showing specifically how to make  
[1995s] those things work well. So, I'll leave that for 
you uh to explore by yourself and skip ahead to  
[2001s] a very important chapter, which is about 
managing terminal sessions. Up until now,  
[2007s] we're just setting some config files and we do it 
one at a time. But as soon as you start to work  
[2013s] with agents, you will need to manage multiple 
agent sessions in parallel. When one agent is  
[2019s] working, you will need to kick off another. When 
one agent is done, you might want to launch new  
[2024s] of them to review its output. In a regular 
terminal window, it's hard to do that. This  
[2029s] is where terminal multiplexers come in. They 
allow you to create sessions, windows, tabs,  
[2035s] and splitting tabs into panes, etc., etc. A really 
popular option here is T-Max, which literally  
[2042s] means terminal multiplexer and is probably the OG. 
I showed it briefly in my previous video. Westerm  
[2050s] also comes with multiplexing functionality 
out of the box, but recently I have come  
[2055s] across something better called Herder. The best 
thing about it is that it's built in this agent  
[2062s] era. It understands what agents are, how they 
work, and integrated with most of the mainstream  
[2068s] agent harnesses really well. I have been using 
T-Max for years and years. So, moving to a  
[2074s] different system was not an easy decision. But 
now that I have used Herder for a few weeks, I  
[2080s] can confidently say it gives a better experience. 
It also might be the only terminal multiplexer  
[2086s] that works on Windows as well. So, if you are 
on Windows, this is very much worth trying out.  
[2092s] So let's set it up. Let's go to our homebrew 
configuration in this configuration.nix file  
[2099s] and instead of casks uh it's a normal brew. So 
we will uh copy that here and uh list it here.  
[2109s] And now let's also uh create this configuration 
uh directory. Let's also go create the config  
[2116s] file for it. Uh and it's at this location 
uh config.tomol. and let's paste it in. Uh,  
[2123s] these are pretty much just key binds that allow 
me to preserve my muscle memory in T-max. If you  
[2129s] haven't used T-Max before, you might be able to 
just rely on the defaults instead. And similarly  
[2136s] uh to other config directories, let's create a 
symbolic link so that we can apply the directory.
[2149s] All right. Now uh let's rebuild Nyx. Now 
let's get into Herder. Uh here you can see  
[2160s] uh it has a side panel on the left where it 
organizes your workspaces and agents and a  
[2166s] main area that is similar to our default terminal 
experience. Now I can use the key binds we set  
[2172s] earlier to create new tabs. Uh like this I can 
name the tab as well. uh I can say dot files  
[2178s] as well and I can split a tab into panes like this 
um and like this. These are just basics that T-Mox  
[2188s] can do as well. What's really cool about Herder 
is that its integration with agent harnesses is  
[2193s] really good. So now let's get to agents as well. 
Let's probably demo this using cloud code. Uh so  
[2199s] let's uh detach from herder. Uh let's go edit our 
homebrew configuration to install uh cloud code  
[2207s] as well. Cloud code is a cask. So let's just 
uh duplicate this line and say cloud code. Um  
[2215s] and we will be rebuilding next. Cloud code saves 
it settings into a settings uh JSON file. Um so  
[2223s] I'm just going to create that uh first. Uh the 
directory I think it's do uh it's home dot uh  
[2232s] home.cloud. Um and then I'm going to create uh the 
settings file settings.json. Uh I'll just leave it  
[2242s] as a empty JSON blob for now and let cloud write 
it when cloud starts. And similarly we need to  
[2249s] uh edit uh create a symbolic link. So we'll do it 
very similarly here. Uh it's going to be claude  
[2258s] settings.json and uh claude settings.json. And 
that should do it. Uh let's rebuild. And now  
[2269s] let's try to uh start cloud in herder. Uh I'll 
run cloud here. We'll choose some basic settings  
[2276s] here. Um and I'll login. I don't do a ton of 
customizations inside of cloud because most of  
[2283s] my setup is deliberately agent agnostic. But one 
thing I do customize in cloud code is the status  
[2289s] line. So I can monitor basic information like 
what model is being used and how much of the  
[2294s] context window is used. I do this by using the 
slash status line command uh in cloud code and  
[2301s] just ask what uh I need. Uh so I'll say I want to 
see the model name and uh percentage of context  
[2312s] window used and claude will write that for me. 
Now you can see that herder on the left hand side  
[2320s] understands that claude is working and can display 
the status inside panel. Here I'll let claude  
[2327s] uh run for now. Um you can replicate some of these 
uh things like status tracking with hooks. Uh but  
[2335s] it's just really nice that herder supports this 
out of the box and uh in a consistent way across  
[2340s] all the agent harnesses, not just cloud code. Now 
we can see cloud has uh created status lines for  
[2346s] us. Uh let me create uh destroy those pes so 
it's uh easier to see. Uh we can see opus 4.8  
[2353s] eight uh and context 2% used being listed uh under 
the prompt line uh which is the status line that  
[2359s] we just created. Uh this real-time monitoring is 
very useful. If I want to see what kind of changes  
[2365s] happened so far, I can just uh split another pane 
and use new vim and use git to see the diff. Uh  
[2373s] this is a very typical flow for how I work. Now a 
really important piece about working with agents  
[2379s] is the global memory file that affects all our 
agents behavior. I want all my agents whether  
[2386s] it's cloud or codeex or open code or pi or grock 
or whatever to behave somewhat consistently and  
[2393s] follow my rules. I do this by creating a central 
memory file. I put it here uh in my files repo.  
[2400s] I'll uh put it here uh home agents.m MD. And here 
is a set of rules I wrote for my agents. Never use  
[2411s] m dash use plain dash instead. Uh for some reason 
a lot of the AI models are trained to use M dash  
[2418s] uh whenever it needs to use a dash. Uh so now 
whenever I see m dash I just feel really robotic.  
[2424s] So whenever I need the agent to write something 
for me like a commit message or a PR description,  
[2430s] I don't want to use the mdash. Uh so that's my 
preference. Uh whenever uh when writing commit  
[2436s] messages, never auto add your agent's name as 
co-author. That is something Claude really loves  
[2441s] to do and this uh system prompt will fight against 
that. Um I don't think it's too useful for agents  
[2448s] to be like a co-author of the human. uh it's 
ultimately still the human that's going to be  
[2453s] accountable for the quality of the code change. Um 
never manually modify change lock.md files or any  
[2460s] files that are marked as autogenerated. That's 
a no-brainer. When making technical decisions,  
[2466s] do not give much weight to development cost. 
Instead, prefer quality, simplicity, robustness,  
[2473s] scalability, and long-term maintainability. 
This is a very very important rule. And the  
[2479s] reason I have this rule is that agents uh the 
large chunkage models today are trained from  
[2485s] human data. And when when we humans are making 
estimations about our projects, our estimations  
[2492s] are usually in days, weeks or months. But agents 
can work a lot faster. But because the agents are  
[2499s] trained from human data, it tends to assume the 
estimation, the development cost is going to be as  
[2506s] high as what humans estimate. So when agents are 
making decisions, sometimes it will put too much  
[2512s] weight onto the development cost and prefer those 
really cheap and not very scalable solutions. That  
[2519s] is bad. So I have this rule here to fight against 
that so that the agents don't put too much weight  
[2525s] onto development cost and instead prefer the other 
things that we care about here. When doing bug  
[2532s] fixes, always start with reproducing the bug in an 
end to end setting as closely aligned with how an  
[2539s] end user would experience it as possible. This 
is also very important uh because uh otherwise  
[2545s] sometimes the agent will jump into conclusion 
and start to fix a problem that doesn't exist.  
[2551s] So this makes sure that the agent will find 
the real problem. So the fix will be actually  
[2557s] uh solving the problem uh effectively. 
Now, when end to end testing a product,  
[2563s] be picky about the UI you see and be obsessed with 
pixel perfection. If something clearly looks off,  
[2571s] even if it is not directly related to what you 
are doing, try to get it fixed along the way. Um,  
[2577s] and the last rule is similar. Apply the same 
high standard to engineering excellence. lint  
[2583s] test failures and test flakiness. If you see one, 
even if it's not caused by what you are working on  
[2589s] right now, still get it fixed. These are also 
rules I find very helpful in holding a high  
[2595s] quality bar. Now I'm going to use home manager 
to distribute this file to all the agents. Um so  
[2603s] we'll come to home.nix and we will be pasting 
this in. This is creating sim links into each  
[2611s] agent's global memory file location. Claude use 
this cla.md and other agents use uh different  
[2618s] locations as well. So now after a rebuild that 
same global memory file will be loaded by all my  
[2626s] agents consistently. And the really cool thing 
now is the rebuild script can fully reproduce  
[2632s] everything we have configured so far. No matter 
what the current state of the system is, I can  
[2638s] now go to a freshly installed Mac, clone this file 
repo, and immediately get the entire setup up and  
[2644s] running. All right, this files repo has now been 
published onto my GitHub. You now have pretty much  
[2651s] the same development environment that I use. It's 
time to start building. If you haven't come across  
[2657s] my previous video about my agentic engineering 
workflow yet, now is a great time to catch up and  
[2663s] see how I actually get work done with this setup. 
Thank you for watching and see you next time.