# Agent Frameworks Are Converging on My Janky Markdown Setup

*Mastra productized in nine days the four primitives my markdown vault has been running DIY for months.*

> Mastra shipped file-based agents, skills, schedules, and signals in nine days. My markdown vault has run all four DIY for months.

Published: 2026-07-11 · Reading time: 7 min · Tags: ai-agents, agent-frameworks, mastra, claude-code, agent-skills, file-based-agents, markdown, personal-ai-system, automation, product-management
Canonical URL: https://huytieu.com/blog/agent-frameworks-converging-on-my-markdown-setup/
Author: Huy Tieu (huytieu.com)

---

> **TL;DR** Between July 1 and July 9, [Mastra](https://mastra.ai) shipped six releases that productize the exact primitives my DIY personal agent system already runs on plain files.
>
> - Their July streak: webhook signals, browser recording, file-based agents, first-class skills, schedules, and custom signal providers. Six announcements in nine days.
> - My [markdown vault](/blog/how-i-moved-my-entire-life-to-the-terminal-building-a-personal-ai-agent-system/) has been running the same four core primitives DIY: 17 agents as markdown files, 80 skills as folders, schedules as launchd plists, signals as hooks.
> - This isn't "I did it first" bragging. It's a signal: the agent stack is standardizing, and it's standardizing on *files you can read*.
> - The durable asset isn't the framework or the model. It's the distilled know-how sitting in those files, and it ports.

File-based agents are AI agents defined entirely by folders and plain files: instructions as markdown, model config, skills, and memory as separate files in a directory. The pattern turns an agent from code you write into content you edit.

That definition matters because two very different camps just arrived at it independently. One is a venture-backed TypeScript framework. The other is me, a PM with a text editor and a mild launchd addiction.

```
[ mastra ]  >>=====[ converging ]=====<<  [ my vault ]
 TypeScript          agents = files          markdown
 framework           skills = files          + launchd
 (funded)            cron   = config         (duct tape)
                     events = signals
```

## What Mastra shipped: file-based agents, skills, schedules, signals

[Mastra](https://mastra.ai) (the TypeScript agent framework from the Gatsby folks) had a shipping streak this July that is worth reading as one artifact, not six:

- **Jul 1**: [Webhook Signals](https://mastra.ai/blog/introducing-webhook-signal-provider). "Your agents can now react to webhook events from GitHub, Slack, Stripe, or your own API."
- **Jul 2**: [Browser Recording](https://mastra.ai/blog/introducing-browser-recording). "Record and replay your agent's browser sessions."
- **Jul 3**: [File-Based Agents](https://mastra.ai/blog/introducing-file-based-agents). "Each agent is defined by a folder with model config, instructions, tools, skills, memory, and workspace as separate files."
- **Jul 7**: [First-Class Skills](https://mastra.ai/blog/introducing-first-class-skills). Skills attach directly to agents now, including as plain markdown: "The filename becomes the skill's name, and the body is the instructions." (They've had workspace-scoped skills since February; direct agent attachment is the new part.)
- **Jul 8**: [Schedules](https://mastra.ai/blog/introducing-schedules-for-agents-and-workflows). "A unified API for managing automated recurring tasks."
- **Jul 9**: [Custom Signal Providers](https://mastra.ai/blog/introducing-custom-signal-providers). "Send notification signals to your agents from any external source."

```
 six ships in nine days:
 webhook -> browser -> agents -> skills -> schedules -> signals
   jul1       jul2      jul3     jul7        jul8         jul9
```

Strip the branding and you get four primitives: **agents as folders, skills as files, schedules, and event signals.**

I stared at that list for a while, because I run all four. Not as a framework. As a pile of markdown, three launchd plists, and stubbornness.

## The same four primitives, the janky version

My whole system lives in an Obsidian vault driven by [Claude Code](https://claude.com/claude-code) from the terminal. I've written about the full setup in [my terminal-first life post](/blog/how-i-moved-my-entire-life-to-the-terminal-building-a-personal-ai-agent-system/) and about why the harness matters more than the model in [Scaling the Harness](/blog/scaling-the-harness/). Here's the primitive-by-primitive mapping, with real counts from tonight:

```
 primitive        mastra ships              my vault runs
 --------------   ----------------------    --------------------------
 agents           folder per agent w/       17 agents, one .md each
                  config, instructions,     (frontmatter = config,
                  tools, skills, memory     body = instructions)

 skills           createSkill() or .md,     80 skill folders,
                  filename = name,          SKILL.md + scripts,
                  body = instructions      invoked by name

 schedules        unified schedule API,     3 launchd plists; the
                  cron for agents +         content factory wakes
                  workflows                 4x a night

 signals          webhook + custom          hooks + stop-hooks
                  providers, wake idle      (the honest gap, see
                  agents on events          below)
```

### Agents as folders

Mastra: a `weather-agent/` directory with `config.ts` and `instructions.md`. My version: `.claude/agents/task-verifier.md`, where YAML frontmatter declares the model and tools, and the markdown body is the job description. Same idea, one file fewer. When I want a new specialist (a read-only verifier, a fix agent, a harvest curator), I write a markdown file. Nobody compiles anything.

### Skills as markdown

This is the one where I have receipts. Mastra's pitch is that the filename becomes the skill's name and the body becomes the instructions. My `.claude/skills/` directory has 80 of those folders, and the interesting discovery of the last few months was how far a distilled skill stretches: I ran an experiment where a frontier model explores a web app once, distills what it learned into a skill file, and then a small, cheap model (Haiku) executes tests against that app using just the skill. Cost per test run: about $0.11. The know-how lives in the file, not in the model. That's the same bet Mastra is now making with downloadable packaged skills.

```
 explore once          distill              execute forever
 (big model)     ->    SKILL.md       ->    (small model, $0.11/test)
   slow, pricey          the asset            fast, cheap, repeatable
```

### Schedules

Mastra unified scheduling into one API. My version is launchd plists that wake Claude Code sessions on a calendar: the content factory (the pipeline that scouted the news this post is about) fires at 21:07, 23:37, 02:07, and 04:47 every night, a shorts pipeline runs at 10:37, and a vault sync tidies up daily. It's crude. It also hasn't missed a night.

```
 21:07 --- 23:37 --- 02:07 --- 04:47
   |          |          |          |
 wake       wake       wake       wake
 (launchd plists, not Mastra's API, four times a night regardless)
```

Full disclosure for the fun of it: this very post was produced by that scheduled pipeline. A cron-woken agent read Mastra's schedules announcement and wrote a blog post about how it, too, is a cron-woken agent. The snake is well fed.

### Signals: the honest gap

Here's where the DIY version is genuinely behind. Mastra's signal providers let an idle agent get woken by an external event: a GitHub push, a Slack message, a Stripe webhook, a Postgres NOTIFY. My closest equivalents are lifecycle hooks (things that fire when an agent session starts or stops) and polling on a schedule. Waking on real external events is the piece I'd steal first. Polling every few hours is a mediocre substitute for "react when it happens", and I feel that gap every time news breaks at 9am and my factory notices at 21:07.

```
 mastra (signals):   9am event --wake--> agent reacts now
 my vault (polling): 9am event ..................... 21:07 catches up
                                          ^ 12 hours of not knowing yet
```

## The PM lens: the stack is standardizing on readable files

I'm a product manager, so I can't not read this as a market signal. When independent builders' duct tape and funded frameworks' roadmaps converge on the same four primitives, that's usually the moment a stack is standardizing. We watched web frameworks do this: everyone eventually agreed on routing, components, and build steps, and the differentiation moved up a layer.

The layer it moves to, I think, is the content of the files. If agents, skills, and schedules become commodity primitives in every framework, then the durable, compounding asset is the distilled know-how you've written into those files: your skills, your playbooks, your verification workflows. Mine took months of [giving my agent real jobs](/blog/i-gave-claude-code-my-qa-job/) to accumulate, and the practices transfer even when the harness changes. Files port. Frameworks rotate.

```
 +------------------------------+
 |  your know-how (the asset)   |  <- differentiation lives here now
 +------------------------------+
 |  agents / skills / schedules |  <- commodity layer, everyone ships it
 |  / signals as primitives     |
 +------------------------------+
```

That's also the quiet argument for keeping everything in plain text you can read. When the primitive is a markdown file, migration is a copy-paste, audit is a read, and version control is git. Try that with know-how baked into a fine-tune.

## What I'd actually steal from Mastra

Adopting ideas only when they beat what I run is a house rule, so, scored honestly:

1. **Custom signal providers**: clear win, closes my biggest gap (event-driven wake instead of polling).
2. **Traced scheduled runs**: their scheduled runs are traceable spans; my night runs log to a TSV ledger and a markdown run log. Theirs is better observability, mine is more readable at 7am. Partial steal.
3. **Packaged, downloadable skills**: the distribution story is the interesting part. A skills registry could do for agent know-how what npm did for code. Watching this one closely.

```
 signal providers    [x] steal    closes the polling gap
 traced runs         [~] partial  mine's a tsv ledger, theirs is spans
 packaged skills      [ ] watch   registry idea, not stealing yet
```

## FAQ

**What are file-based agents?**
AI agents defined by a directory of plain files instead of code: instructions in markdown, model config, skills, and memory as separate files. Mastra shipped them on July 3, 2026; Claude Code has used markdown-defined subagents for a while.

**Are markdown skills better than fine-tuning for domain knowledge?**
For most workflow knowledge, in my experience, yes: skills are inspectable, versionable, portable across models, and editable in seconds. My skill-based testing experiment ran at roughly $0.11 per test with a small model executing a skill a frontier model distilled once.

**Do I need an agent framework to run scheduled agents?**
No. Any scheduler that can start an agent session works; my setup uses macOS launchd plists to wake Claude Code four times a night. A framework earns its keep when you need traced runs, retries, and event-driven signals without building them yourself.

**What's the difference between a skill and a tool?**
A tool (like an MCP server) gives an agent a capability: an API it can call. A skill gives it know-how: instructions for when and how to use its capabilities on a specific job. Tools are verbs, skills are recipes.

## Sources

- [Introducing File-Based Agents for Mastra](https://mastra.ai/blog/introducing-file-based-agents) (Jul 3, 2026)
- [Introducing First-Class Skills for Mastra Agents](https://mastra.ai/blog/introducing-first-class-skills) (Jul 7, 2026)
- [Introducing Schedules for Mastra Agents and Workflows](https://mastra.ai/blog/introducing-schedules-for-agents-and-workflows) (Jul 8, 2026)
- [Introducing Custom Signal Providers for Mastra Agents](https://mastra.ai/blog/introducing-custom-signal-providers) (Jul 9, 2026)
- [Introducing Webhook Signals](https://mastra.ai/blog/introducing-webhook-signal-provider) (Jul 1, 2026) and [Browser Recording](https://mastra.ai/blog/introducing-browser-recording) (Jul 2, 2026)
