Claude-skill-registry custom-global-events

Guidelines for creating/using the app’s typed global events system.

install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/custom-global-events" ~/.claude/skills/majiayu000-claude-skill-registry-custom-global-events && rm -rf "$T"
manifest: skills/data/custom-global-events/SKILL.md
source content

Overview

Global events are used for cross-component communication without React context dependencies, allowing for simple function calls to trigger events across different parts of the application.

Global Events Guidelines

Global events are used for cross-component communication without React context dependencies, allowing for simple function calls to trigger events across different parts of the application.

Overview

The global events system lives at global-event.tsx and is built on a typed

Event
subclass (
XCustomEvent
).

It exposes:

  • global_event_Event
    : the canonical type map of event keys →
    detail
    payload types
  • global_event_dispatch(event, payload)
    : dispatch a typed event (works outside React)
  • global_event_listen(event, handler, options?)
    : listen with typed handler (works outside React)
  • useGlobalEvent(event, handler)
    : React hook for subscriptions with stale-closure protection

Event key naming

Event keys are string literals using the pattern:

(

module::event_name
), for example
ai_chat::open_canvas
.

How to add or modify an event

When the user requests a new global event, you must:

Update the event map

Add the new event key to the

global_event_Event
map in global-event.tsx.

Example:

export class global_event_Event extends XCustomEvent<{
	"ai_chat::open_canvas": {
		pageId: app_convex_Id<"pages">;
		mode: "diff" | "editor";
		modifiedContent?: string;
		threadId: string;
	};
	"ai_chat::open_canvas_by_path": {
		path: string;
	};
	"docs::focus_path": {
		path: string;
	};
}> {}

Keep all event keys centralized

All supported global event keys must be declared in that

global_event_Event
type map. Do not introduce ad-hoc stringly-typed events elsewhere.

Use the exported helpers

Prefer

global_event_dispatch
/
global_event_listen
/
useGlobalEvent
rather than calling
window.dispatchEvent(new CustomEvent(...))
directly.

Usage patterns

React components

Use

useGlobalEvent(eventName, handler)
to subscribe. The handler receives a typed event object, and the payload is on
event.detail
.

Example (from canvas.tsx):

useGlobalEvent("ai_chat::open_canvas", (e) => {
	const payload = e.detail;
	// payload.pageId, payload.mode, payload.modifiedContent, payload.threadId
});

Non-React code (or manual lifecycle control)

Use

global_event_listen
directly when you need to wire AbortController, or you are outside React.

const controller = new AbortController();

const cleanup = global_event_listen(
	"ai_chat::open_canvas_by_path",
	(e) => {
		console.info("path:", e.detail.path);
	},
	{ signal: controller.signal },
);

// later:
controller.abort();
cleanup();

Dispatching

Use

global_event_dispatch(eventName, payload)
from anywhere client-side.

Example (from app-ai-chat.tsx):

global_event_dispatch("ai_chat::open_canvas_by_path", { path: args.path });

Handler typing and payload access

Handlers receive the typed event object, not the payload directly:

useGlobalEvent("ai_chat::open_canvas", (e) => {
	const payload = e.detail;
});

Files and references