Semantic application runtime
Give every task its own interface.
Gruntend lets models compose typed application capabilities with JavaScript and return interactive UI. Every operation stays in app-owned handlers.
Plans are interpreted with JailJS, not eval or Function.
your.webapp.com// JavaScript plan generated by the LLM from the user's intent.
const menus = await tools.menus.list({});
const itemGroups = await Promise.all(
menus.menus.map((menu) =>
tools.menu.items.list({ menuId: menu.menuId })
)
);
const changes = itemGroups
.flatMap((group, index) =>
group.items.map((item) => ({
...item,
menuName: menus.menus[index].name,
}))
)
.filter(({ price }) => price < 10)
.map((item) => ({
...item,
nextPrice: item.price * 1.2,
}));
let message = "";
const applyChanges = async () => {
await Promise.all(changes.map((change) =>
tools.menu.item.update({
menuId: change.menuId,
itemId: change.itemId,
price: change.nextPrice,
})
));
message = `${changes.length} prices updated.`;
};
const render = () => html`<section class="price-review">
<header>
<div><small>Generated for this task</small><h2>Price review</h2></div>
<b>${changes.length} items</b>
</header>
<div class="price-list">${changes.map((change) => html`
<article>
<span><strong>${change.name}</strong><small>${change.menuName}</small></span>
<span><del>$${change.price.toFixed(2)}</del><b>$${change.nextPrice.toFixed(2)}</b></span>
</article>
`)}</div>
<footer>
<button onclick=${applyChanges}>Apply all changes</button>
<span>${message || "No mutation until confirmation"}</span>
</footer>
</section>`;
return render;$parse plan.jsready
+globals: input, tools, Promise, htmlprovided
−fetch, window, document, evalblocked
›execute interpreted JavaScriptrunning
tools.menus.list()→menus.list handler4 menustools.menu.items.list(…)→menu items handler19 itemsTruffle Fries Dinner menu$8.00$9.60
Cold Brew Drinks menu$5.00$6.00
Ginger Lemonade Drinks menu$6.00$7.20