mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-03 07:01:40 +00:00
57 lines
2.0 KiB
TypeScript
57 lines
2.0 KiB
TypeScript
import { AsyncLocalStorage } from "node:async_hooks";
|
|
import os from "node:os";
|
|
import path from "node:path";
|
|
import { resolveStateDir } from "../config/paths.js";
|
|
import { resolveGlobalSingleton } from "../shared/global-singleton.js";
|
|
import { resolveConfigDir } from "../utils.js";
|
|
|
|
const PLUGIN_INSTALL_ROOT_CONTEXT_KEY = Symbol.for("openclaw.pluginInstallRootContext");
|
|
|
|
/** Immutable roots that own installed plugin artifacts and their registry. */
|
|
export type PluginInstallRoots = Readonly<{
|
|
extensionsDir: string;
|
|
gitDir: string;
|
|
npmDir: string;
|
|
stateDir: string;
|
|
}>;
|
|
|
|
const pluginInstallRootContext = resolveGlobalSingleton<AsyncLocalStorage<PluginInstallRoots>>(
|
|
PLUGIN_INSTALL_ROOT_CONTEXT_KEY,
|
|
() => new AsyncLocalStorage(),
|
|
);
|
|
|
|
/** Resolve the ordinary operator-owned plugin roots before a run redirects state. */
|
|
export function resolvePluginInstallRoots(
|
|
env: NodeJS.ProcessEnv = process.env,
|
|
homedir: () => string = os.homedir,
|
|
): PluginInstallRoots {
|
|
const configDir = resolveConfigDir(env, homedir);
|
|
return Object.freeze({
|
|
extensionsDir: path.join(configDir, "extensions"),
|
|
gitDir: path.join(configDir, "git"),
|
|
npmDir: path.join(configDir, "npm"),
|
|
stateDir: resolveStateDir(env, homedir),
|
|
});
|
|
}
|
|
|
|
/** Return run-pinned install roots, or resolve the caller's ordinary roots. */
|
|
export function resolveActivePluginInstallRoots(
|
|
env: NodeJS.ProcessEnv = process.env,
|
|
homedir: () => string = os.homedir,
|
|
): PluginInstallRoots {
|
|
return pluginInstallRootContext.getStore() ?? resolvePluginInstallRoots(env, homedir);
|
|
}
|
|
|
|
/** Return whether the current run pinned operator-owned plugin install roots. */
|
|
export function hasActivePluginInstallRoots(): boolean {
|
|
return pluginInstallRootContext.getStore() !== undefined;
|
|
}
|
|
|
|
/**
|
|
* Keep plugin discovery on one operator-owned install generation while a run
|
|
* redirects OPENCLAW_STATE_DIR for ephemeral sessions and runtime state.
|
|
*/
|
|
export function withPluginInstallRoots<T>(roots: PluginInstallRoots, run: () => T): T {
|
|
return pluginInstallRootContext.run(roots, run);
|
|
}
|