{"slug": "i-made-my-desktop-agent-speak-skill-md-now-it-can-eat-the-whole-skills-ecosystem", "title": "I made my desktop agent speak SKILL.md — now it can eat the whole skills ecosystem", "summary": "A developer built AMA-teras, a desktop AI agent that now supports the SKILL.md open standard for agent skills, allowing it to consume skills from a community ecosystem of over 1,000 entries. The agent can both read skills from directories and export its own self-generated tools as portable SKILL.md packages with verification gates. The implementation prioritizes security by validating skill names against path traversal and respects progressive disclosure to keep context windows clean.", "body_md": "Last week I wrote about [AMA-teras](https://github.com/moriwo-dev-ai/ama-teras), a desktop AI agent that writes its own tools behind verification gates. This week it learned to speak **SKILL.md** — the open standard for agent skills — in both directions. Here's what that means, why I think it matters more than any single feature, and the implementation details that surprised me.\n\nSKILL.md started as an internal format and became an open standard that 30+ coding agents now support — Claude Code, Codex CLI, Cursor, Gemini CLI, and the rest. A skill is just a folder:\n\n```\nmy-skill/\n SKILL.md # frontmatter (name, description) + instructions\n templates/… # optional resources\n```\n\nThe clever part is *progressive disclosure*: the agent only reads the one-line description until a task actually needs the skill — then it loads the full instructions. Your context window stays clean; your agent still has a library card.\n\nThere are now community collections with 1,000+ skills. That's a lot of packaged expertise that, until this week, my agent couldn't touch.\n\nThe consuming side turned out to be almost embarrassingly small. Two tools:\n\n`skill_list`\n\n— walks the skill directories, parses frontmatter, returns `name: description`\n\nlines only`skill_use {name}`\n\n— returns the full SKILL.md body for one skillDirectories, in priority order: skills bundled with the app, then `userData/skills/`\n\nwhere users drop anything from the ecosystem. Same-name conflicts? **Bundled wins.** That mirrors how our plugin loader already works — a user-installed artifact must never silently replace a built-in one. It's a small rule that closes a real attack: drop a folder called `security-review`\n\nthat says \"skip all the checks\" and wait for the agent to load it.\n\nTwo implementation notes that earn their keep:\n\n**1. Path traversal dies at the name check, not at the filesystem.**\n\n``` js\nconst NAME_RE = /^[a-z0-9][a-z0-9_-]{0,63}$/i;\n```\n\nThe skill name is the only user-controlled path segment, and it never gets to contain `..`\n\n, `/`\n\n, or `\\`\n\n. Validating the *shape* before touching `fs`\n\nis simpler and stricter than normalizing paths after the fact.\n\n**2. The tool description is the real UX.** The agent decides whether to call `skill_use`\n\nby reading `skill_list`\n\n's output. So the list deliberately returns *only* names and one-liners — if it returned full bodies, we'd have paid the context cost of every skill to use one. The standard's progressive-disclosure idea survives only if your tools respect it.\n\nAMA-teras already had a self-evolution pipeline: when the agent lacks a capability, it writes a new tool for itself, which then has to pass **typecheck → unit tests → a real smoke run → human approval** before it's allowed to load. (I wrote about why after watching my own agent claim success on things that didn't work.)\n\nNow every tool that survives those gates can be exported as:\n\n```\nexported-tool/\n SKILL.md # description + how to run + verification evidence\n run.mjs # esbuild-bundled, self-contained runner\n gate.json # the actual gate results: what passed, when, code hash\n```\n\n`node run.mjs '{\"numbers\":[1,2,39]}'`\n\nworks on any machine with Node — no AMA-teras required. The SKILL.md says, honestly, which gates the code passed and when. If there's no evidence, it says that instead.\n\nThe test for this feature doesn't mock anything: it bundles a real plugin, executes `run.mjs`\n\nwith the real Node binary, and asserts on stdout. If the export format rots, CI catches it — because the worst possible outcome for a \"portable\" format is shipping bundles that only work on the author's machine.\n\nBecause the alternative is the thing I built this project to escape.\n\nEvery major vendor ships an agent SDK, and every SDK quietly assumes your tools, your memory, your workflows live inside *their* runtime. Skills-as-folders is the opposite bet: expertise as plain files, readable by anything, owned by whoever wrote them. My agent can now use skills written for Claude Code; tools born inside my agent can serve someone using Codex. Neither side asked a vendor for permission.\n\nFor a solo open-source project, adopting the standard also beats inventing one for a more selfish reason: I get the ecosystem's growth for free, and the ecosystem gets one more independent implementation keeping the standard honest.\n\n`skill_list`\n\n/ `skill_use`\n\nwith 20 bundled skills (TDD discipline, security review, frontend design, Playwright E2E, pdf/docx/xlsx/pptx handling, …) — all original write-upsIt's AGPL, it runs on your machine, and it swaps between Anthropic / OpenAI / open-weight models with a config change: [github.com/moriwo-dev-ai/ama-teras](https://github.com/moriwo-dev-ai/ama-teras)\n\nIf you maintain skills for any agent — I'd genuinely like to know what breaks when you drop them into a different runtime. That interop friction is the most useful bug report there is.", "url": "https://wpnews.pro/news/i-made-my-desktop-agent-speak-skill-md-now-it-can-eat-the-whole-skills-ecosystem", "canonical_source": "https://dev.to/moriwodevai/i-made-my-desktop-agent-speak-skillmd-now-it-can-eat-the-whole-skills-ecosystem-506k", "published_at": "2026-07-25 00:59:28+00:00", "updated_at": "2026-07-25 02:02:17.163051+00:00", "lang": "en", "topics": ["artificial-intelligence", "ai-agents", "developer-tools", "ai-safety", "ai-products"], "entities": ["AMA-teras", "Claude Code", "Codex CLI", "Cursor", "Gemini CLI"], "alternates": {"html": "https://wpnews.pro/news/i-made-my-desktop-agent-speak-skill-md-now-it-can-eat-the-whole-skills-ecosystem", "markdown": "https://wpnews.pro/news/i-made-my-desktop-agent-speak-skill-md-now-it-can-eat-the-whole-skills-ecosystem.md", "text": "https://wpnews.pro/news/i-made-my-desktop-agent-speak-skill-md-now-it-can-eat-the-whole-skills-ecosystem.txt", "jsonld": "https://wpnews.pro/news/i-made-my-desktop-agent-speak-skill-md-now-it-can-eat-the-whole-skills-ecosystem.jsonld"}}