Introducing Selector Forge: an AI selector builder for the browser
Add Selector Forge to Chrome, or browse the source on GitHub.
We build Intuned, and at its core is a coding agent that writes and maintains browser automations. The code it writes is good. The selectors were the weak spot, and not in the way you'd expect. They looked right. A bad selector and a good one are nearly identical on the page; the difference only shows up later, when one of them quietly starts matching the wrong element. The agent couldn't see that coming any better than a person can.
And fixing them was no easier. The error was clear (sometimes), but agents in general can't land on a working selector without rounds of trial and error against the page, each test another tool call piling useless output into their context.
Better prompting barely helped, because writing automation code and picking a reliable selector are two different jobs. So we split them: the agent decides what it wants to grab, and a separate tool decides how to grab it. That tool is now the AI engine behind Selector Forge, a browser extension. Point it at an element and you get a selector built on the rules below, applied for you instead of by hand.
What we taught it to look for
DevTools' Copy Selector and the pickers on the Chrome Store all work the same way: walk up the page and grab whatever's there. They can't tell a meaningful anchor from a throwaway one, so they keep everything:
#block-symsoft-content > div > main > div.field.field--name-dynamic-block-fieldnode-solicitation-fields-block.field--type-ds.field--label-hidden.field__item > div > div > div > div > div > div > div > dl > div:nth-child(1) > ddWhat bit us most was the throwaway stuff baked right in: a random id like widget-12i4a3, or styling classes like .flex, .text-12, .font-bold, the Tailwind soup that's all over the modern web. Those describe how the element looked the day you clicked it, not what it is. The next deploy changes the id, a restyle drops the class, and the selector is dead while the element hasn't moved an inch.
A good selector keeps only what means something:
Anchor to what a human chose. data-testid="login-button" is real; widget-12i4a3 is generated and .font-bold is decoration. Telling them apart is most of the job.
Anchor to the label and you can trust the result. This is the one I care about most. That element above sits next to a label that says "Solicitation Type," so anchor to the label:
//dt[normalize-space()='Solicitation Type']/following-sibling::ddNow I know what comes out: the value beside "Solicitation Type," not "whatever's in the first row today." The old version still returns something after the page changes, just the wrong thing, with no warning. This one returns the right value or nothing at all. When you're feeding data somewhere, that's the whole point.
Keep it minimal. No positions, no long chains, no extra classes. On Hacker News the right selector for a story link is just .titleline > a, buried in the nine-hop chain Copy Selector gives you.
Make it work across pages. A selector for "the price" should work on every product page, not the one you're on. Check it against a few, which is also what makes lists work: pick one item and the question becomes "what do these have in common," not "what positions were they in today."
Those four are the whole job, and they're exactly what Selector Forge does on every pick, using AI.
From internal tool to extension
The engine fixed the agent. Our Forward Deployed Engineers, the ones building customer automations every day, saw it working there and asked for it themselves, so we wrapped it in a small extension. They know what a reliable selector is worth, and it became their first move whenever they work a page directly: debugging a run, scoping a new site, checking a case the agent flagged. That's when we decided to ship it.
Where this is useful (and where it's going)
Reliable selectors matter anywhere you drive a browser instead of calling an API. Scraping is the obvious case, but it's the same job when you build an integration on a service that has no API, wrap an old internal tool as a clean endpoint, or automate something a vendor never exposed. Turning sites into APIs is most of what we do at Intuned. It helps with tests that shouldn't break on a refactor, and even with CSS, for styling pages you don't control. In all of them, quietly grabbing the wrong element is the nightmare, and a selector you trust is the fix.
The use we're most excited about is the one that started this: coding agents. Selectors are how an agent holds onto the web, and every coding agent writing browser automation today is doing it the way ours used to. A lot of that happens locally — people writing and running these automations on their own machines — so we're bringing Selector Forge to that world: a CLI that lets your agent ask a real browser for a reliable selector instead of guessing from a snapshot, alongside tools like agent-browser and browser-harness. More on that soon.
Selector Forge
Pick an element, get a selector you can build on. Pick one item, get the whole list. Free, open source, available for Chrome and Firefox. Every selector in this post is real, unedited output.
Add it to Chrome, or check out the source at github.com/Intuned/selector-forge.