Downcity
PluginsExamples

RoleResolverPlugin Scenario

Use a resolve scenario to show why some extension points must produce exactly one final answer

RoleResolverPlugin Scenario

Scenario

You want one runtime path to ask:

  • "what is this user's current role?"

That is not a collaborative transformation problem. It is a single-answer resolution problem.

That makes it a classic resolve case.

Example

import { Agent, type Plugin } from "@downcity/agent";

export const roleResolverPlugin: Plugin = {
  name: "role_resolver",
  title: "Role Resolver",
  description: "Resolves one final role for a user.",
  resolves: {
    "auth.resolve_role": async ({ value }) => {
      const body = value as { userId?: unknown };
      const userId = String(body.userId || "").trim();
      if (!userId) {
        throw new Error("userId is required");
      }
      if (userId === "owner") return "admin" as never;
      return "member" as never;
    },
  },
};

const agent = new Agent({
  id: "repo-helper",
  path: "/path/to/project",
  tools: {},
  plugins: [roleResolverPlugin],
});

const role = await agent.plugins.resolve<{ userId: string }, string>(
  "auth.resolve_role",
  { userId: "owner" },
);

Why there cannot be two resolvers

Because the semantic question is not:

  • "let several plugins each add something"

It is:

  • "who is the final authority for this answer?"

That is why duplicate resolve registration fails in the current implementation.