mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-12 20:42:53 +00:00
docs: document plugin scope state helpers
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
/** Channel presence and gateway startup plugin id helpers. */
|
||||
export {
|
||||
hasConfiguredChannelsForReadOnlyScope,
|
||||
hasExplicitChannelConfig,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/** Runtime shape needed to expose an active plugin channel registration. */
|
||||
export type ActiveChannelPluginRuntimeShape = {
|
||||
id?: string | null;
|
||||
meta?: {
|
||||
@@ -16,12 +17,14 @@ export type ActiveChannelPluginRuntimeShape = {
|
||||
} | null;
|
||||
};
|
||||
|
||||
/** Active channel registration with owning plugin metadata. */
|
||||
export type ActivePluginChannelRegistration = {
|
||||
plugin: ActiveChannelPluginRuntimeShape;
|
||||
pluginId?: string | null;
|
||||
origin?: string | null;
|
||||
};
|
||||
|
||||
/** Active runtime channel registry snapshot. */
|
||||
export type ActivePluginChannelRegistry = {
|
||||
channels: ActivePluginChannelRegistration[];
|
||||
};
|
||||
|
||||
@@ -7,10 +7,12 @@ import {
|
||||
} from "../infra/install-safe-path.js";
|
||||
import { resolveConfigDir, resolveUserPath } from "../utils.js";
|
||||
|
||||
/** Encodes arbitrary input as a safe plugin install filename. */
|
||||
export function safePluginInstallFileName(input: string): string {
|
||||
return safeDirName(input);
|
||||
}
|
||||
|
||||
/** Encodes a plugin id for use as an install directory name. */
|
||||
export function encodePluginInstallDirName(pluginId: string): string {
|
||||
const trimmed = pluginId.trim();
|
||||
if (!trimmed.includes("/")) {
|
||||
@@ -21,6 +23,7 @@ export function encodePluginInstallDirName(pluginId: string): string {
|
||||
return `@${safePathSegmentHashed(trimmed)}`;
|
||||
}
|
||||
|
||||
/** Validates a plugin id for install path safety. */
|
||||
export function validatePluginId(pluginId: string): string | null {
|
||||
const trimmed = pluginId.trim();
|
||||
if (!trimmed) {
|
||||
@@ -51,6 +54,7 @@ export function validatePluginId(pluginId: string): string | null {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Checks whether an installed plugin id matches the expected id, including old npm keying. */
|
||||
export function matchesExpectedPluginId(params: {
|
||||
expectedPluginId?: string;
|
||||
pluginId: string;
|
||||
@@ -73,6 +77,7 @@ export function matchesExpectedPluginId(params: {
|
||||
);
|
||||
}
|
||||
|
||||
/** Resolves the default directory for path-installed plugin extensions. */
|
||||
export function resolveDefaultPluginExtensionsDir(
|
||||
env: NodeJS.ProcessEnv = process.env,
|
||||
homedir?: () => string,
|
||||
@@ -80,6 +85,7 @@ export function resolveDefaultPluginExtensionsDir(
|
||||
return path.join(resolveConfigDir(env, homedir), "extensions");
|
||||
}
|
||||
|
||||
/** Resolves the default directory for managed npm plugin installs. */
|
||||
export function resolveDefaultPluginNpmDir(
|
||||
env: NodeJS.ProcessEnv = process.env,
|
||||
homedir?: () => string,
|
||||
@@ -87,6 +93,7 @@ export function resolveDefaultPluginNpmDir(
|
||||
return path.join(resolveConfigDir(env, homedir), "npm");
|
||||
}
|
||||
|
||||
/** Encodes an npm package name into a managed npm project directory name. */
|
||||
export function encodePluginNpmProjectDirName(packageName: string): string {
|
||||
const trimmed = packageName.trim();
|
||||
if (!trimmed) {
|
||||
@@ -95,11 +102,13 @@ export function encodePluginNpmProjectDirName(packageName: string): string {
|
||||
return safePathSegmentHashed(trimmed);
|
||||
}
|
||||
|
||||
/** Resolves the directory containing managed npm plugin projects. */
|
||||
export function resolvePluginNpmProjectsDir(npmDir?: string): string {
|
||||
const npmBase = npmDir ? resolveUserPath(npmDir) : resolveDefaultPluginNpmDir();
|
||||
return path.join(npmBase, "projects");
|
||||
}
|
||||
|
||||
/** Resolves the managed npm project directory for a package name. */
|
||||
export function resolvePluginNpmProjectDir(params: {
|
||||
packageName: string;
|
||||
npmDir?: string;
|
||||
@@ -110,6 +119,7 @@ export function resolvePluginNpmProjectDir(params: {
|
||||
);
|
||||
}
|
||||
|
||||
/** Resolves the installed node_modules package directory for a managed npm plugin. */
|
||||
export function resolvePluginNpmPackageDir(params: {
|
||||
packageName: string;
|
||||
npmDir?: string;
|
||||
@@ -121,6 +131,7 @@ export function resolvePluginNpmPackageDir(params: {
|
||||
);
|
||||
}
|
||||
|
||||
/** Resolves the default directory for git-installed plugins. */
|
||||
export function resolveDefaultPluginGitDir(
|
||||
env: NodeJS.ProcessEnv = process.env,
|
||||
homedir?: () => string,
|
||||
@@ -128,6 +139,7 @@ export function resolveDefaultPluginGitDir(
|
||||
return path.join(resolveConfigDir(env, homedir), "git");
|
||||
}
|
||||
|
||||
/** Resolves the safe install directory for one plugin id. */
|
||||
export function resolvePluginInstallDir(pluginId: string, extensionsDir?: string): string {
|
||||
const extensionsBase = extensionsDir
|
||||
? resolveUserPath(extensionsDir)
|
||||
|
||||
@@ -2,6 +2,7 @@ import { createDedupeCache, resolveGlobalDedupeCache } from "../infra/dedupe.js"
|
||||
import type { DedupeCache } from "../infra/dedupe.js";
|
||||
import type { PluginInteractiveHandlerRegistration } from "./types.js";
|
||||
|
||||
/** Registered interactive handler with owning plugin metadata. */
|
||||
export type RegisteredInteractiveHandler = PluginInteractiveHandlerRegistration & {
|
||||
pluginId: string;
|
||||
pluginName?: string;
|
||||
@@ -67,6 +68,7 @@ function getState() {
|
||||
return created;
|
||||
}
|
||||
|
||||
/** Returns the process-global plugin interactive handler registry. */
|
||||
export function getPluginInteractiveHandlersState() {
|
||||
return getState().interactiveHandlers;
|
||||
}
|
||||
@@ -75,6 +77,7 @@ function getPluginInteractiveCallbackDedupeState() {
|
||||
return getState().callbackDedupe;
|
||||
}
|
||||
|
||||
/** Claims an interactive callback dedupe key while the callback is in flight. */
|
||||
export function claimPluginInteractiveCallbackDedupe(
|
||||
dedupeKey: string | undefined,
|
||||
now = Date.now(),
|
||||
@@ -90,6 +93,7 @@ export function claimPluginInteractiveCallbackDedupe(
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Commits an interactive callback dedupe key after successful handling. */
|
||||
export function commitPluginInteractiveCallbackDedupe(
|
||||
dedupeKey: string | undefined,
|
||||
now = Date.now(),
|
||||
@@ -102,6 +106,7 @@ export function commitPluginInteractiveCallbackDedupe(
|
||||
state.callbackDedupe.check(dedupeKey, now);
|
||||
}
|
||||
|
||||
/** Releases an in-flight interactive callback dedupe claim without committing it. */
|
||||
export function releasePluginInteractiveCallbackDedupe(dedupeKey: string | undefined): void {
|
||||
if (!dedupeKey) {
|
||||
return;
|
||||
@@ -109,12 +114,14 @@ export function releasePluginInteractiveCallbackDedupe(dedupeKey: string | undef
|
||||
getState().inflightCallbackDedupe.delete(dedupeKey);
|
||||
}
|
||||
|
||||
/** Clears plugin interactive handlers and callback dedupe state. */
|
||||
export function clearPluginInteractiveHandlersState(): void {
|
||||
clearPluginInteractiveHandlerRegistrationsState();
|
||||
getPluginInteractiveCallbackDedupeState().clear();
|
||||
getState().inflightCallbackDedupe.clear();
|
||||
}
|
||||
|
||||
/** Clears only plugin interactive handler registrations. */
|
||||
export function clearPluginInteractiveHandlerRegistrationsState(): void {
|
||||
getPluginInteractiveHandlersState().clear();
|
||||
}
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
/** Plugin kind labels for non-provider plugin capability groups. */
|
||||
export type PluginKind = "memory" | "context-engine";
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization";
|
||||
|
||||
/** Optional scoped plugin id list; undefined means unscoped. */
|
||||
export type PluginIdScope = readonly string[] | undefined;
|
||||
|
||||
/** Normalizes plugin id scope input into a sorted unique string list. */
|
||||
export function normalizePluginIdScope(ids?: readonly unknown[]): string[] | undefined {
|
||||
if (ids === undefined) {
|
||||
return undefined;
|
||||
@@ -11,14 +13,17 @@ export function normalizePluginIdScope(ids?: readonly unknown[]): string[] | und
|
||||
).toSorted();
|
||||
}
|
||||
|
||||
/** True when plugin scope was explicitly provided, including an empty scope. */
|
||||
export function hasExplicitPluginIdScope(ids?: readonly string[]): boolean {
|
||||
return ids !== undefined;
|
||||
}
|
||||
|
||||
/** True when plugin scope was explicitly provided with at least one id. */
|
||||
export function hasNonEmptyPluginIdScope(ids?: readonly string[]): boolean {
|
||||
return ids !== undefined && ids.length > 0;
|
||||
}
|
||||
|
||||
/** Creates a lookup set for explicit plugin scope, or null when unscoped. */
|
||||
export function createPluginIdScopeSet(ids?: readonly string[]): ReadonlySet<string> | null {
|
||||
if (ids === undefined) {
|
||||
return null;
|
||||
@@ -26,6 +31,7 @@ export function createPluginIdScopeSet(ids?: readonly string[]): ReadonlySet<str
|
||||
return new Set(ids);
|
||||
}
|
||||
|
||||
/** Serializes plugin scope for cache keys. */
|
||||
export function serializePluginIdScope(ids?: readonly string[]): string {
|
||||
return ids === undefined ? "__unscoped__" : JSON.stringify(ids);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ type SetupDescriptorRecord = Pick<
|
||||
"providers" | "cliBackends" | "providerAuthAliases" | "setup"
|
||||
>;
|
||||
|
||||
/** Lists setup provider ids and auth aliases owned by one plugin manifest. */
|
||||
export function listSetupProviderIds(record: SetupDescriptorRecord): readonly string[] {
|
||||
const providerIds = record.setup?.providers?.map((entry) => entry.id) ?? record.providers;
|
||||
const normalizedProviderIds = new Set(providerIds.map(normalizeProviderId));
|
||||
@@ -15,6 +16,7 @@ export function listSetupProviderIds(record: SetupDescriptorRecord): readonly st
|
||||
return [...providerIds, ...aliases];
|
||||
}
|
||||
|
||||
/** Lists setup CLI backend ids from setup metadata or manifest contribution ids. */
|
||||
export function listSetupCliBackendIds(record: SetupDescriptorRecord): readonly string[] {
|
||||
return record.setup?.cliBackends ?? record.cliBackends;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import { resolveUserPath } from "../utils.js";
|
||||
import { normalizeBundledLookupPath } from "./bundled-load-path-aliases.js";
|
||||
import { resolveBundledPluginSources, type BundledPluginSource } from "./bundled-sources.js";
|
||||
|
||||
/** Stale install record that points at old compiled bundled plugin output. */
|
||||
export type StaleLocalBundledPluginInstallRecord = {
|
||||
pluginId: string;
|
||||
record: PluginInstallRecord;
|
||||
@@ -49,6 +50,7 @@ function hasStaleBundledVersion(
|
||||
return Boolean(recordVersion && bundledVersion && recordVersion !== bundledVersion);
|
||||
}
|
||||
|
||||
/** Lists path install records that still point at stale compiled bundled plugin output. */
|
||||
export function listStaleLocalBundledPluginInstallRecords(params: {
|
||||
installRecords: Record<string, PluginInstallRecord>;
|
||||
workspaceDir?: string;
|
||||
@@ -100,6 +102,7 @@ export function listStaleLocalBundledPluginInstallRecords(params: {
|
||||
return stale;
|
||||
}
|
||||
|
||||
/** Removes stale compiled bundled plugin path records from an install record map. */
|
||||
export function pruneStaleLocalBundledPluginInstallRecords(params: {
|
||||
installRecords: Record<string, PluginInstallRecord>;
|
||||
workspaceDir?: string;
|
||||
|
||||
Reference in New Issue
Block a user