diff --git a/actions/setup/js/dispatch_repository.cjs b/actions/setup/js/dispatch_repository.cjs
new file mode 100644
index 00000000000..8848d11ecb6
--- /dev/null
+++ b/actions/setup/js/dispatch_repository.cjs
@@ -0,0 +1,183 @@
+// @ts-check
+///
+
+/**
+ * @typedef {import('./types/handler-factory').HandlerFactoryFunction} HandlerFactoryFunction
+ */
+
+/** @type {string} Safe output type handled by this module */
+const HANDLER_TYPE = "dispatch_repository";
+
+const { getErrorMessage } = require("./error_helpers.cjs");
+const { createAuthenticatedGitHubClient } = require("./handler_auth.cjs");
+const { parseRepoSlug, validateTargetRepo, parseAllowedRepos } = require("./repo_helpers.cjs");
+const { logStagedPreviewInfo } = require("./staged_preview.cjs");
+const { isStagedMode } = require("./safe_output_helpers.cjs");
+
+/**
+ * Main handler factory for dispatch_repository
+ * Returns a message handler function that processes individual dispatch_repository messages
+ * @type {HandlerFactoryFunction}
+ */
+async function main(config = {}) {
+ const tools = config.tools || {};
+ const githubClient = await createAuthenticatedGitHubClient(config);
+ const isStaged = isStagedMode(config);
+
+ const contextRepoSlug = `${context.repo.owner}/${context.repo.repo}`;
+ core.info(`dispatch_repository handler initialized: tools=${Object.keys(tools).join(", ")}, context_repo=${contextRepoSlug}`);
+
+ // Per-tool dispatch counters for max enforcement
+ /** @type {Record} */
+ const dispatchCounts = {};
+
+ /**
+ * Message handler function that processes a single dispatch_repository message
+ * @param {Object} message - The dispatch_repository message to process
+ * @param {Object} resolvedTemporaryIds - Map of temporary IDs to resolved values
+ * @returns {Promise