<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Recurse on Jahvon Dockery</title>
    <link>https://jahvon.dev/tags/recurse/</link>
    <description>Recent content in Recurse on Jahvon Dockery</description>
    <image>
      <title>Jahvon Dockery</title>
      <url>https://jahvon.dev/images/og-default.png</url>
      <link>https://jahvon.dev/images/og-default.png</link>
    </image>
    <generator>Hugo -- 0.153.4</generator>
    <language>en-us</language>
    <lastBuildDate>Tue, 09 Sep 2025 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://jahvon.dev/tags/recurse/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>return recurse(): Summer of Building and Learning</title>
      <link>https://jahvon.dev/notes/rc-return-statement/</link>
      <pubDate>Tue, 09 Sep 2025 00:00:00 +0000</pubDate>
      <guid>https://jahvon.dev/notes/rc-return-statement/</guid>
      <description>What I built and learned during 12 weeks of focused development at the Recurse Center.</description>
      <content:encoded><![CDATA[<p>I wrapped up my batch at <a href="https://www.recurse.com/scout/click?t=420ecb9ef5810758f6fe8dec816d80a8">Recurse Center</a> a few weeks ago and wanted to capture what I worked on during those 12 weeks.
RC gave me the space I needed to dive deep into a passion project, pick up new technologies, and push my
comfort zone across many areas of software engineering.</p>
<h3 id="learning-highlights">Learning highlights</h3>
<p><strong>Collaborative learning through pairing</strong> - Gained exposure to a diverse set of projects and development approaches. I didn&rsquo;t always
understand the technologies or projects I paired on, but they often provided inspiration for improving my own work or workflows. Notable
pairing sessions included a recipe management app with OpenAI integration, a BPE tokenizer implementation, and programming language development.</p>
<p><strong>Teaching through presentation</strong> - Regular demos of flow progress and architectural decisions solidified my understanding and gave me
practice explaining complex technical concepts to others. Take a look at my <a href="https://docs.google.com/presentation/d/11WBdY8pZ5IPJkBGb9A9pZIWUTCa9D2RAJaeNHPXNIQg/edit?usp=sharing">final presentation deck</a>
for the overview that I gave on flow&rsquo;s composable workflows!</p>
<p><strong>Discovering my learning patterns</strong> - After a few weeks of experimenting with time management, I settled on a three-day project focus
while leaving space for exploration. Using flow itself as a platform for trying new technologies safely turned out to be an effective
learning strategy.</p>
<p><strong>Balancing focus and community</strong> - The biggest challenge was finding rhythm between deep work and community engagement - there were so
many interesting things happening at RC. Writing regular check-ins and reading others&rsquo; updates helped me reflect and adjust that balance as desired.</p>
<h3 id="core-project">Core project</h3>
<p>As I described in <a href="https://jahvon.dev/notes/rc-6-week-flow/">6 Weeks of flow at Recurse Center</a>, I decided to expand my long-running side project <em>flow</em> as my
main focus. A little more than half of my flow work fell into these four major efforts, with the remainder spent on bug fixes and UX
improvements throughout.</p>
<p><strong>flow CLI v1.0 release</strong> - Stabilized platform with comprehensive testing, v2 of the integrated secrets vault, major documentation
updates, and CI integration via custom <a href="https://github.com/marketplace/actions/flow-execute">GitHub Action</a></p>
<p><strong>Desktop app POC</strong> - Built proof-of-concept with <a href="https://github.com/tauri-apps/tauri">Tauri</a>, establishing CLI-as-source-of-truth architecture for upcoming first release</p>
<p><strong>Executable generation</strong> - Added parsers for makefile, package.json, and docker-compose to streamline workflow migration</p>
<p><strong>MCP server</strong> - Built <a href="https://modelcontextprotocol.io/docs/getting-started/intro">Model Context Protocol</a> integration enabling AI tools to understand flow workspaces and executables natively</p>
<p>Check out my new <a href="https://jahvon.dev/architecture/flow/">architecture doc</a> for more details on how I&rsquo;ve been building this local-first developer automation platform. To continue on with the &ldquo;learning generously&rdquo; mindset, I plan to keep it updated as the architecture evolves.</p>
<h3 id="honorable-mentions">Honorable mentions</h3>
<p><strong>Dev environment exploration</strong> - Tried various changes to my development editors and workflows, including AI-enhanced IDEs,
terminal-based applications, and improvements to local project and dotfile organization. This also included deeper integrations of
flow into my productivity, development, and operation workflows as I began to use it to standardize workflows across my side-projects.</p>
<p><strong>&ldquo;Impossible&rdquo; experiments</strong> - Single-day projects at the edge of my abilities, including a CGo process monitor using C for system process
information and a container runtime with runc. Also explored a WebAssembly plugin system for flow - not as impossible as it seemed but
informative for future feature planning.</p>
<p><strong>Creative coding</strong> - Completely new domain I fell into through RC events. These sessions became a refreshing creative outlet, including
mini projects with p5.js, tone.js, Motion Canvas, and the Python Imaging Library. Check out <a href="https://codepen.io/jahvon/pen/pvJXJjv">this Codepen</a> for an example of one of my creations.</p>
<p><strong>Vibe coding</strong> - Exploration of spinning up complete applications with AI development tools. These weekly sessions gave me better
appreciation of AI-assisted coding and helped me understand its current limitations. I&rsquo;ve since been vibe coding a few small apps
for my home lab. It&rsquo;s also been cool to also see how vibes + flow MCP can produce some neat, standardized workflows.</p>
<p><strong>Community programming</strong> - Beyond the creative and vibe coding sessions, I explored topics well outside my main focus through these
community activities. System design discussions, a workshop on building Obsidian plugins, and weekly non-programming presentations are
just a few that kept me curious about areas I wouldn&rsquo;t encounter naturally. As a &ldquo;never-graduated&rdquo; alum, I&rsquo;m looking forward to continuing
to participate whenever time allows.</p>
<p><strong>WordPress project</strong> - Pro bono work for nonprofit Boston HERC. Started before RC but got more time to work on this and
launched the first phase of the redesign of their core pages at <a href="https://bostonherc.org">bostonherc.org</a>. It was interesting finding
ways to apply my evolving learning style to evaluating and picking up newer, no-code frameworks like Elementor.</p>
<hr>
<p>My time at RC ended up giving me much more than I was hoping for. I got dedicated time to tackle ambitious ideas
I&rsquo;d been putting off for a while and learn new-to-me technologies in a supportive environment. The collaborative culture
pushed me to share my work regularly and learn from other skilled builders working on completely different problems.
As I move into the next phase of my career, I&rsquo;m carrying forward not just new technical skills but a better understanding
of how I learn best and what gets me excited about software engineering.</p>
<script async defer src="https://www.recurse-scout.com/loader.js?t=420ecb9ef5810758f6fe8dec816d80a8"></script>
]]></content:encoded>
    </item>
    <item>
      <title>6 Weeks of flow at Recurse Center</title>
      <link>https://jahvon.dev/notes/rc-6-week-flow/</link>
      <pubDate>Mon, 30 Jun 2025 00:00:00 +0000</pubDate>
      <guid>https://jahvon.dev/notes/rc-6-week-flow/</guid>
      <description>An update on my journey tackling developer tool chaos with a personal automation platform. 6 weeks of building desktop apps, cryptographic vaults, and feature planning at Recurse Center.</description>
      <content:encoded><![CDATA[<p>I&rsquo;ve been thinking a lot about developer tooling and the idea of a &ldquo;personal developer platform&rdquo; - something that I could adapt to aid how <em>I</em> want to develop. Modern development can feel like tool chaos at times - we&rsquo;re juggling package managers, test runners, linters, deployment scripts, language-specific tooling, and dozens of open source CLI tools. Each project accumulates its own collection of scripts and commands that live in different places with different interfaces.</p>
<p>I introduced <a href="https://flowexec.io/">flow</a> in <a href="https://jahvon.dev/notes/forging-flow/">another post</a> a few months ago, but I&rsquo;ve had the amazing opportunity to start a sabbatical at the <a href="https://www.recurse.com/scout/click?t=420ecb9ef5810758f6fe8dec816d80a8">Recurse Center</a>, where I&rsquo;ve been able to think more deeply about the problems I was solving and the technologies I wanted to learn about! As I mentioned in that post, flow has been my &ldquo;learning platform&rdquo; over the last 2 years and I knew I wanted to take it a step further at Recurse.</p>
<p>I&rsquo;m at the halfway point of my time at RC and am excited to share how my first 6 weeks have been on my main coding project.</p>
<h2 id="flow-desktop">flow desktop</h2>
<p>I&rsquo;ve been itching to work on a frontend project for a while now. While building the flow TUI library, I had lots of fun thinking about how I could create a good experience through visuals and layout. <a href="https://github.com/charmbracelet/bubbletea">Bubble Tea</a> has been fun to use here, but I&rsquo;ve wanted to do some UI development with more possibilities. Doing this in the &ldquo;browser&rdquo; and using new-to-me technologies sounded like a great plan.</p>
<p>Coming into RC, this was something I knew I wanted to work on, but my excitement grew as I started to learn about the fascinating world of frontend development through RC pair programming, events, and chats.</p>
<p><strong>Architecture Decision: CLI as Single Source of Truth</strong></p>
<p>Instead of duplicating business logic in my desktop app, I&rsquo;ve been building it as a pure visualization layer over the existing CLI.</p>
<p><img src="https://jahvon.dev/images/flow-desktop-arch.png" srcset="https://jahvon.dev/images/flow-desktop-arch_hu_fde535ab93ee9ac8.png 600w, https://jahvon.dev/images/flow-desktop-arch.png 1201w" sizes="(min-width: 768px) 720px, 100vw" width="1201" height="446"
     alt="Desktop Architecture"
     loading="lazy" decoding="async">
</p>
<p>This felt risky at first - wouldn&rsquo;t spawning processes be too slow? Turns out CLI commands execute pretty fast thanks to some caching I do on the CLI side. The whole round trip feels instant with my current usage.</p>
<p><strong>Tech Stack</strong></p>
<p>All of the resources, pairing, feedback, and individual research I&rsquo;ve done has landed me on the following:</p>
<ul>
<li><strong>Tauri</strong>: Gives me Rust backend + web frontend without Electron&rsquo;s bloat. Bonus that it&rsquo;s an opportunity to learn some Rust.</li>
<li><strong>TypeScript</strong>: I was able to get TS and Rust types generated from the same JSON schema that I use to generate Go code. This has been making development much smoother across the 3 languages that flow now uses.</li>
<li><strong>React &amp; Mantine UI</strong>: VSCode-like components without building everything from scratch. Their <a href="https://mantine.dev/x/spotlight/">Spotlight</a> extension is what sold me - it could be a really cool search and command center for the UI!</li>
</ul>
<p><strong>Demo!</strong></p>
<p>Here is a quick demo of me using my current implementation of the desktop. This shows the workspace and executable viewer/runner in action - you can see me running an executable directly from the UI and playing with the theme picker I prototyped for customization.</p>
<video class="demo-video"
       controls preload="none" poster="https://jahvon.dev/images/desktop-demo-poster.png"
       aria-label="The flow desktop app, early build">
  <source src="https://jahvon.dev/images/flow-desktop-demo.mp4" type="video/mp4">
</video>

<p>I still have more work to do here, but it&rsquo;s been satisfying seeing my ideas come to life as I pick up these new technologies.</p>
<h2 id="vaults-v2">vaults v2</h2>
<p>I had a couple of pain points with the vault that I initially built for flow. The UX was pretty simple but limiting. I&rsquo;ve also been really wanting a way to integrate my Bitwarden secrets into flow seamlessly. This led me to brainstorm a new design for that feature. I spent my first 2 weeks at RC doing some light research on cryptography with Go, studying how other tools handle secrets, and building a simple POC.</p>
<p>I decided to introduce a &ldquo;provider&rdquo; concept that also improves the experience around having multiple vaults. I currently have an implementation for an updated version of my AES symmetrically encrypted vault, added an Age asymmetric encryption backend, and plan to add a backend for custom CLI-tool vault managers. You can see what I came up with in <a href="https://github.com/jahvon/vault">this repo</a>. From the flow perspective, the experience would be like this:</p>
<p><strong>Creating a vault</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Auto-generates everything for the AES vault</span>
</span></span><span class="line"><span class="cl">flow vault create development
</span></span><span class="line"><span class="cl"><span class="c1"># Create an Age vault with identity generated from age-keygen</span>
</span></span><span class="line"><span class="cl">flow vault create team --type age --recipients key1,key2,key3 --identityFile id.txt
</span></span><span class="line"><span class="cl"><span class="c1"># External needs CLI integration</span>
</span></span><span class="line"><span class="cl">flow vault create bitwarden --type external --interactive
</span></span></code></pre></div><p><strong>Vault Switching as Primary UX</strong></p>
<p>Borrowed the mental model from git/kubectl:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">flow vault switch development    <span class="c1"># Like git checkout</span>
</span></span><span class="line"><span class="cl">flow secret <span class="nb">set</span> api-key <span class="s2">&#34;dev-123&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">flow vault switch production
</span></span><span class="line"><span class="cl">flow secret <span class="nb">set</span> api-key <span class="s2">&#34;prod-456&#34;</span>
</span></span></code></pre></div><p>This allows for clean secret references in executables: <code>secretRef: &quot;api-key&quot;</code> uses current vault, <code>secretRef: &quot;production/api-key&quot;</code> is explicit.</p>
<h2 id="technical-decisions">Technical decisions</h2>
<h3 id="executable-composition">Executable composition</h3>
<p>Executables aren&rsquo;t just scripts - they&rsquo;re composable units with conditional logic:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">serial</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">failFast</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">execs</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">if</span><span class="p">:</span><span class="w"> </span><span class="l">os == &#34;darwin&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">cmd</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;command -v mytool || brew install mytool&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">if</span><span class="p">:</span><span class="w"> </span><span class="l">env[&#34;PUSH&#34;] == &#34;true&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">cmd</span><span class="p">:</span><span class="w"> </span><span class="l">make image</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">ref</span><span class="p">:</span><span class="w"> </span><span class="l">deploy development</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">reviewRequired</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">  </span><span class="c"># Pauses for human confirmation</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">ref</span><span class="p">:</span><span class="w"> </span><span class="l">launch app</span><span class="w">
</span></span></span></code></pre></div><p>The expression language (using <a href="https://github.com/expr-lang/expr">Expr</a>) has access to OS info, environment variables, and flow&rsquo;s cache. It&rsquo;s like having bash conditionals but declarative.</p>
<h3 id="process-architecture">Process architecture</h3>
<p>The desktop app&rsquo;s process model is pretty simple. Each user action spawns a CLI process:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="cp">#[tauri::command]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">async</span><span class="w"> </span><span class="k">fn</span> <span class="nf">get_workspaces</span><span class="p">()</span><span class="w"> </span>-&gt; <span class="nb">Result</span><span class="o">&lt;</span><span class="nb">Vec</span><span class="o">&lt;</span><span class="n">Workspace</span><span class="o">&gt;</span><span class="p">,</span><span class="w"> </span><span class="nb">String</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">output</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Command</span>::<span class="n">new</span><span class="p">(</span><span class="s">&#34;flow&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">.</span><span class="n">args</span><span class="p">([</span><span class="s">&#34;workspace&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;list&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;--output&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;json&#34;</span><span class="p">])</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">.</span><span class="n">output</span><span class="p">().</span><span class="k">await</span><span class="o">?</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">serde_json</span>::<span class="n">from_slice</span><span class="p">(</span><span class="o">&amp;</span><span class="n">output</span><span class="p">.</span><span class="n">stdout</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>This seems inefficient but has huge benefits:</p>
<ul>
<li>Desktop crashes don&rsquo;t corrupt CLI state</li>
<li>CLI updates immediately benefit desktop</li>
<li>No state synchronization between processes</li>
<li>Easy to debug - each operation is a discrete CLI command</li>
</ul>
<h2 id="rc-moments-that-shaped-the-code">RC moments that shaped the code</h2>
<p><strong>Pair Programming</strong>: I paired on setting up Tauri and trying to integrate it with the CLI. We came up with the great idea of using some of my existing CLI output formatting options to get data through the app. This turned out to be a great decision to make on the fly. Conversations with others helped me confirm that CLI-as-source-of-truth wasn&rsquo;t a compromise - it was the right abstraction.</p>
<p><strong>The Feedback Loop</strong>: RC&rsquo;s culture of sharing work-in-progress meant getting feedback on half-baked ideas. I&rsquo;ve enjoyed presenting and demoing my progress throughout my time. I&rsquo;d thought extensions would be a neat feature but I never actually needed them myself. Hearing about the different ways that others think flow could be extended convinced me to reopen an <a href="https://github.com/flowexec/flow/issues/185">issue</a> I closed.</p>
<p><strong>Community Inspiration</strong>: Seeing the variety of projects and approaches at RC has reinforced my belief that developer tools should be adaptable rather than prescriptive. Everyone has their own workflow, and the best tools are the ones that bend to fit how you think, not the other way around.</p>
<h2 id="next-up">Next up</h2>
<h3 id="flow-mcp-server">flow MCP server</h3>
<p>I&rsquo;ve started using Claude Code and this has inspired me to learn how to create a Model Context Protocol server that will allow AI to understand flow workspaces and executables natively. I&rsquo;d love to eventually have something that enables:</p>
<ul>
<li>Browsing flow files and suggesting syntax improvements</li>
<li>Generating new workflows from natural language</li>
<li>Debugging failures with full workspace context 🚀</li>
</ul>
<h3 id="wasm-plugin-system">WASM plugin system</h3>
<p>Extending flow with WASM-integrated extensions. I want to try to allow automations to be programmable in two ways:</p>
<ul>
<li><strong>Executable template generator</strong>: Plugins that run template generation for flow-discoverable executables (from APIs, templates, external sources). I&rsquo;m thinking of something like Taskfile/just → flow executable integrations to start</li>
<li><strong>WASM Runtime executable type</strong>: Plugin executables that run sandboxed through flow</li>
</ul>
<p>This will be my first time getting hands-on with WebAssembly and I already have many ideas for cool plugins that will allow me to tinker with a variety of languages in the future.</p>
<h3 id="test--release-improvements">Test &amp; release improvements</h3>
<p>The best way to try out some of these new and upcoming features would be to clone the flow repo and run the <code>build binary</code> executable to get a local go build. Note that the main branch is not guaranteed to be stable, though.</p>
<p>With a new component in the flow ecosystem, I need to level up the test and release process as I prepare for v1 over the next couple of months. This means learning frontend testing practices, updating my GitHub workflows to handle multi-language builds, and rethinking the installation process to bundle the desktop app alongside the CLI.</p>
]]></content:encoded>
    </item>
  </channel>
</rss>
