Trimming the fat for agentic coding AI agents like Cursor and GitHub Copilot aren't just autocomplete tools anymore; they are active participants in the development loop. However, every character they read and write costs money. Nuno Maduro recently launched Pow, a package designed specifically to optimize this economy by stripping away human-centric formatting from PHPUnit and Pest outputs. The goal is simple: provide agents with only the data they need, eliminating the fluff of Tailwind-styled dashboards or verbose test results. The reality of token consumption Testing Pow with a fresh Laravel 13 project and the Kimi K2.5 model reveals a nuanced truth about AI-driven development. While a high-tier model might solve a problem in one shot, cheaper models often "run in circles." They generate code, trigger a test failure, analyze the stack trace, and attempt a fix. In these recursive loops, the volume of tokens consumed by repetitive, verbose test responses adds up. Pow addresses this by shortening successful responses to a few essential symbols. Current limitations and the failure gap During my hands-on evaluation, a critical limitation emerged: Pow currently focuses heavily on successful test results. When tests fail, the package often leaves the response untruncated. This is a double-edged sword. While agents require detailed error information to debug, passing an entire, unoptimized stack trace to an agent consumes significant token budget. For Pow to become an essential tool, it must find a middle ground that zips failed output without losing the semantic meaning needed for a fix. Future integration in the Laravel ecosystem Despite being in its early version 0.1 stages, Pow signals a broader shift in how we build developer tools. It relies on an Agent Detector to identify if the current environment is an AI interface like Cursor. There is a strong possibility this logic becomes default behavior in future versions of Pest or Laravel. As we enter the agentic era, optimizing our CLI output for machine readability is no longer optional—it's a financial necessity.
GitHub Copilot
Products
ArjanCodes (4 mentions) frames GitHub Copilot as a tool that speeds up coding but doesn't replace the need for human architectural design, highlighted in videos like "Coupling 101" and "DeepSeek Won't Matter for Software Engineers."
- Apr 9, 2026
- Apr 7, 2026
- Jan 30, 2026
- Jan 28, 2026
- Sep 10, 2025
The Premise of the Great Collapse Recent industry whispers and social media trends suggest that Software as a Service (SaaS) is facing an existential crisis. The argument, often echoed by leaders like Satya Nadella, posits that most business applications are merely CRUD databases wrapped in business logic. With the rise of AI agents and "vibe coding," many believe these platforms will collapse into a single, fluid agent era where bespoke internal tools replace expensive subscriptions. While the technical barrier to entry for building software is plummeting, the reality of running a global service remains stubbornly complex. The Barrier of Invisible Infrastructure Software development is often the simplest part of a successful SaaS product. High-utility platforms like Stripe or Squarespace do not just offer code; they provide a gateway to massive, regulated ecosystems. Consider Stripe. A developer might "vibe code" a functional payment button in an afternoon, but they cannot code the legal agreements with global banks, compliance with international tax laws, or the trust required to handle millions in transactions. The value lies in the hard-won partnerships and infrastructure that an AI agent cannot simply prompt into existence. Regulation and the Compliance Moat Regulatory requirements act as a natural defense for established platforms. An accounting SaaS must adhere to GDPR, ISO security standards, and local tax laws that vary by country. In the Netherlands, for instance, independent accountants often only support specific, validated platforms. You cannot replace a legally compliant audit trail with a custom-coded agent if the bank refuses to grant that agent API access or if the government doesn't recognize the output. These administrative and legal hurdles form a "moat" that protects the SaaS model from being completely disrupted by decentralized AI tools. The Future of Integrated Intelligence Instead of dying, SaaS is evolving to absorb the very tools meant to replace it. Platforms are already implementing Model Context Protocol (MCP) to allow AI agents to interact with their data seamlessly. We are moving toward a hybrid world where graphical user interfaces and chat interfaces coexist. The goal remains efficiency. It is still cheaper and more reliable to pay for a specialized service like Spotify than to build a custom player, negotiate music label licenses, and manage cloud streaming personally. SaaS isn't dead; it's simply getting smarter.
Jul 18, 2025Overview Managing source code effectively is the difference between a streamlined release and a chaotic debugging session. This guide explores the mechanical and strategic nuances of Git branching. By using a FastAPI web application as a concrete example, we demonstrate how to isolate new features, maintain a clean history, and choose between different integration strategies like merging and rebasing. Understanding these patterns allows you to collaborate without stepping on your teammates' toes. Prerequisites To follow this tutorial, you should have a baseline understanding of Python syntax and the basic concept of version control. You will need a terminal environment, Git installed, and a package manager like UV or pip. Familiarity with basic HTTP methods (GET) and unit testing with Pytest is also beneficial. Key Libraries & Tools * **FastAPI**: A modern, fast (high-performance) web framework for building APIs with Python. * **GitKraken**: A visual Git client that simplifies branch management and history visualization. * **UV**: An extremely fast Python package installer and resolver. * **Pytest**: A framework that makes it easy to write small, readable tests. Code Walkthrough Initializing the API We start by defining a simple root endpoint. This serves as our stable baseline on the `main` branch. ```python from fastapi import FastAPI app = FastAPI() @app.get("/") def read_root(): return {"Hello": "World"} ``` Isolating Features via Branches Instead of modifying `main` directly, create a feature branch. This keeps the production-ready code clean while you experiment. We add a new `goodbye` endpoint and a corresponding unit test to verify it works. ```python @app.get("/goodbye") def say_goodbye(name: str = "World"): return {"message": f"Goodbye {name}"} ``` Merging vs. Rebasing When it is time to bring changes back to `main`, you face a choice. A **Standard Merge** creates a new commit that ties the two histories together. This preserves the exact context of when a feature was developed but can lead to a "spaghetti" visual history. **Rebasing** offers a cleaner alternative. It takes your feature commits, sets them aside, moves your branch to the tip of the current `main`, and then reapplies your work on top. This results in a perfectly linear history. If `main` hasn't changed since you branched, Git performs a **Fast-Forward**, simply moving the branch pointer forward without creating a new commit at all. Syntax Notes * **Feature Flags**: When using Trunk-Based Development, use boolean constants to toggle code paths. This allows you to merge unfinished code safely. * **Naming Conventions**: In GitFlow, prefix branches with `feature/` or `hotfix/` to organize the repository automatically. Practical Examples Real-world teams often use **GitFlow** for structured releases where separate `develop` and `main` branches exist. Alternatively, fast-moving startups might prefer **Trunk-Based Development**, pushing directly to `main` while hiding incomplete features behind logic toggles to avoid long-lived branch conflicts. Tips & Gotchas * **Rewrite History with Caution**: Never rebase a branch that others are also working on. It changes commit hashes and will break their local environments. * **Small Commits**: Commit early and often. Smaller commits make resolving merge conflicts significantly easier. * **Test Before Integration**: Always run Pytest on your feature branch before merging to ensure you aren't introducing regressions.
Apr 11, 2025The Race to the Bottom AI models like DeepSeek represent a massive shift in how we perceive the value of code. While billions flow into companies like OpenAI and Microsoft, the reality is a swift race to the bottom. AI is becoming a commodity—a free or cheap feature integrated into existing tools rather than a standalone product worth a premium. For software engineers, this means the act of writing code is no longer the primary value driver. Shifting Expectations in Development Companies will not simply fire their entire engineering staff because of automation. Instead, they will move the goalposts. Management will expect developers to build three times as fast using tools like GitHub Copilot. The expectation shifts from "can you write this function?" to "can you design a robust, scalable system?" Efficiency is now the baseline, not the competitive advantage. The Evolution of the Junior Role Junior engineers face the most immediate pressure, especially in startup environments where first-version prototypes are easily generated by AI. However, this creates an opportunity for a more exciting career path. Instead of spending years on menial syntax tasks, juniors can engage with high-level architecture and design decisions much earlier. The role is becoming less about being a "coder" and more about being a software designer who understands how to orchestrate complex systems. Deepening the Moat through Architecture The only way to remain relevant is to go deep. Specialized skills in software architecture and complex system design provide a moat that AI cannot easily cross. While Apple Intelligence and other models can produce snippets or even small apps, they lack the human judgment required for nuanced design decisions. To thrive, engineers must use AI as a stepping stone to reach higher levels of abstraction and complexity.
Jan 31, 2025Overview Setting up a Python development environment in VSCode often feels like a constant battle against broken imports, mismatched interpreter versions, and testing suites that refuse to discover your code. This guide moves past temporary fixes to establish a robust, professional workflow. We will focus on creating a project structure that Pylance understands and Pytest can navigate, using modern tools like UV for dependency management. Prerequisites To follow along, you should have VSCode installed and a basic understanding of the Python language. Familiarity with the terminal or command prompt is necessary for running installation commands and project initialization. Key Libraries & Tools * **UV**: A fast Python package installer and resolver written in Rust, used as a modern alternative to Poetry. * **Ruff**: An extremely fast Python linter and code formatter. * **Pylance**: The default language server for Python in VSCode, providing IntelliSense and type checking. * **Pytest**: A framework that makes it easy to write simple and scalable test suites. * **Even Better TOML**: An extension for better syntax highlighting and navigation in configuration files. Project Structure and Initialization Instead of installing packages globally, we use UV to create an isolated environment. Start by initializing your project in the terminal: ```bash uv init --no-workspace ``` A professional structure separates the logic from the metadata. Move your code into a `src` directory and include a `__init__.py` file to signal that it is a package. Your directory should look like this: ```text my_project/ └── src/ └── my_app/ └── __init__.py └── main.py └── tests/ └── test_main.py └── pyproject.toml ``` To add Pytest as a development dependency, run: ```bash uv add --dev pytest ``` Solving the Import and Test Discovery Crisis The most common headache is Pytest failing to find your modules because it doesn't know about the `src` folder. You fix this by adding a `pythonpath` setting to your `pyproject.toml` file: ```toml [tool.pytest.ini_options] pythonpath = "src" ``` However, Pylance might still show "reportMissingImports" in the editor even if tests run. You must align the editor's analysis with your runtime path by creating a `.vscode/settings.json` file: ```json { "python.analysis.extraPaths": ["./src"], "python.testing.pytestArgs": ["tests"], "python.testing.unittestEnabled": false, "python.testing.pytestEnabled": true } ``` Professional VSCode Configuration Managing settings across a team requires moving beyond global user settings. Use **Folder Settings** within the `.vscode` directory to ensure every developer on the project uses the same interpreter and formatter. Recommended Extensions Share a consistent toolset by creating `.vscode/extensions.json`. When a team member opens the project, VSCode will prompt them to install the necessary tools: ```json { "recommendations": [ "ms-python.python", "charliermarsh.ruff", "tamasfe.even-better-toml" ] } ``` Syntax Notes and Conventions * **TOML Folding**: Use the Even Better TOML extension to collapse large configuration blocks in your `pyproject.toml`. * **Bundled Formatters**: If you use the Ruff extension, enable the `useBundled` setting to avoid needing a separate local installation of the binary. * **Analysis Paths**: Always use relative paths (like `./src`) in `extraPaths` to ensure settings work across different machines. Tips & Gotchas * **Priority of Settings**: Remember that **Folder Settings** override **Workspace Settings**, which in turn override **User Settings**. If your project isn't behaving, check the local `.vscode/settings.json` first. * **Syncing**: Use VSCode's built-in Settings Sync for personal preferences like themes and fonts, but keep project-specific logic (like the Python path) in the repository. * **Source Folder**: Never name your root code folder `source` or `src` without an `__init__.py` if you intend to import it as a package; Pylance needs that marker to recognize the package boundary correctly.
Nov 22, 2024The Dominance of the Domain Model Software development often gets bogged down in the minutiae of syntax and implementation. We argue over where to place comments or whether a function should be a class method. These details feel vital, but Domain-Driven Design by Eric Evans suggests they are secondary. The real heart of software is the domain model—a conceptual representation of data and behavior that mirrors the real-world problem you are solving. If your model is wrong, the most beautiful Python code in the world won't save you. Cultivating a Shared Ubiquitous Language One of the most critical steps in building robust systems is bridging the gap between developers and stakeholders. You cannot write effective software for a domain you do not understand. This requires cultivating a shared language. Developers shouldn't just take a list of requirements from a business analyst; they must engage in a feedback loop. This interaction uncovers technical constraints and conceptual misunderstandings early. Whether you are building an HR system or an Electric Vehicle interface, the language used in the code must match the language used by the domain experts. Trash Can Oriented Programming I view code as a temporary, evolving expression of a persistent domain model. Because models change as we learn more, we must optimize for iteration. This means writing code that is easy to throw away. We use patterns like the Strategy pattern or focus on reducing coupling specifically so we can toss out an old implementation and replace it without the whole system collapsing. If you treat your code as precious, you become resistant to the changes required to improve the model. Embracing "trash can oriented" development allows you to fail fast and refine the logic that actually matters. The Role of AI in Evolving Models Modern tools like GitHub Copilot change the equation of how we spend our time. AI is exceptionally good at handling the repetitive task of expressing a model in code. This shifts the developer's primary value away from syntax and toward analytical thinking. Our job is to crunch knowledge, establish constraints, and ensure the conceptual model makes sense. AI helps us cycle through versions of our code faster, which in turn lets us iterate on the underlying domain model at a pace previously impossible.
Feb 16, 2024The Modern Backend Toolkit Transitioning Visual Studio Code from a simple text editor into a full-scale backend IDE requires more than just syntax highlighting. For modern developers, the goal is to minimize context switching. Every time you leave your editor to check a database, test an API, or review a Git history, you break your cognitive flow. By integrating these tools directly into the workspace, you maintain a unified environment that handles everything from HTTP requests to automated linting. Prerequisites To follow this guide, you should have a basic understanding of Python and FastAPI. Familiarity with Docker for containerization and Git for version control is also recommended. Key Libraries & Tools * Postman: A platform for building and testing APIs. * GitLens: An extension that supercharges the built-in Git capabilities. * Ruff: An extremely fast Python linter and code formatter. * SQLite Extension: A tool to explore and query SQLite databases inside the editor. Streamlining API Testing and Database Inspection Instead of juggling external clients, the Postman extension allows you to manage collections and environment variables directly. You can execute requests against a local uvicorn server and view formatted JSON responses without leaving your code. ```python from fastapi import FastAPI app = FastAPI() @app.get("/") def read_root(): return {"items": [1, 2, 3]} ``` When working with local data, the SQLite Extension enables a sidebar explorer. You can open a `.db` file and run queries or view table contents as HTML with a single click. This is far more efficient than writing manual fetch scripts just to verify data persistence. Syntax Notes and Performance The move from Pylint to Ruff represents a massive leap in performance. Because Ruff is written in Rust, it performs 10 to 100 times faster than traditional Python-based tools. To get the most out of it, configure your `settings.json` to format on save: ```json { "editor.formatOnSave": true, "editor.defaultFormatter": "charliermarsh.ruff", "notebook.formatOnSave": true } ``` Tips & Gotchas Always ensure your linter is compatible with your Python version. Older tools like Pylint often lag behind new syntax features in Python 3.12. Ruff provides immediate compatibility and can even automatically remove unused imports, keeping your codebase lean without manual intervention.
Feb 9, 2024Overview Refactoring legacy code often feels like walking through a minefield. You change one line of an `if` statement, and suddenly a seemingly unrelated feature breaks. The Gilded Rose Kata, originally created by Terry Hughes, is the industry-standard exercise for practicing how to handle these "spaghetti code" scenarios. This tutorial demonstrates a systematic 5-step framework to transform messy, nested conditional logic into a clean, extensible class hierarchy using Python. Prerequisites To follow this guide, you should be comfortable with basic Python syntax, including loops and conditional statements. Familiarity with Object-Oriented Programming (OOP) concepts like classes and inheritance is helpful, along with a basic understanding of how to run tests using pytest. Key Libraries & Tools * **Python**: The primary programming language used for the implementation. * **pytest**: A robust testing framework used to build our safety net. * **GitHub Copilot**: An AI pair programmer used to accelerate boilerplate generation and test writing. * **Hypothesis**: A library for property-based testing (recommended for advanced edge-case detection). Step 1 & 2: Analysis and Goal Setting Before touching the keyboard, you must understand the business logic. In the Gilded Rose, items have a `sell_in` value (days remaining) and a `quality` value. Most items degrade over time, but "Aged Brie" improves, and "Sulfuras" is a legendary item that never changes. Our specific goal is to add a new "Conjured" item type. The measure of success is simple: after refactoring, adding this new type should require minimal changes to the core engine. Step 3: Creating the Safety Net You cannot safely refactor without tests. If you don't have a safety net, you're just guessing. Start by writing pytest functions for every requirement. ```python import pytest from gilded_rose import Item, GildedRose def test_item_quality_decreases_over_time(): items = [Item("Standard Item", 10, 20)] gilded_rose = GildedRose(items) gilded_rose.update_quality() assert items[0].quality == 19 assert items[0].sell_in == 9 def test_quality_never_negative(): items = [Item("Standard Item", 10, 0)] gilded_rose = GildedRose(items) gilded_rose.update_quality() assert items[0].quality == 0 ``` Step 4: Step-by-Step Refactoring Refactor in small, verifiable increments. I start by extracting the logic into a separate function to reduce indentation and then move hard-coded strings into constants. Inverting Logic to Untangle Nesting One of the most powerful moves is inverting `if not` statements. By focusing on what an item **is** rather than what it **isn't**, we can flatten the logic into a clean `if/elif` chain. Implementing the Strategy Pattern Once the logic is flat, we replace the conditionals with an inheritance hierarchy. Each item type gets its own updater class. ```python from typing import Protocol class ItemUpdater(Protocol): def update_quality(self, item: Item) -> None: ... def update_sellin(self, item: Item) -> None: ... class DefaultUpdater: def update_sellin(self, item: Item): item.sell_in -= 1 def update_quality(self, item: Item): item.quality -= 1 if item.sell_in < 0: item.quality -= 1 ``` We then map these to a dictionary for easy lookup: ```python UPDATER_MAP = { "Aged Brie": AgedBrieUpdater(), "Backstage passes": BackstagePassUpdater(), "Sulfuras": SulfurasUpdater(), } ``` Step 5: Measuring Success With our new structure, adding the "Conjured" item—our original goal—becomes trivial. We simply create a new class and add it to the map. ```python class ConjuredUpdater(DefaultUpdater): def update_quality(self, item: Item): item.quality -= 2 if item.sell_in < 0: item.quality -= 2 ``` Syntax Notes * **Protocols**: We use `typing.Protocol` for structural subtyping, which defines an interface without requiring explicit inheritance in the base implementation. * **Type Annotations**: Adding types to the legacy `Item` class immediately improves IDE support and helps catch bugs during the refactor. * **Max/Min Functions**: Use `max(0, quality)` and `min(50, quality)` to keep values within bounds instead of writing multiple `if` checks. Tips & Gotchas * **Commit Often**: Commit every time your tests pass. If you break something three steps later, you can revert easily. * **Avoid AI Blindness**: GitHub Copilot is great at generating tests, but it often gets the Gilded Rose's weird logic wrong. Always verify the expected values manually. * **Don't Change the Item Class**: In the original Kata, you aren't allowed to touch the `Item` class. Use a wrapper or an updater class to work around this constraint.
Sep 1, 2023Software development is undergoing a seismic shift. While the anxiety surrounding Large Language Models is real, fighting the tide is a losing battle. The path forward involves transforming these tools into your greatest allies. These seven strategies will help you stay ahead of the curve. Lean into the Workflow Stop viewing AI as a competitor and start seeing it as a standard library for the modern era. Using GitHub Copilot to automate boilerplate code allows you to focus on high-level architectural decisions. If you aren't integrating these tools into your daily cycle, you're voluntarily working at a slower pace than the rest of the industry. Accelerate Your Learning Cycle AI is a world-class information filter. Use it to organize complex documentation or summarize new framework updates. In a job market where junior hiring is evolving, your ability to understand Prompt Engineering and system design will outweigh simple syntax knowledge. Specialize in the Complex General tasks are low-hanging fruit for AI. To secure your value, go deep into specialized domains like Cybersecurity, Blockchain, or Quantum Computing. The more niche your expertise, the more effective your AI prompts become because you actually know what to ask. Bridge the Interdisciplinary Gap Coding is only a fraction of the job. Understanding business logic, psychology, and User Experience (UX) gives you a perspective AI cannot replicate. Businesses don't just need code; they need solutions that solve human problems. Focusing on the "why" behind the software ensures you remain indispensable. Prioritize Security and Soft Skills AI creates massive privacy risks. Mastering how to handle proprietary data while using these models makes you a corporate asset. Pair that with strong leadership and empathy. Ultimately, humans hire humans because they need someone to be accountable and to communicate with stakeholders. Machines don't have skin in the game; you do.
Jul 21, 2023Overview of AI-Driven Development Modern software development moves at a breakneck pace. We often feel flooded by new tools, yet GitHub%20Copilot stands out because it minimizes context switching. Instead of bouncing between a browser and your IDE, these tools integrate directly into your workspace. This tutorial explores how to use GitHub%20Copilot for real-time code suggestions and GitHub%20Copilot%20Chat for high-level architectural guidance. Prerequisites To follow along, you need VS%20Code installed. You should have a basic understanding of Python and familiarity with pip or Poetry for package management. You also need a subscription to GitHub%20Copilot. Key Libraries & Tools * **GitHub%20Copilot**: An AI programmer that provides autocomplete-style suggestions. * **GitHub%20Copilot%20Chat**: A conversational interface inside VS%20Code for complex queries. * **Taipy**: An open-source Python library used to build data-driven web applications rapidly. * **Pytest**: A framework for writing and running unit tests. Code Walkthrough: From Logic to Tests GitHub%20Copilot excels at generating boilerplate and implementing standard algorithms. Consider a class definition where we need type annotations and standard methods: ```python from dataclasses import dataclass @dataclass class Person: name: str age: int ssn: str def print_info(self): print(f"{self.name} is {self.age} years old.") ``` While writing this, the AI suggests the `print_info` method body automatically. Once your logic is set, you can generate unit tests in a separate file. Start by typing `test_person` and let the AI fill in the assertions. However, stay sharp. AI sometimes adds too many assertions in a single test, which violates the best practice of testing one specific behavior per function. Syntax Notes and Shortcuts Efficiency comes from knowing the keybindings. Press `Tab` to accept a suggestion or `Esc` to reject it. If the first suggestion doesn't fit, use `Option + ]` (Mac) or `Alt + ]` (Windows) to cycle through alternatives. To see multiple solutions at once, `Ctrl + Enter` opens a dedicated panel with various code snippets. Practical Examples GitHub%20Copilot%20Chat acts as a sparring partner for architectural questions. You can ask it to "Set up a basic database model for a webshop using SQLAlchemy." It will generate the schema, which you can then insert directly at your cursor. It understands the context of your open files, allowing you to ask, "Convert this class into a Python data class." Tips & Gotchas AI makes mistakes. It might make private members public or fail to finish a complex block of code. Always review the logic. A great tip is to disable GitHub%20Copilot for specific file types via the `settings.json` if it becomes too intrusive during creative writing or configuration tasks.
Jun 16, 2023Mastering Your Foundation with Homebrew and System Settings Setting up a new MacBook for development starts with the foundation. I always begin by installing Homebrew, the essential package manager for macOS. It handles everything from Git to Python with a simple `brew install` command. Once the tools are present, the environment needs to feel responsive. Many developers overlook the **Keyboard** settings, but I find it vital to set the **Key Repeat** to the fastest rate and the **Delay Until Repeat** to the shortest possible duration. This small change makes navigating large codebases in VS Code significantly faster. Furthermore, I disable all auto-correction, smart quotes, and auto-capitalization. These features are helpful for prose but a nightmare for coding, as they can inadvertently corrupt ASCII characters or break syntax. Essential Productivity Tools for Workflow Efficiency Managing data and snippets is where most time is lost. I rely on Notion as a central brain for project documentation and Bitwarden for secure credential sharing across the team. For the daily grind, two small utilities change the game: Maccy and Rectangle. Maccy provides a lightweight clipboard history, allowing you to access previously copied code snippets instantly. Rectangle solves the lack of native window snapping in macOS, letting you organize your IDE and browser windows side-by-side with simple keyboard shortcuts. To save even more time, I use Rocket Typist for text expansion. Whether it is a boilerplate code block or a standard email response, typing a short abbreviation triggers a full-text replacement, removing the need for repetitive typing. Advanced Terminal and Developer Extensions For the actual coding work, the default terminal isn't enough. I swap it for iTerm2, which offers a dedicated hotkey to drop a terminal window down from the top of the screen like a gaming console. This paired with Oh My Zsh provides better visual feedback on Git branches and syntax highlighting. I have also integrated Fig, which provides IDE-style autocomplete directly in the terminal—a massive productivity boost for complex CLI commands. When I need to format data, I use DevToys, a versatile toolbox for JSON formatting, Base64 encoding, and JWT debugging. Within VS Code, I keep it lean with extensions like GitHub Copilot for AI assistance and Mermaid for rendering diagrams directly from markdown. Refining Finder for Developer Sanity Finder is often the most frustrating part of macOS if not configured correctly. I immediately change it to show the **Path Bar** and **Status Bar**, so I always know exactly where I am in the directory structure. Perhaps the most important change is the search behavior; I set Finder to search the **current folder** by default rather than the entire Mac. Finally, I change the "New Finder Window" preference to point directly to my `Development` folder. This ensures that every time I open a window, I am exactly where I need to work, rather than staring at a list of recent files.
Apr 7, 2023