From 3db46a58a7038099e428d765c478f0d653ab47cf Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Mon, 2 Mar 2026 15:20:02 +0900 Subject: [PATCH] feat(hashline): change hashline_edit default from true to false Hashline edit tool and companion hooks now require explicit opt-in via `"hashline_edit": true` in config. Previously enabled by default. - tool-registry: hashline edit tool not registered unless opted in - create-tool-guard-hooks: hashline-read-enhancer disabled by default - Updated config schema comment and documentation - Added TDD tests for default behavior --- docs/reference/configuration.md | 6 +-- src/config/schema/oh-my-opencode-config.ts | 2 +- src/plugin/hooks/create-tool-guard-hooks.ts | 2 +- src/plugin/tool-execute-before.test.ts | 51 +++++++++++++++++++++ src/plugin/tool-registry.ts | 2 +- 5 files changed, 57 insertions(+), 6 deletions(-) diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index c01865a5f..28eba1193 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -573,13 +573,13 @@ Define `fallback_models` per agent or category: ### Hashline Edit -Replaces the built-in `Edit` tool with a hash-anchored version using `LINE#ID` references to prevent stale-line edits. Enabled by default. +Replaces the built-in `Edit` tool with a hash-anchored version using `LINE#ID` references to prevent stale-line edits. Disabled by default. ```json -{ "hashline_edit": false } +{ "hashline_edit": true } ``` -When enabled, two companion hooks are active: `hashline-read-enhancer` (annotates Read output) and `hashline-edit-diff-enhancer` (shows diffs). Disable them individually via `disabled_hooks`. +When enabled, two companion hooks are active: `hashline-read-enhancer` (annotates Read output) and `hashline-edit-diff-enhancer` (shows diffs). Opt-in by setting `hashline_edit: true`. Disable the companion hooks individually via `disabled_hooks` if needed. ### Experimental diff --git a/src/config/schema/oh-my-opencode-config.ts b/src/config/schema/oh-my-opencode-config.ts index 52e7d461e..200f7289c 100644 --- a/src/config/schema/oh-my-opencode-config.ts +++ b/src/config/schema/oh-my-opencode-config.ts @@ -33,7 +33,7 @@ export const OhMyOpenCodeConfigSchema = z.object({ disabled_commands: z.array(BuiltinCommandNameSchema).optional(), /** Disable specific tools by name (e.g., ["todowrite", "todoread"]) */ disabled_tools: z.array(z.string()).optional(), - /** Enable hashline_edit tool/hook integrations (default: true at call site) */ + /** Enable hashline_edit tool/hook integrations (default: false) */ hashline_edit: z.boolean().optional(), /** Enable model fallback on API errors (default: false). Set to true to enable automatic model switching when model errors occur. */ model_fallback: z.boolean().optional(), diff --git a/src/plugin/hooks/create-tool-guard-hooks.ts b/src/plugin/hooks/create-tool-guard-hooks.ts index 758b78c59..3e909e785 100644 --- a/src/plugin/hooks/create-tool-guard-hooks.ts +++ b/src/plugin/hooks/create-tool-guard-hooks.ts @@ -100,7 +100,7 @@ export function createToolGuardHooks(args: { : null const hashlineReadEnhancer = isHookEnabled("hashline-read-enhancer") - ? safeHook("hashline-read-enhancer", () => createHashlineReadEnhancerHook(ctx, { hashline_edit: { enabled: pluginConfig.hashline_edit ?? true } })) + ? safeHook("hashline-read-enhancer", () => createHashlineReadEnhancerHook(ctx, { hashline_edit: { enabled: pluginConfig.hashline_edit ?? false } })) : null const jsonErrorRecovery = isHookEnabled("json-error-recovery") diff --git a/src/plugin/tool-execute-before.test.ts b/src/plugin/tool-execute-before.test.ts index b3cd3f7fe..7383bfb63 100644 --- a/src/plugin/tool-execute-before.test.ts +++ b/src/plugin/tool-execute-before.test.ts @@ -1,5 +1,6 @@ const { describe, expect, test } = require("bun:test") const { createToolExecuteBeforeHandler } = require("./tool-execute-before") +const { createToolRegistry } = require("./tool-registry") describe("createToolExecuteBeforeHandler", () => { test("does not execute subagent question blocker hook for question tool", async () => { @@ -219,4 +220,54 @@ describe("createToolExecuteBeforeHandler", () => { }) }) +describe("createToolRegistry", () => { + function createRegistryInput(overrides = {}) { + return { + ctx: { + directory: process.cwd(), + client: {}, + }, + pluginConfig: { + ...overrides, + }, + managers: { + backgroundManager: {}, + tmuxSessionManager: {}, + skillMcpManager: {}, + }, + skillContext: { + mergedSkills: [], + availableSkills: [], + browserProvider: "playwright", + disabledSkills: new Set(), + }, + availableCategories: [], + } + } + + describe("#given hashline_edit is undefined", () => { + describe("#when creating tool registry", () => { + test("#then should not register edit tool", () => { + const result = createToolRegistry(createRegistryInput()) + + expect(result.filteredTools.edit).toBeUndefined() + }) + }) + }) + + describe("#given hashline_edit is true", () => { + describe("#when creating tool registry", () => { + test("#then should register edit tool", () => { + const result = createToolRegistry( + createRegistryInput({ + hashline_edit: true, + }), + ) + + expect(result.filteredTools.edit).toBeDefined() + }) + }) + }) +}) + export {} diff --git a/src/plugin/tool-registry.ts b/src/plugin/tool-registry.ts index 21d7901f4..7efce95f2 100644 --- a/src/plugin/tool-registry.ts +++ b/src/plugin/tool-registry.ts @@ -113,7 +113,7 @@ export function createToolRegistry(args: { } : {} - const hashlineEnabled = pluginConfig.hashline_edit ?? true + const hashlineEnabled = pluginConfig.hashline_edit ?? false const hashlineToolsRecord: Record = hashlineEnabled ? { edit: createHashlineEditTool() } : {}