2026-02-19 17:09:46 +09:00
|
|
|
import { tool, type ToolContext, type ToolDefinition } from "@opencode-ai/plugin/tool"
|
2026-02-16 16:32:33 +09:00
|
|
|
import type { HashlineEdit } from "./types"
|
2026-02-22 14:13:59 +09:00
|
|
|
import { executeHashlineEditTool } from "./hashline-edit-executor"
|
2026-02-22 03:38:04 +09:00
|
|
|
import { HASHLINE_EDIT_DESCRIPTION } from "./tool-description"
|
2026-02-16 16:32:33 +09:00
|
|
|
|
|
|
|
|
interface HashlineEditArgs {
|
2026-02-19 17:09:46 +09:00
|
|
|
filePath: string
|
2026-02-16 16:32:33 +09:00
|
|
|
edits: HashlineEdit[]
|
2026-02-22 03:38:04 +09:00
|
|
|
delete?: boolean
|
|
|
|
|
rename?: string
|
2026-02-16 16:32:33 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function createHashlineEditTool(): ToolDefinition {
|
|
|
|
|
return tool({
|
2026-02-22 03:38:04 +09:00
|
|
|
description: HASHLINE_EDIT_DESCRIPTION,
|
2026-02-16 16:32:33 +09:00
|
|
|
args: {
|
2026-02-19 17:09:46 +09:00
|
|
|
filePath: tool.schema.string().describe("Absolute path to the file to edit"),
|
2026-02-22 03:38:04 +09:00
|
|
|
delete: tool.schema.boolean().optional().describe("Delete file instead of editing"),
|
|
|
|
|
rename: tool.schema.string().optional().describe("Rename output file path after edits"),
|
2026-02-16 16:32:33 +09:00
|
|
|
edits: tool.schema
|
|
|
|
|
.array(
|
|
|
|
|
tool.schema.union([
|
|
|
|
|
tool.schema.object({
|
|
|
|
|
type: tool.schema.literal("set_line"),
|
2026-02-20 11:02:07 +09:00
|
|
|
line: tool.schema.string().describe("Line reference in LINE#ID format"),
|
|
|
|
|
text: tool.schema
|
|
|
|
|
.union([tool.schema.string(), tool.schema.array(tool.schema.string())])
|
|
|
|
|
.describe("New content for the line (string or string[] for multiline)"),
|
2026-02-16 16:32:33 +09:00
|
|
|
}),
|
|
|
|
|
tool.schema.object({
|
|
|
|
|
type: tool.schema.literal("replace_lines"),
|
2026-02-20 11:02:07 +09:00
|
|
|
start_line: tool.schema.string().describe("Start line in LINE#ID format"),
|
|
|
|
|
end_line: tool.schema.string().describe("End line in LINE#ID format"),
|
|
|
|
|
text: tool.schema
|
|
|
|
|
.union([tool.schema.string(), tool.schema.array(tool.schema.string())])
|
|
|
|
|
.describe("New content to replace the range (string or string[] for multiline)"),
|
2026-02-16 16:32:33 +09:00
|
|
|
}),
|
|
|
|
|
tool.schema.object({
|
|
|
|
|
type: tool.schema.literal("insert_after"),
|
2026-02-20 11:02:07 +09:00
|
|
|
line: tool.schema.string().describe("Line reference in LINE#ID format"),
|
|
|
|
|
text: tool.schema
|
|
|
|
|
.union([tool.schema.string(), tool.schema.array(tool.schema.string())])
|
|
|
|
|
.describe("Content to insert after the line (string or string[] for multiline)"),
|
2026-02-16 16:32:33 +09:00
|
|
|
}),
|
2026-02-22 03:38:04 +09:00
|
|
|
tool.schema.object({
|
|
|
|
|
type: tool.schema.literal("insert_before"),
|
|
|
|
|
line: tool.schema.string().describe("Line reference in LINE#ID format"),
|
|
|
|
|
text: tool.schema
|
|
|
|
|
.union([tool.schema.string(), tool.schema.array(tool.schema.string())])
|
|
|
|
|
.describe("Content to insert before the line (string or string[] for multiline)"),
|
|
|
|
|
}),
|
|
|
|
|
tool.schema.object({
|
|
|
|
|
type: tool.schema.literal("insert_between"),
|
|
|
|
|
after_line: tool.schema.string().describe("After line in LINE#ID format"),
|
|
|
|
|
before_line: tool.schema.string().describe("Before line in LINE#ID format"),
|
|
|
|
|
text: tool.schema
|
|
|
|
|
.union([tool.schema.string(), tool.schema.array(tool.schema.string())])
|
|
|
|
|
.describe("Content to insert between anchor lines (string or string[] for multiline)"),
|
|
|
|
|
}),
|
2026-02-16 16:32:33 +09:00
|
|
|
tool.schema.object({
|
|
|
|
|
type: tool.schema.literal("replace"),
|
|
|
|
|
old_text: tool.schema.string().describe("Text to find"),
|
2026-02-20 11:02:07 +09:00
|
|
|
new_text: tool.schema
|
|
|
|
|
.union([tool.schema.string(), tool.schema.array(tool.schema.string())])
|
|
|
|
|
.describe("Replacement text (string or string[] for multiline)"),
|
2026-02-16 16:32:33 +09:00
|
|
|
}),
|
2026-02-22 14:13:59 +09:00
|
|
|
tool.schema.object({
|
|
|
|
|
type: tool.schema.literal("append"),
|
|
|
|
|
text: tool.schema
|
|
|
|
|
.union([tool.schema.string(), tool.schema.array(tool.schema.string())])
|
|
|
|
|
.describe("Content to append at EOF; also creates missing file"),
|
|
|
|
|
}),
|
|
|
|
|
tool.schema.object({
|
|
|
|
|
type: tool.schema.literal("prepend"),
|
|
|
|
|
text: tool.schema
|
|
|
|
|
.union([tool.schema.string(), tool.schema.array(tool.schema.string())])
|
|
|
|
|
.describe("Content to prepend at BOF; also creates missing file"),
|
|
|
|
|
}),
|
2026-02-16 16:32:33 +09:00
|
|
|
])
|
|
|
|
|
)
|
2026-02-22 03:38:04 +09:00
|
|
|
.describe("Array of edit operations to apply (empty when delete=true)"),
|
2026-02-16 16:32:33 +09:00
|
|
|
},
|
2026-02-22 14:13:59 +09:00
|
|
|
execute: async (args: HashlineEditArgs, context: ToolContext) => executeHashlineEditTool(args, context),
|
2026-02-16 16:32:33 +09:00
|
|
|
})
|
|
|
|
|
}
|