{"slug": "agentic-software-factory-in-action", "title": "Agentic Software Factory, In Action", "summary": "Software engineer Konstantin Gredeskoul released agentilda-ai-setup, a GitHub repository that installs coding agents, skills, and plugins from a single configuration.yml file into ~/.agents and auto-symlinks them into ~/.claude. The tool addresses the absence of standard package managers for agent plugins and skills by letting users declare GitHub repos and filter skills with include_skills and exclude_skills regular expressions, and its installer also installs the author's two companion repositories. Gredeskoul wrote that \"there are no standard package managers yet for plugins, skills, commands, scripts, and so on\" and that the setup repo is \"perhaps the most important one of the three.", "body_md": "[// AI](https://kig.re/categories/AI)\n\n# Agentic Software Factory, In Action\n\nThere is a particular flavor of sadness that comes from sitting down at your laptop instead of your desktop and discovering that half your skills are missing, your slash commands do not exist, and the agent you just asked to do a thing has never heard of the thing.\n\nI had that problem for months. My `~/.claude` folder was a museum: skills installed by hand in February from a repo I could no longer name, plugins that somebody on Twitter recommended, a `CLAUDE.md` that had drifted apart on three machines like continents. Every new computer was an archaeology project.\n\nSo I did what any reasonable person does after the third archaeology project. I wrote three repos.\n\n## The problem is not the agents, it’s the sameness\n\nClaude Code is great. Codex is fine. Cursor does things. That is not where the pain is. The pain is that a coding agent is only as good as the context it loads, and the context lives in a pile of dotfiles that no package manager owns.\n\nIMPORTANT\n\nThere are no standard package managers yet for plugins, skills, commands, scripts, and so on. Everyone is winging it. So this is my version of winging it, although it is perhaps quite rigorous and consistent in it’s design and implementation.\n\nNobody publishes `my-skills-as-of-tuesday` to a registry. You clone a repo, you copy a folder, you forget where it came from, and six weeks later the skill is stale and there is no way to tell which upstream it drifted from. Multiply by two laptops and a desktop.\n\nWhat I wanted was boring: one file that declares what my agentic environment is, and one command that makes any machine look like that.\n\n## Repo I: `agentilda-ai-setup`\n\nIMPORTANT\n\nThis repo, is, perhaps, the most important one of the three. This is because if you run it’s installer, it will also install the other two gems I talk about below. Together with the consistent set of skills, plugins, coding agents, and the global AGENTS.md and CLAUDE.md. To have it be your way, just fork the repo, make your own changes, and run it on any new computer you plan to do AI-assisted development. It’s that simple.\n\n[`agentilda-ai-setup`](https://github.com/kigster/agentilda-ai-setup) is the boring one, which means it’s the one that actually solves the problem.\n\nIt has a crucial file: **[`configuration.yml`](https://github.com/kigster/agentilda-ai-setup/blob/main/configuration.example.yml)**. The file lists which coding agents you want installed (with the vendor’s own install line, because I am not in the business of reimplementing `npm i -g`), which extra executables should be on PATH, and then any number of GitHub repos to pull skills and plugins from.\n\n```\n  - name: pstack\n    type: plugin\n    repo: git@github.com:cursor/plugins.git\n    path: pstack\n    include_skills: /\\A(architect|unslop|why)\\z/\n    exclude_skills: /\\A(architect-slop)\\z/\n```\n\nThat last line is the part I use constantly. Most skill repos ship forty skills and I want three. Regular expression, matched against the name the skill installs as, done. There is `exclude_skills` too, and the same pair for plugins, and an `agents:` key so a Claude-only source never gets installed for an agent that cannot read it.\n\nAs you can see, I added the `exclude_skills` above for demonstration purposes, but of course in this case it is completely unnecessary.\n\nNOTE\n\nIf you haven’t checked out the Cursor’s `/unslop` skill, you really should. It turns the wall of text that Claude likes to overwhelm you with into a much more structured bullet-point format that’s way easier to read.\n\nThen you simply run:\n\n```\nbin/install\n```\n\nYou run the installer. This installs everything into `~/.agents`,\ndoes not overwrite anything unless you pass `--force`, and auto-symlinks\nit into `~/.claude` so all the skills are available to all agents, Claude included.\nPlugins are a bit of a more proprietary story, but if you look how the TypeSafe Jev\nplugin is installed, once for claude, once for the rest of the agents, you can see\nthe flexibility this offers.\n\nThree steps happen. `scripts/install-sources` builds `skills/` and `plugins/` in the checkout from the config. `bin/install` copies that into `~/.agents` with every symlink resolved, so `~/.agents` holds real files. `bin/setup` links `~/.agents` into `~/.claude`.\n\nNothing under `skills/` or `plugins/` is committed. They are fully regenerable from the config, which is the whole idea. The moment a skill exists in git with no record of where it came from, you are back in the museum.\n\nMy favorite property: tightening a filter takes skills *away*. Next run unlinks whatever it installed last time and no longer wants. The tree converges on what the file says instead of accumulating like a Downloads folder.\n\n### My Own skills\n\nThe repo has a folder `src/skills` which contains skills I wrote myself. At some point I’ll move them to a standalone repo that’s installed the same way every other repo is. But for the time being, my own creations live with the repo and get installed together with the rest of the stuff defined in the `configuration.yml`\n\nDeliberate trade: editing `src/skills/foo` does not reach `~/.claude` until you run install again. Installed tree that keeps, rather than a live symlink into a checkout you might rename on a Tuesday.\n\n## Repo II: `agentilda`, or the part that does the work\n\nThey say “picture is worth a thousand words” so here it is, in action:\n\nNOTE\n\nThe screenshot above is `tilda run` with agents working on two plans at once. Left plan has backend and frontend both building. Right plan is still at research. Nobody is merging anything, which is the point.\n\n[`agentilda`](https://github.com/kigster/agentilda) is a Ruby gem with one command, installed as both `agentilda` and `tilda`. It has a [ratatui](https://github.com/kigster/ratatui_ruby)-based dashboard, which is a Rust extension, which means installing it needs `cargo` and `clang`. Sorry. It looks good though.\n\nWhat it actually does is manage a `.plans` folder and drive a team of specialist agents over it. You write a short brief. Seven agents research it, spec it, plan it, build it, review it. You merge. They never merge.\n\nThe folder name is the state, which sounds like a gimmick until you have used it for a week:\n\n```\n.plans/000.00-✅ → dev-foundation\n       001.00-🟡 → tenancy-households\n       002.00-⚪️ → tax-rule-dsl\n```\n\nNumber is permanent, branches and PR titles join on it. Emoji is the state. And a folder may only claim a state its files can prove: no `plan.md`, no ⭐️. Agents lie about having finished things. Disk does not.\n\nThe cast, roughly:\n\n| Agent | Does | \n|---|---|\n| `leah-researcher` | researches the brief in parallel, appends a Research chapter | \n| `yoda-writer` | writes the real spec, or `blocked.md` when a human has to decide | \n| `palpatine-planner` | splits the spec into independently buildable work units | \n| `luke-backend` | data, domain, API, tests | \n| `rey-frontend` | the interface against Luke’s API, and proof the halves fit | \n| `hansolo-reviewer` | reviews the diff against the plan, rejects at most twice | \n| `lando-broker` | folds your answers to blocked questions back into spec and plan | \n\nYes, the names are what you think they are. No, I will not be taking questions.\n\nLuke and Rey work at the same time, in the same worktree, toward one PR, and talk to each other through a `mailbox.md`. Which is exactly the situation that requires repo three, so hold that thought.\n\nTwo safety rails matter more than the rest. **Agents cannot publish.** They write source, tests and their plan documents, and that is it. The tool withholds git commands from them and then checks afterwards that `HEAD` did not move, because trusting an agent’s own report about whether it committed is how you end up with a very confident pile of nothing. The harness commits, pushes and opens the PR. And every command that writes is a dry run until you add `--commit`.\n\n```\ntilda create tax rule dsl      # writes the brief skeleton, opens it\ntilda run                      # who would take what, touching nothing\ntilda run --commit -j 4        # four agents at a time, worktree each\ntilda list-plans               # state and PRs for everything\n```\n\nWhen an agent crashes, times out, or you press `q`, it writes a `RESUME:` note into the plan’s mailbox and signs itself `Interrupted`. Every agent reads its mail before starting. A later run picks up instead of redoing fifteen minutes of research you already paid for.\n\n## What it looks like with a dozen plans at once\n\nTalking about it is cheap, so I recorded one. The repo started with twelve plan folders under `.plans`, and each held only a `spec.md`. No `plan.md`, no code, no pull requests. A few specs already had Leah’s research chapter appended from an earlier run, and two were already parked waiting on me. Then I ran `tilda run --commit` and went to make tea.\n\nIt opens with `tilda list-plans`, so you can see the starting line. What follows is every plan getting its own dedicated agent in its own worktree. Leah researches and signs off, and the harness hands the folder to Yoda. Yoda writes the real spec and passes to Palpatine, who plans and passes to Luke and Rey, and so on down the line. Some of them spin up their own sub-agents for parallel research or to split a build, which is exactly where `alock` earns its keep (more on that below). Each row in the dashboard is one agent on one plan, with its last few status lines underneath, newest first.\n\nIt went on for about thirty five minutes of wall clock and **141 million tokens**, at which point every remaining agent died with `You've hit your session limit` and the factory went quiet in the middle of a shift. Very realistic, actually. Real factories also stop when nobody pays the electricity bill. The recording ends with the harness listing which agents got cut off, and a box saying six plans need a human decision, with the exact `tilda unblock` command to run once I answer them.\n\nBut the project moved forward a lot. Here’s `.plans` afterwards:\n\nSix plans are 🟡 **Building**: they made it through research, spec and planning, and Luke and Rey are writing code. The other six are ⭕️ **Technical Block**, which means an agent hit a question it had no business answering on its own and wrote it into `blocked.md` instead of guessing. Honestly, that is my favorite part of the screenshot. An agent that stops and asks is worth ten that confidently invent your architecture.\n\nTo unstick those, I write my answers into each `blocked.md` and run `tilda unblock 008 --commit`. Lando folds the answers back into spec and plan, and the folder returns to ⭐️ Planned for the next run.\n\n`agentilda-state.json` next to the folders is the run’s bookkeeping: process ids, token counts, who was doing what when everything stopped. It’s git-ignored, and it is how the next `tilda run` picks up where this one died instead of starting over.\n\n### What the emoji mean\n\nEvery emoji in a folder name is a state, and every arrow is a handover from one agent to the next:\n\nTop to bottom:\n\n- ⚪️ **New** : you wrote a brief in`spec.md` . Leah picks it up.\n- 🔎 **Researched** : Leah appended her research chapter. Yoda picks it up.\n- 📋 **Ready for Planning** : Yoda wrote the full spec, with goals, non-goals and scope. Palpatine picks it up.\n- ⭐️ **Planned** : Palpatine split it into work units in`plan.md` . Luke starts.\n- 🟡 **Building** : Luke is on the backend. When he is done and Rey is still working on the frontend, it becomes 🎨**Building UI** . Whichever of the two finishes last moves the plan on.\n- 🟢 **Ready for Review** : a PR exists. Han Solo starts reviewing, and the folder becomes 👀**In Review** .\n- 🔴 **Changes Requested** : Han rejected it, so Luke and Rey go back to 🟡 and fix it. He rejects at most twice.\n- ✅ **Approved & Merged** : only a human gets to draw the last arrow. It says so right on the diagram.\n\nThe blocked states (⭕️ technical, 🅱️ product) are not on the diagram because they are off the main road: any agent can park a plan there, and only you can get it back out. Same for the endings nobody wants, like 💩 Scrapped by Review and ❌ Discarded.\n\nThe important part is that no agent ever renames a folder. It signs the document it owns with `Completed`, `Blocked` or `Interrupted`, and the harness checks that the files the next state requires actually exist before it moves anything. So when you see 🟡 in that screenshot, it’s not an agent’s opinion. It’s a `plan.md` on disk.\n\n## Repo III: `agent-lock`, the least glamorous, but no less important one\n\nHere is the thing nobody tells you about running several agents in one checkout: git will not save you.\n\nTwo agents on one branch and one working tree do not produce a merge conflict. There is nothing to conflict. The second writer just wins, the first one’s work is gone, and no error appears anywhere. You find out later, from a file that is mysteriously shorter than you remember.\n\n[`agent-lock`](https://github.com/kigster/agent-lock) ships `alock`, which is advisory locking on globs:\n\n```\nalock acquire \"lib/billing/**\" \"rewriting the invoices\"\nalock check   \"lib/billing/tax.rb\"\nalock note    \"lib/billing/**\" \"totals done, specs red\"\nalock release-all\n```\n\nA refusal tells you who, since when, and what they are doing, not merely that you lost:\n\n``` bash\n$ alock acquire lib/billing/tax.rb\nREFUSED, do not write here\nHELD  lib/billing/**  by luke-backend  since 2026-09-09T21:04:11Z\n      intent: rewriting the invoices\n```\n\nThe lock is a markdown document with frontmatter and a progress log, not a flag file. Agent that runs into one learns enough to decide whether to wait or go elsewhere. Human that runs into one can open it in an editor.\n\nLocks live in `$(git rev-parse --git-common-dir)/agent-locks`, which is a quietly excellent choice: git cannot track it, `git clean -xdf` cannot reach it, every worktree resolves to the same store, and it dies with the checkout instead of accumulating in your home directory forever.\n\nThe hard part was never the locking. It was **identity**. An agent harness runs every command in a brand new shell, so `export AGENT_ID=...` from the previous call is gone. Worse, Claude Code runs sub-agents inside the parent’s own process and sets nothing that tells them apart, so by default all eight of your sub-agents share one fingerprint, sign every lock as the parent, and block absolutely nobody.\n\nSo a sub-agent names itself on every single call:\n\n```\nAGENT_ID=luke-backend alock acquire lib/billing/** \"invoices\"\n```\n\nAnd the model is a family rather than a single holder. Your parent’s scope does not block you; you claim something narrower inside it, and *that* is what keeps your siblings out. Your own `release-all` takes your locks and your children’s, never your parent’s. Asking for exactly your parent’s scope is refused, since that leaves nothing for a sibling to be excluded from.\n\nCrash handling has a detail I like. When a holder is provably dead, a lock with no notes is deleted, because there is nothing to come back to. A lock *with* notes is orphaned instead: claim void, record kept, and `acquire` refuses to silently paper over it.\n\n``` bash\n$ alock acquire workflow/**\nINTERRUPTED WORK on workflow/**, left by luke-backend\n  alock resume workflow/**   # take it back, notes and all\n  alock break workflow/**    # throw it away and start over\n```\n\nBackend is Redis if one answers locally, file system otherwise. Choice is recorded once in a marker file and every later process in that tree is bound to it, claimed atomically with `O_CREAT|O_EXCL`. Because the genuinely dangerous failure is not “no lock”, it is two agents taking locks in two different stores, seeing nothing of each other, and both reporting success.\n\nAnd critically, the gem ships a skill that teaches agents the rules, so they live where agents read them instead of in a README nobody loads. Advisory locks only work because everybody checks.\n\n## The part I actually care about\n\nAny of these three alone is a moderately useful utility. Together they are the thing I wanted: a machine I can hand a config file and get my exact working environment back, a workflow that turns a paragraph into reviewed PRs across any repo, and enough coordination that running eight agents at once is a Tuesday rather than an incident.\n\nThe honest caveats. It is my setup, opinionated in ways that are about my taste and not a law of nature. The `.plans` emoji naming makes shell quoting mandatory, forever. Ratatui needs a Rust toolchain. And the agents still produce PRs that need real review, which is precisely why nothing merges itself.\n\nI wrote a bit before about [condensing twenty years of opinions into one markdown file](https://kig.re/2026/08/19/condensing-twenty-years-of-wisdom-in-one-markdown.html). This is the sequel: making sure that file, and everything around it, is the same on every machine I sit down at.\n\n```\ngem install agentilda agent-lock -N\ngit clone https://github.com/kigster/agentilda-ai-setup\ncd agentilda-ai-setup && cp configuration.example.yml configuration.yml\n# read it before you run it, seriously\nbin/install --dry-run\n```\n\nAnd if you were curious about my PostgreSQL skills files, they are available to pick and choose right here:\n\nI should probably mention that these skills cross-reference each other, so you might want to grab them all to get the maximum benefit.\n\nAll three are MIT. If you run more than one agent at a time, at minimum steal `alock`. Ask me how I learned that one.", "url": "https://wpnews.pro/news/agentic-software-factory-in-action", "canonical_source": "https://kig.re/2026/09/21/one-agentic-setup-on-every-machine.html", "published_at": "2026-09-21 00:00:00+00:00", "updated_at": "2026-09-22 04:24:47.963326+00:00", "lang": "en", "topics": ["ai-agents", "ai-tools", "developer-tools", "ai-products"], "entities": ["agentilda-ai-setup", "Konstantin Gredeskoul", "GitHub", "Claude Code", "Codex", "Cursor"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/agentic-software-factory-in-action", "markdown": "https://wpnews.pro/news/agentic-software-factory-in-action.md", "text": "https://wpnews.pro/news/agentic-software-factory-in-action.txt", "jsonld": "https://wpnews.pro/news/agentic-software-factory-in-action.jsonld"}}