From b17ded942d5ac42e239f7cd88ca3d4c269c9b362 Mon Sep 17 00:00:00 2001 From: LHMQ878 <72402929@cityu-dg.edu.cn> Date: Sat, 8 Aug 2026 16:49:17 +0800 Subject: [PATCH] fix: register /dcp command with OpenCode Expose the /dcp command alongside /dcp-compress so users can manage DCP from chat, including re-enabling auto compression via /dcp manual off. --- index.ts | 9 ++---- lib/commands/register.ts | 30 ++++++++++++++++++++ tests/plugin-commands.test.ts | 52 +++++++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 7 deletions(-) create mode 100644 lib/commands/register.ts create mode 100644 tests/plugin-commands.test.ts diff --git a/index.ts b/index.ts index 3f11e392..3664dca9 100644 --- a/index.ts +++ b/index.ts @@ -16,6 +16,7 @@ import { createSystemPromptHandler, createTextCompleteHandler, } from "./lib/hooks" +import { registerOpencodeCommands } from "./lib/commands/register" import { configureClientAuth, isSecureMode } from "./lib/auth" import { startAutoUpdate } from "./lib/update" @@ -94,13 +95,7 @@ const server: Plugin = (async (ctx) => { config.compress.permission = "deny" } - if (config.commands.enabled && config.compress.permission !== "deny") { - opencodeConfig.command ??= {} - opencodeConfig.command["dcp-compress"] = { - template: "", - description: "Trigger DCP manual compression with: /dcp-compress [focus]", - } - } + registerOpencodeCommands(opencodeConfig, config) const toolsToAdd: string[] = [] if (config.compress.permission !== "deny" && !config.experimental.allowSubAgents) { diff --git a/lib/commands/register.ts b/lib/commands/register.ts new file mode 100644 index 00000000..6ffda7e8 --- /dev/null +++ b/lib/commands/register.ts @@ -0,0 +1,30 @@ +import type { PluginConfig } from "./config" + +type OpencodeCommandConfig = { + template: string + description: string +} + +type OpencodeConfig = { + command?: Record +} + +export function registerOpencodeCommands( + opencodeConfig: OpencodeConfig, + config: PluginConfig, +): void { + if (!config.commands.enabled || config.compress.permission === "deny") { + return + } + + opencodeConfig.command ??= {} + opencodeConfig.command["dcp"] = { + template: "", + description: + "DCP context management: /dcp stats, /dcp context, /dcp sweep, /dcp manual, /dcp decompress, /dcp recompress", + } + opencodeConfig.command["dcp-compress"] = { + template: "", + description: "Trigger DCP manual compression with: /dcp-compress [focus]", + } +} diff --git a/tests/plugin-commands.test.ts b/tests/plugin-commands.test.ts new file mode 100644 index 00000000..18660d00 --- /dev/null +++ b/tests/plugin-commands.test.ts @@ -0,0 +1,52 @@ +import assert from "node:assert/strict" +import test from "node:test" +import type { PluginConfig } from "../lib/config" +import { registerOpencodeCommands } from "../lib/commands/register" + +function buildConfig(permission: "allow" | "deny" = "allow"): PluginConfig { + return { + enabled: true, + debug: false, + pruneNotification: "off", + pruneNotificationType: "chat", + commands: { enabled: true, protectedTools: [] }, + manualMode: { enabled: false, automaticStrategies: true }, + turnProtection: { enabled: false, turns: 4 }, + experimental: { allowSubAgents: false, customPrompts: false }, + protectedFilePatterns: [], + compress: { + mode: "message", + permission, + showCompression: false, + maxContextLimit: 150000, + minContextLimit: 50000, + nudgeFrequency: 5, + iterationNudgeThreshold: 15, + nudgeForce: "soft", + protectedTools: ["task"], + protectTags: false, + protectUserMessages: false, + }, + strategies: { + deduplication: { enabled: true, protectedTools: [] }, + purgeErrors: { enabled: true, turns: 4, protectedTools: [] }, + }, + } as PluginConfig +} + +test("registerOpencodeCommands exposes /dcp and /dcp-compress", () => { + const opencodeConfig: Record = {} + registerOpencodeCommands(opencodeConfig, buildConfig("allow")) + + const commands = opencodeConfig.command as Record + assert.ok(commands.dcp) + assert.match(commands.dcp.description, /\/dcp manual/) + assert.ok(commands["dcp-compress"]) +}) + +test("registerOpencodeCommands skips commands when compress is denied", () => { + const opencodeConfig: Record = {} + registerOpencodeCommands(opencodeConfig, buildConfig("deny")) + + assert.equal(opencodeConfig.command, undefined) +})