mirror of
https://github.com/rtk-ai/rtk.git
synced 2026-09-19 07:33:17 +08:00
56160d8399
* feat: add OpenClaw plugin for transparent exec rewriting Adds an OpenClaw plugin that intercepts exec tool calls via the before_tool_call hook and rewrites commands to their RTK equivalents. This is the OpenClaw equivalent of hooks/rtk-rewrite.sh for Claude Code. The plugin: - Registers a before_tool_call hook on the exec tool - Rewrites git, grep, find, ls, gh, docker, kubectl, and test commands - Guards against rewriting piped/compound commands and heredocs - Returns properly typed PluginHookBeforeToolCallResult - Supports enabled/verbose config options Measured savings: 48-87% token reduction on common commands. Files: - openclaw/index.ts — plugin source - openclaw/openclaw.plugin.json — plugin manifest - openclaw/README.md — installation and usage docs * refactor: delegate OpenClaw plugin to rtk rewrite Replace 60+ hardcoded regex rules with a single call to `rtk rewrite`, matching the OpenCode plugin pattern (hooks/opencode-rtk.ts). Benefits: - Zero maintenance: new RTK filters work automatically - Single source of truth: rewrite logic in Rust (src/discover/registry.rs) - 122 → 73 lines, no rule duplication Also: rebase on develop, fix homepage URL, bump version to 1.0.0. Signed-off-by: Patrick szymkowiak <patrick.szymkowiak@innovtech.eu> * feat: add package.json for npm publishing Enables `openclaw plugins install @rtk-ai/rtk-rewrite` for OpenClaw users. Signed-off-by: Patrick szymkowiak <patrick.szymkowiak@innovtech.eu> --------- Signed-off-by: Patrick szymkowiak <patrick.szymkowiak@innovtech.eu> Co-authored-by: Patrick szymkowiak <patrick.szymkowiak@innovtech.eu>
75 lines
1.8 KiB
TypeScript
75 lines
1.8 KiB
TypeScript
/**
|
|
* RTK Rewrite Plugin for OpenClaw
|
|
*
|
|
* Transparently rewrites exec tool commands to RTK equivalents
|
|
* before execution, achieving 60-90% LLM token savings.
|
|
*
|
|
* All rewrite logic lives in `rtk rewrite` (src/discover/registry.rs).
|
|
* This plugin is a thin delegate — to add or change rules, edit the
|
|
* Rust registry, not this file.
|
|
*/
|
|
|
|
import { execSync } from "node:child_process";
|
|
|
|
let rtkAvailable: boolean | null = null;
|
|
|
|
function checkRtk(): boolean {
|
|
if (rtkAvailable !== null) return rtkAvailable;
|
|
try {
|
|
execSync("which rtk", { stdio: "ignore" });
|
|
rtkAvailable = true;
|
|
} catch {
|
|
rtkAvailable = false;
|
|
}
|
|
return rtkAvailable;
|
|
}
|
|
|
|
function tryRewrite(command: string): string | null {
|
|
try {
|
|
const result = execSync(`rtk rewrite ${JSON.stringify(command)}`, {
|
|
encoding: "utf-8",
|
|
timeout: 2000,
|
|
}).trim();
|
|
return result && result !== command ? result : null;
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
export default function register(api: any) {
|
|
const pluginConfig = api.config ?? {};
|
|
const enabled = pluginConfig.enabled !== false;
|
|
const verbose = pluginConfig.verbose === true;
|
|
|
|
if (!enabled) return;
|
|
|
|
if (!checkRtk()) {
|
|
console.warn("[rtk] rtk binary not found in PATH — plugin disabled");
|
|
return;
|
|
}
|
|
|
|
api.on(
|
|
"before_tool_call",
|
|
(event: { toolName: string; params: Record<string, unknown> }) => {
|
|
if (event.toolName !== "exec") return;
|
|
|
|
const command = event.params?.command;
|
|
if (typeof command !== "string") return;
|
|
|
|
const rewritten = tryRewrite(command);
|
|
if (!rewritten) return;
|
|
|
|
if (verbose) {
|
|
console.log(`[rtk] ${command} -> ${rewritten}`);
|
|
}
|
|
|
|
return { params: { ...event.params, command: rewritten } };
|
|
},
|
|
{ priority: 10 }
|
|
);
|
|
|
|
if (verbose) {
|
|
console.log("[rtk] OpenClaw plugin registered");
|
|
}
|
|
}
|