Files
openclaw/src/plugins/runtime-workspace-state.ts
Peter Steinberger 2aa4ff0825 refactor: consolidate duplicate helper exports (#106016)
* refactor(normalization): consolidate string helpers

* refactor(normalization): consolidate agent ids

* refactor(paths): consolidate user path resolution

* refactor(gateway): preserve transcript helper facade

* fix(normalization): align helper build aliases

* fix(memory): keep helper import line neutral

* chore(plugin-sdk): align consolidated helper surface

* refactor(normalization): reuse lowercase string helper

* refactor(normalization): reuse record guard

* refactor(normalization): share surrogate boundary helper

* refactor(agents): share token estimate constant

* refactor(memory): distinguish standalone helper contracts

* refactor(normalization): share error cause formatter

* refactor(config): distinguish eligibility predicates

* refactor(plugins): share registry state symbol

* refactor(cli): reuse outbound dependency adapter

* refactor(cron): distinguish positive duration parser

* fix(gateway): keep transcript helper private

* fix(paths): preserve public helper status

* refactor(channels): reuse registry normalizer

* refactor(agents): reuse agent core runtime facade

* refactor(auth): reuse locked profile upsert

* refactor(records): distinguish trap-safe guard

* refactor(migrations): distinguish sync directory helper

* test(plugins): drop stale duration alias expectations

* fix(channels): remove stale registry import

* chore(plugin-sdk): refresh helper API baseline

* fix(memory): keep renamed helpers private

* fix(plugins): keep registry state key private

* fix(plugin-sdk): tighten wildcard surface budget

* chore(plugin-sdk): refresh rebased helper API baseline
2026-07-13 03:22:00 -07:00

48 lines
1.9 KiB
TypeScript

// Shares plugin runtime workspace state across module reloads.
import { AsyncLocalStorage } from "node:async_hooks";
import { resolveGlobalSingleton } from "../shared/global-singleton.js";
import { PLUGIN_REGISTRY_STATE } from "./runtime-state-key.js";
const PINNED_PLUGIN_REGISTRY_WORKSPACE_KEY = Symbol.for(
"openclaw.pinnedPluginRegistryWorkspaceDir",
);
type GlobalRegistryWorkspaceState = typeof globalThis & {
[PLUGIN_REGISTRY_STATE]?: {
workspaceDir?: string | null;
};
};
const pinnedWorkspaceDirStorage = resolveGlobalSingleton<
AsyncLocalStorage<{ workspaceDir: string | undefined }>
>(PINNED_PLUGIN_REGISTRY_WORKSPACE_KEY, () => new AsyncLocalStorage());
/** Reads the active plugin registry workspace directory from global runtime state,
* respecting any pinned workspace from the current async context. */
export function getActivePluginRegistryWorkspaceDirFromState(): string | undefined {
const pinned = pinnedWorkspaceDirStorage.getStore();
if (pinned) {
return pinned.workspaceDir;
}
return (
(globalThis as GlobalRegistryWorkspaceState)[PLUGIN_REGISTRY_STATE]?.workspaceDir ?? undefined
);
}
/**
* Pin the active plugin-registry workspace dir for the duration of `fn`.
* While pinned, calls to `getActivePluginRegistryWorkspaceDirFromState()` return
* the snapshot taken at pin time, ignoring concurrent mutations from other
* agent turns or crons. This prevents per-row memo-busting in operations that
* iterate over many rows (e.g. sessions.list).
*/
export function withPinnedActivePluginRegistryWorkspaceDir<T>(fn: () => T): T {
if (pinnedWorkspaceDirStorage.getStore()) {
// Already pinned in an outer scope — reuse it.
return fn();
}
const workspaceDir =
(globalThis as GlobalRegistryWorkspaceState)[PLUGIN_REGISTRY_STATE]?.workspaceDir ?? undefined;
return pinnedWorkspaceDirStorage.run({ workspaceDir }, fn);
}