Files
2026-05-30 14:16:04 -05:00

124 lines
3.7 KiB
TypeScript

import { Type } from "@sinclair/typebox"
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/plugin-entry"
import type { BmClient } from "../bm-client.ts"
import { log } from "../logger.ts"
export function registerEditTool(
api: OpenClawPluginApi,
client: BmClient,
): void {
api.registerTool(
{
name: "edit_note",
label: "Edit Note",
description:
"Incrementally edit an existing note in the Basic Memory knowledge graph. " +
"Supports append, prepend, find/replace, and section replacement " +
"without rewriting the entire note.",
parameters: Type.Object({
identifier: Type.String({
description: "Note title, permalink, or memory:// URL to edit",
}),
operation: Type.Union(
[
Type.Literal("append"),
Type.Literal("prepend"),
Type.Literal("find_replace"),
Type.Literal("replace_section"),
],
{
description:
"Edit operation: append (add to end), prepend (add to start), " +
"find_replace (replace matching text), replace_section (replace a heading section)",
},
),
content: Type.String({
description: "New content to add or replace with",
}),
find_text: Type.Optional(
Type.String({
description: "Text to find (required for find_replace)",
}),
),
section: Type.Optional(
Type.String({
description:
"Section heading to replace (required for replace_section)",
}),
),
expected_replacements: Type.Optional(
Type.Number({
description:
"Expected replacement count for find_replace (default: 1)",
}),
),
project: Type.Optional(
Type.String({
description: "Target project name (defaults to current project)",
}),
),
}),
async execute(
_toolCallId: string,
params: {
identifier: string
operation: "append" | "prepend" | "find_replace" | "replace_section"
content: string
find_text?: string
section?: string
expected_replacements?: number
project?: string
},
) {
log.debug(`edit_note: id="${params.identifier}" op=${params.operation}`)
try {
const note = await client.editNote(
params.identifier,
params.operation,
params.content,
{
find_text: params.find_text,
section: params.section,
expected_replacements: params.expected_replacements,
},
params.project,
)
return {
content: [
{
type: "text" as const,
text: `Note updated: ${note.title} (${note.permalink})`,
},
],
details: {
title: note.title,
permalink: note.permalink,
file_path: note.file_path,
operation: params.operation,
checksum: note.checksum ?? null,
},
}
} catch (err) {
log.error("edit_note failed", err)
return {
content: [
{
type: "text" as const,
text: `Failed to edit note "${params.identifier}". It may not exist.`,
},
],
details: {
identifier: params.identifier,
operation: params.operation,
error: "edit_note_failed",
},
}
}
},
},
{ name: "edit_note" },
)
}