Hardcoding command logic and prompts directly into your script makes it rigid and difficult to extend. This lesson demonstrates a more flexible and powerful pattern: defining your script's commands as individual Markdown files in a dedicated directory.
This approach allows you to easily add, remove, or modify commands without touching the core script logic. You'll learn how to dynamically load these command files, present them as options to the AI, and inject the corresponding instructions into your prompt, creating a truly modular and extensible tool.
Workflow demonstrated in this lesson:
commands directory to house your command definitions (e.g., summarize.md, translate.md).globby to discover all available command files at runtime.commandMap that maps the filename (e.g., "summarize") to its file content.enum of the dynamically discovered command names.profile.md file to demonstrate how the script can act on user-created content with the new file-based commands.By the end of this lesson, your script will be architected for easy expansion, allowing you to build a robust library of custom commands simply by adding new text files.
[00:00] To make our commands more flexible and more powerful let's take out summarize and translate from here. And I'm going to create a new file in a commands directory called summarize.md. And we'll just put in please summarize the following content to a single sentence. Then we can also create a translate command. We'll call it translate.
[00:21] Please translate the following content into French. And then back in our index file we can load in our commands directory, and since we're already using globby we'll just go ahead and use that. I'm going to rename commands to command file paths since this is an array of the relative path to the files. Then we'll create a command map where we can just map the command name to the file path. And I love writing comments like this because code suggestions can usually infer what you want to do next.
[00:51] So I'll hit tab. I actually don't necessarily like this way of grabbing the command name from a path since there are path tools where if we import path we can parse this and just get the .name and .name returns the file name without the extension, which is exactly what we need. So then down in our command string, tab is suggesting an enum. We still don't want to do an enum, but we do want to do this command map keys and then join them with a comma. So it'll just look like summarize comma translate.
[01:21] And then based on the selected command, we're gonna go ahead and drop in instructions and let the command map get the instructions based on the command that was inferred from the AI. So now in my terminal, if I run bun index, create a summary of my package file, then I'll let this run. It was able to find the package.json. It was able to infer that create a summary meant to summarize, which then pulled in my summary instructions and injected them into my text prompt. So the final action was to generate this text.
[01:55] So let's also try translate while we're here. Please translate my TypeScript file. We'll just see what happens when it tries to translate a TS config to French. So if we expand this it looks like it just gave up on the task because it was JSON and no translation was needed. Let's add in some more demo files based on our blobby pattern here.
[02:13] So instead of JSON files let's add some just markdown files in the root of the project and we can create another markdown file in the workspace root. We'll call this my profile. My name is John Lindquist and I'm a software developer. So we'll drop down here, find index, Please translate my profile, and then it gives me my profile in French.