Plugins

Custom Plugin

Build a custom Plugin with Actions, Hooks, System, Lifecycle, and a City module.

Custom Plugin

Custom Plugin contracts come from @downcity/city/plugin. City owns one Plugin instance per Plugin ID and automatically exposes every registered Plugin to every Agent.

import {
  Plugin,
  create_action,
} from "@downcity/city/plugin";

class NotesPlugin extends Plugin {
  readonly name = "notes";
  readonly title = "Notes Helper";
  readonly description = "Adds note-related actions.";

  readonly actions = {
    status: create_action({
      execute: async ({ context }) => ({
        success: true,
        data: {
          workspace_path: context.workspace.path,
          storage_path: context.storage.path,
          session_id: context.session?.id ?? null,
        },
      }),
    }),
  };
}

const city = new City({ plugins: [new NotesPlugin()], workspaces: [workspace] });
city.agents.add(agent);

Implement only the Actions, Hooks, Resolves, System, Availability, HTTP, or Lifecycle behavior the domain actually needs. Use initialize/dispose for Plugin-owned resources and derive any internal resource key from real domain ownership, not Workspace entry. Do not hide long-lived resources inside Hooks.

See Plugin Development for the complete module, manifest, Context, and testing model.

Table of Contents