Linkwarden is an open-source bookmark manager. People self-host it, sign in, and file links into collections. It has an API, a Prisma schema, and no idea what Vendo is.
That made it the right test. Every demo we ship was built by people who knew where the agent would go. A real install starts from the other side: someone's existing product, someone's existing auth, a workspace already full of opinions. So we forked Linkwarden and gave it an agent, the way you would give yours one.
Signed in, you click a launcher pill and ask for something the product has no page for. "Show my dead links by collection." "Tag everything I saved last week." The agent answers through Linkwarden's own API, as you, and draws the screen it needs. Nobody wrote a dead-links page. Nobody will have to.
The whole integration is four touched files and a handful of new ones. A
route, a registry, a provider in the layout, one config line, and the contract
vendo init writes. The interesting part is the walls, because your product
will have its own.
Linkwarden speaks next-auth v4, which Vendo's presets cannot read — and Vendo refuses to guess who someone is. The fix is one honest function: the host resolves its own session and hands Vendo the user.
auth: {
principal: async (request: Request) => {
const token = await getToken({ req: request as never });
if (token?.sub == null) return null;
return { kind: "user" as const, subject: `user_${token.sub}` };
},
},The workspace held two more surprises. The background worker pinned an older
ai major than Vendo needs, and the app itself runs zod 4 while half of
Vendo's packages expected their own zod 3. Both have one-line fixes now, both
are documented, and the second is filed as a bug — because a real product
found it and our own demos never could. That is the point of installing into
software you didn't write.
The fork is public. Every commit is one wall and its fix, and the diff against upstream is the entire answer to "what does Vendo touch." Start with the walkthrough, or go straight to the fork.
