mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 05:00:43 +00:00
* feat: wire codex diagnostics feedback * fix: harden codex diagnostics hints * fix: neutralize codex diagnostics output * fix: tighten codex diagnostics safeguards * fix: bound codex diagnostics feedback output * fix: tighten codex diagnostics throttling * fix: confirm codex diagnostics uploads * docs: clarify codex diagnostics add-on * fix: route diagnostics through core command * fix: tighten diagnostics authorization * fix: pin diagnostics to bundled codex command * fix: limit owner status in plugin commands * fix: scope diagnostics confirmations * fix: scope codex diagnostics cooldowns * fix: harden codex diagnostics ownership scopes * fix: harden diagnostics command trust and display * fix: keep diagnostics command trust internal * fix: clarify diagnostics exec boundary * fix: consume codex diagnostics confirmations atomically * test: include codex diagnostics binding metadata * test: use string codex binding timestamps * fix: keep reserved command trust host-only * fix: harden diagnostics trust and resume hints * wire diagnostics through exec approval * fix: keep diagnostics tests aligned with bundled root trust * fix telegram diagnostics owner auth * route trajectory exports through exec approval * fix trajectory exec command encoding * fix telegram group owner auth * fix export trajectory approval hardening * fix pairing command owner bootstrap * fix telegram owner exec approvals * fix: make diagnostics approval flow pasteable * fix: route native sensitive command followups * fix: invoke diagnostics exports with current cli * fix: refresh exec approval protocol models * fix: list codex diagnostics from thread bindings * fix: fold codex diagnostics into exec approval * fix: preserve diagnostics approval line breaks * docs: clarify diagnostics codex workflow
87 lines
2.5 KiB
TypeScript
87 lines
2.5 KiB
TypeScript
import { resolveGlobalSingleton } from "../shared/global-singleton.js";
|
|
import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js";
|
|
import type { OpenClawPluginCommandDefinition } from "./types.js";
|
|
|
|
export type RegisteredPluginCommand = OpenClawPluginCommandDefinition & {
|
|
pluginId: string;
|
|
pluginName?: string;
|
|
pluginRoot?: string;
|
|
};
|
|
|
|
type PluginCommandState = {
|
|
pluginCommands: Map<string, RegisteredPluginCommand>;
|
|
registryLocked: boolean;
|
|
};
|
|
|
|
const PLUGIN_COMMAND_STATE_KEY = Symbol.for("openclaw.pluginCommandsState");
|
|
|
|
const getState = () =>
|
|
resolveGlobalSingleton<PluginCommandState>(PLUGIN_COMMAND_STATE_KEY, () => ({
|
|
pluginCommands: new Map<string, RegisteredPluginCommand>(),
|
|
registryLocked: false,
|
|
}));
|
|
|
|
const getPluginCommandMap = () => getState().pluginCommands;
|
|
|
|
export const pluginCommands = new Proxy(new Map<string, RegisteredPluginCommand>(), {
|
|
get(_target, property) {
|
|
const value = Reflect.get(getPluginCommandMap(), property, getPluginCommandMap());
|
|
return typeof value === "function" ? value.bind(getPluginCommandMap()) : value;
|
|
},
|
|
});
|
|
|
|
export function isPluginCommandRegistryLocked(): boolean {
|
|
return getState().registryLocked;
|
|
}
|
|
|
|
export function setPluginCommandRegistryLocked(locked: boolean): void {
|
|
getState().registryLocked = locked;
|
|
}
|
|
|
|
export function clearPluginCommands(): void {
|
|
pluginCommands.clear();
|
|
}
|
|
|
|
export function clearPluginCommandsForPlugin(pluginId: string): void {
|
|
for (const [key, cmd] of pluginCommands.entries()) {
|
|
if (cmd.pluginId === pluginId) {
|
|
pluginCommands.delete(key);
|
|
}
|
|
}
|
|
}
|
|
|
|
export function isTrustedReservedCommandOwner(command: RegisteredPluginCommand): boolean {
|
|
return command.ownership === "reserved";
|
|
}
|
|
|
|
export function listRegisteredPluginCommands(): RegisteredPluginCommand[] {
|
|
return Array.from(pluginCommands.values());
|
|
}
|
|
|
|
export function listRegisteredPluginAgentPromptGuidance(): string[] {
|
|
const lines: string[] = [];
|
|
const seen = new Set<string>();
|
|
for (const command of pluginCommands.values()) {
|
|
for (const line of command.agentPromptGuidance ?? []) {
|
|
const trimmed = line.trim();
|
|
if (!trimmed || seen.has(trimmed)) {
|
|
continue;
|
|
}
|
|
seen.add(trimmed);
|
|
lines.push(trimmed);
|
|
}
|
|
}
|
|
return lines;
|
|
}
|
|
|
|
export function restorePluginCommands(commands: readonly RegisteredPluginCommand[]): void {
|
|
pluginCommands.clear();
|
|
for (const command of commands) {
|
|
const name = normalizeOptionalLowercaseString(command.name);
|
|
if (!name) {
|
|
continue;
|
|
}
|
|
pluginCommands.set(`/${name}`, command);
|
|
}
|
|
}
|