Skip to content

Instantly share code, notes, and snippets.

@vinciest
Created June 25, 2026 09:10
Show Gist options
  • Select an option

  • Save vinciest/900d2712aad394e5c8f359e27be8ca89 to your computer and use it in GitHub Desktop.

Select an option

Save vinciest/900d2712aad394e5c8f359e27be8ca89 to your computer and use it in GitHub Desktop.
Copilot CLI + RTK, put at ~/.copilot/extensions/rtk-rewrite/extension.mjs
import { spawn } from "node:child_process";
import { approveAll } from "@github/copilot-sdk";
import { joinSession } from "@github/copilot-sdk/extension";
// Pipes bash onPreToolUse events through rtk hook copilot, which rewrites
// commands to their rtk-equivalent for token savings (e.g. git status → rtk git status).
// Safe no-op if rtk is not installed or returns no rewrite.
//
// Input shape: app.js calls extensions via FCs() which produces { toolName, toolArgs }
// per individual tool call. toolArgs may be a JSON string (OpenAI wire format) or
// already-parsed object depending on CLI version — handle both defensively.
function runRtk(input) {
let toolInput;
if (input.toolName) {
if (input.toolName !== "bash") return Promise.resolve({});
toolInput = typeof input.toolArgs === "string"
? JSON.parse(input.toolArgs)
: input.toolArgs;
} else if (input.toolCalls) {
const call = input.toolCalls.find(c => c.name === "bash");
if (!call) return Promise.resolve({});
try { toolInput = JSON.parse(call.args); } catch { return Promise.resolve({}); }
} else {
return Promise.resolve({});
}
return new Promise((resolve) => {
const proc = spawn("rtk", ["hook", "copilot"], { timeout: 5000 });
let stdout = "";
proc.stdout.on("data", (d) => (stdout += d));
proc.on("close", () => {
try {
const hook = JSON.parse(stdout)?.hookSpecificOutput;
if (hook?.updatedInput) {
// Merge back fields rtk drops (e.g. description) — CLI validates all required fields
resolve({ permissionDecision: "allow", modifiedArgs: { ...toolInput, ...hook.updatedInput } });
} else {
resolve({});
}
} catch { resolve({}); }
});
proc.on("error", () => resolve({}));
proc.stdin.write(JSON.stringify({ tool_name: "bash", tool_input: toolInput }));
proc.stdin.end();
});
}
await joinSession({
onPermissionRequest: approveAll,
hooks: {
onPreToolUse: async (input) => runRtk(input),
},
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment