botholomew 0.16.4 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -41
- package/package.json +4 -9
- package/src/chat/agent.ts +37 -40
- package/src/chat/session.ts +10 -10
- package/src/cli.ts +0 -2
- package/src/commands/capabilities.ts +35 -33
- package/src/commands/context.ts +133 -221
- package/src/commands/init.ts +22 -1
- package/src/commands/mcpx.ts +21 -8
- package/src/commands/nuke.ts +52 -15
- package/src/commands/prepare.ts +16 -13
- package/src/config/loader.ts +1 -8
- package/src/config/schemas.ts +6 -0
- package/src/constants.ts +16 -32
- package/src/init/index.ts +52 -27
- package/src/mcpx/client.ts +21 -5
- package/src/mem/client.ts +33 -0
- package/src/{context → prompts}/capabilities.ts +11 -7
- package/src/schedules/store.ts +1 -1
- package/src/tasks/store.ts +1 -1
- package/src/threads/store.ts +1 -1
- package/src/tools/capabilities/refresh.ts +1 -1
- package/src/tools/membot/adapter.ts +111 -0
- package/src/tools/membot/copy.ts +59 -0
- package/src/tools/membot/count_lines.ts +53 -0
- package/src/tools/membot/edit.ts +72 -0
- package/src/tools/membot/exists.ts +54 -0
- package/src/tools/membot/index.ts +26 -0
- package/src/tools/{context → membot}/pipe.ts +34 -32
- package/src/tools/registry.ts +6 -37
- package/src/tools/tool.ts +6 -8
- package/src/tui/App.tsx +3 -4
- package/src/tui/components/ContextPanel.tsx +109 -226
- package/src/tui/components/HelpPanel.tsx +2 -2
- package/src/tui/components/StatusBar.tsx +0 -6
- package/src/tui/components/ThreadPanel.tsx +8 -7
- package/src/tui/wrapDetail.ts +11 -0
- package/src/worker/heartbeat.ts +0 -20
- package/src/worker/index.ts +13 -13
- package/src/worker/llm.ts +7 -9
- package/src/worker/prompt.ts +25 -13
- package/src/worker/spawn.ts +1 -1
- package/src/worker/tick.ts +10 -9
- package/src/commands/db.ts +0 -119
- package/src/commands/with-db.ts +0 -22
- package/src/context/chunker.ts +0 -275
- package/src/context/embedder-impl.ts +0 -100
- package/src/context/embedder.ts +0 -9
- package/src/context/fetcher-errors.ts +0 -8
- package/src/context/fetcher.ts +0 -515
- package/src/context/locks.ts +0 -146
- package/src/context/markdown-converter.ts +0 -186
- package/src/context/reindex.ts +0 -198
- package/src/context/store.ts +0 -841
- package/src/context/url-utils.ts +0 -25
- package/src/db/connection.ts +0 -255
- package/src/db/doctor.ts +0 -235
- package/src/db/embeddings.ts +0 -317
- package/src/db/query.ts +0 -56
- package/src/db/schema.ts +0 -93
- package/src/db/sql/1-core_tables.sql +0 -53
- package/src/db/sql/10-dedupe_context_items.sql +0 -26
- package/src/db/sql/11-rebuild_hnsw.sql +0 -8
- package/src/db/sql/12-workers.sql +0 -66
- package/src/db/sql/13-drive-paths.sql +0 -47
- package/src/db/sql/14-drop_hnsw_index.sql +0 -8
- package/src/db/sql/15-fts_index.sql +0 -8
- package/src/db/sql/16-source_url.sql +0 -7
- package/src/db/sql/17-worker_log_path.sql +0 -3
- package/src/db/sql/18-reset_embeddings_for_local.sql +0 -39
- package/src/db/sql/19-disk_backed_index.sql +0 -36
- package/src/db/sql/2-logging_tables.sql +0 -24
- package/src/db/sql/20-drop_db_tables_for_files.sql +0 -19
- package/src/db/sql/3-daemon_state.sql +0 -5
- package/src/db/sql/4-unique_context_path.sql +0 -1
- package/src/db/sql/5-reset_embeddings_for_openai.sql +0 -1
- package/src/db/sql/6-vss_index.sql +0 -7
- package/src/db/sql/7-drop_embeddings_fk.sql +0 -23
- package/src/db/sql/8-task_output.sql +0 -1
- package/src/db/sql/9-source-type.sql +0 -1
- package/src/tools/context/read-large-result.ts +0 -33
- package/src/tools/dir/create.ts +0 -47
- package/src/tools/dir/size.ts +0 -77
- package/src/tools/dir/tree.ts +0 -124
- package/src/tools/file/copy.ts +0 -73
- package/src/tools/file/count-lines.ts +0 -54
- package/src/tools/file/delete.ts +0 -83
- package/src/tools/file/edit.ts +0 -76
- package/src/tools/file/exists.ts +0 -33
- package/src/tools/file/info.ts +0 -66
- package/src/tools/file/move.ts +0 -66
- package/src/tools/file/read.ts +0 -67
- package/src/tools/file/write.ts +0 -58
- package/src/tools/search/fuse.ts +0 -96
- package/src/tools/search/index.ts +0 -127
- package/src/tools/search/regexp.ts +0 -82
- package/src/tools/search/semantic.ts +0 -167
- /package/src/{db → utils}/uuid.ts +0 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { isHelpfulError } from "membot";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { applyLinePatches, LinePatchSchema } from "../../fs/patches.ts";
|
|
4
|
+
import type { ToolDefinition } from "../tool.ts";
|
|
5
|
+
|
|
6
|
+
const inputSchema = z.object({
|
|
7
|
+
logical_path: z
|
|
8
|
+
.string()
|
|
9
|
+
.describe("Logical path of the file to edit (e.g. 'notes/foo.md')."),
|
|
10
|
+
patches: z
|
|
11
|
+
.array(LinePatchSchema)
|
|
12
|
+
.min(1)
|
|
13
|
+
.describe(
|
|
14
|
+
"Git-hunk-style edits applied bottom-up. `end_line: 0` inserts; empty `content` deletes.",
|
|
15
|
+
),
|
|
16
|
+
change_note: z
|
|
17
|
+
.string()
|
|
18
|
+
.optional()
|
|
19
|
+
.describe("Free-text note attached to the new version."),
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
const outputSchema = z.object({
|
|
23
|
+
is_error: z.boolean(),
|
|
24
|
+
logical_path: z.string().optional(),
|
|
25
|
+
version_id: z.string().optional(),
|
|
26
|
+
size_bytes: z.number().optional(),
|
|
27
|
+
error_type: z.string().optional(),
|
|
28
|
+
message: z.string().optional(),
|
|
29
|
+
next_action_hint: z.string().optional(),
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
export const membotEditTool = {
|
|
33
|
+
name: "membot_edit",
|
|
34
|
+
description:
|
|
35
|
+
"[[ bash equivalent command: patch ]] Apply line-range edits to a stored file: reads the current version, applies bottom-up patches, and writes the result back as a new version. Prefer this over membot_write when you only need to change part of a file — the diff is small and the change_note travels with the new version. To replace the whole body, use membot_write. To delete the file, use membot_delete.",
|
|
36
|
+
group: "membot",
|
|
37
|
+
inputSchema,
|
|
38
|
+
outputSchema,
|
|
39
|
+
execute: async (input, ctx) => {
|
|
40
|
+
try {
|
|
41
|
+
const current = await ctx.mem.read({ logical_path: input.logical_path });
|
|
42
|
+
const next = applyLinePatches(current.content ?? "", input.patches);
|
|
43
|
+
const result = await ctx.mem.write({
|
|
44
|
+
logical_path: input.logical_path,
|
|
45
|
+
content: next,
|
|
46
|
+
change_note: input.change_note,
|
|
47
|
+
});
|
|
48
|
+
return {
|
|
49
|
+
is_error: false,
|
|
50
|
+
logical_path: result.logical_path,
|
|
51
|
+
version_id: result.version_id,
|
|
52
|
+
size_bytes: result.size_bytes,
|
|
53
|
+
};
|
|
54
|
+
} catch (err) {
|
|
55
|
+
if (isHelpfulError(err)) {
|
|
56
|
+
return {
|
|
57
|
+
is_error: true,
|
|
58
|
+
error_type: err.kind,
|
|
59
|
+
message: err.message,
|
|
60
|
+
next_action_hint: err.hint,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
return {
|
|
64
|
+
is_error: true,
|
|
65
|
+
error_type: "internal_error",
|
|
66
|
+
message: err instanceof Error ? err.message : String(err),
|
|
67
|
+
next_action_hint:
|
|
68
|
+
"Re-read the file with membot_read to confirm current line numbers, then retry.",
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
} satisfies ToolDefinition<typeof inputSchema, typeof outputSchema>;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { isHelpfulError } from "membot";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import type { ToolDefinition } from "../tool.ts";
|
|
4
|
+
|
|
5
|
+
const inputSchema = z.object({
|
|
6
|
+
logical_path: z.string().describe("Logical path to check."),
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
const outputSchema = z.object({
|
|
10
|
+
is_error: z.boolean(),
|
|
11
|
+
exists: z.boolean().optional(),
|
|
12
|
+
logical_path: z.string().optional(),
|
|
13
|
+
error_type: z.string().optional(),
|
|
14
|
+
message: z.string().optional(),
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
export const membotExistsTool = {
|
|
18
|
+
name: "membot_exists",
|
|
19
|
+
description:
|
|
20
|
+
"[[ bash equivalent command: test -e ]] Check whether a logical_path has a current (non-tombstoned) version in the store. Returns `{ exists: true|false }` — never throws on absence. Use before membot_write when you want to avoid clobbering, or to disambiguate a not_found from a real error.",
|
|
21
|
+
group: "membot",
|
|
22
|
+
inputSchema,
|
|
23
|
+
outputSchema,
|
|
24
|
+
execute: async (input, ctx) => {
|
|
25
|
+
try {
|
|
26
|
+
await ctx.mem.info({ logical_path: input.logical_path });
|
|
27
|
+
return {
|
|
28
|
+
is_error: false,
|
|
29
|
+
exists: true,
|
|
30
|
+
logical_path: input.logical_path,
|
|
31
|
+
};
|
|
32
|
+
} catch (err) {
|
|
33
|
+
if (isHelpfulError(err) && err.kind === "not_found") {
|
|
34
|
+
return {
|
|
35
|
+
is_error: false,
|
|
36
|
+
exists: false,
|
|
37
|
+
logical_path: input.logical_path,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
if (isHelpfulError(err)) {
|
|
41
|
+
return {
|
|
42
|
+
is_error: true,
|
|
43
|
+
error_type: err.kind,
|
|
44
|
+
message: err.message,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
48
|
+
is_error: true,
|
|
49
|
+
error_type: "internal_error",
|
|
50
|
+
message: err instanceof Error ? err.message : String(err),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
} satisfies ToolDefinition<typeof inputSchema, typeof outputSchema>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { OPERATIONS } from "membot";
|
|
2
|
+
import { type AnyToolDefinition, registerTool } from "../tool.ts";
|
|
3
|
+
import { adaptOperation } from "./adapter.ts";
|
|
4
|
+
import { membotCopyTool } from "./copy.ts";
|
|
5
|
+
import { membotCountLinesTool } from "./count_lines.ts";
|
|
6
|
+
import { membotEditTool } from "./edit.ts";
|
|
7
|
+
import { membotExistsTool } from "./exists.ts";
|
|
8
|
+
import { membotPipeTool } from "./pipe.ts";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Register every membot operation as a Botholomew tool. The 14 verbs that
|
|
12
|
+
* have a direct membot Operation (add, list, tree, read, search, info,
|
|
13
|
+
* stats, versions, diff, write, move, delete, refresh, prune) are wired via
|
|
14
|
+
* `adaptOperation`; the five Botholomew-side wrappers (edit, copy, exists,
|
|
15
|
+
* count_lines, pipe) bolt on the file-shaped UX our agents already know.
|
|
16
|
+
*/
|
|
17
|
+
export function registerMembotTools(): void {
|
|
18
|
+
for (const op of OPERATIONS) {
|
|
19
|
+
registerTool(adaptOperation(op) as unknown as AnyToolDefinition);
|
|
20
|
+
}
|
|
21
|
+
registerTool(membotEditTool);
|
|
22
|
+
registerTool(membotCopyTool);
|
|
23
|
+
registerTool(membotExistsTool);
|
|
24
|
+
registerTool(membotCountLinesTool);
|
|
25
|
+
registerTool(membotPipeTool);
|
|
26
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import { isHelpfulError } from "membot";
|
|
1
2
|
import { z } from "zod";
|
|
2
|
-
import { PathConflictError, writeContextFile } from "../../context/store.ts";
|
|
3
3
|
import { getTool, type ToolDefinition } from "../tool.ts";
|
|
4
4
|
|
|
5
5
|
const PREVIEW_CHARS = 200;
|
|
6
6
|
const ERROR_MESSAGE_CAP = 2000;
|
|
7
|
-
const TOOL_NAME = "
|
|
7
|
+
const TOOL_NAME = "membot_pipe";
|
|
8
8
|
|
|
9
9
|
function truncate(s: string, cap: number): string {
|
|
10
10
|
if (s.length <= cap) return s;
|
|
@@ -15,29 +15,28 @@ const inputSchema = z.object({
|
|
|
15
15
|
tool_name: z
|
|
16
16
|
.string()
|
|
17
17
|
.describe(
|
|
18
|
-
"Name of the tool to dispatch. Its full output is
|
|
18
|
+
"Name of the tool to dispatch. Its full output is captured and written to membot under `logical_path`; you (the LLM) only see the storage acknowledgment, never the raw bytes.",
|
|
19
19
|
),
|
|
20
20
|
tool_input: z
|
|
21
21
|
.record(z.string(), z.unknown())
|
|
22
22
|
.describe(
|
|
23
23
|
"Arguments to pass to the inner tool (same shape as a normal call).",
|
|
24
24
|
),
|
|
25
|
-
|
|
25
|
+
logical_path: z
|
|
26
26
|
.string()
|
|
27
27
|
.describe(
|
|
28
|
-
"
|
|
28
|
+
"Destination logical_path under which to store the captured output (e.g. 'gdoc/quarterly-plan.md'). Creates a new version on every call.",
|
|
29
29
|
),
|
|
30
|
-
|
|
31
|
-
.
|
|
30
|
+
change_note: z
|
|
31
|
+
.string()
|
|
32
32
|
.optional()
|
|
33
|
-
.describe(
|
|
34
|
-
"What to do if a file already exists at this path. Defaults to 'error'. Pass 'overwrite' to replace.",
|
|
35
|
-
),
|
|
33
|
+
.describe("Free-text note attached to the new version."),
|
|
36
34
|
});
|
|
37
35
|
|
|
38
36
|
const outputSchema = z.object({
|
|
39
37
|
is_error: z.boolean(),
|
|
40
|
-
|
|
38
|
+
logical_path: z.string().optional(),
|
|
39
|
+
version_id: z.string().optional(),
|
|
41
40
|
bytes_written: z.number().optional(),
|
|
42
41
|
preview: z
|
|
43
42
|
.string()
|
|
@@ -52,18 +51,19 @@ const outputSchema = z.object({
|
|
|
52
51
|
"forbidden_tool",
|
|
53
52
|
"invalid_input",
|
|
54
53
|
"inner_tool_error",
|
|
55
|
-
"
|
|
54
|
+
"write_failed",
|
|
55
|
+
"internal_error",
|
|
56
56
|
])
|
|
57
57
|
.optional(),
|
|
58
58
|
message: z.string().optional(),
|
|
59
59
|
next_action_hint: z.string().optional(),
|
|
60
60
|
});
|
|
61
61
|
|
|
62
|
-
export const
|
|
62
|
+
export const membotPipeTool = {
|
|
63
63
|
name: TOOL_NAME,
|
|
64
64
|
description:
|
|
65
|
-
"[[ bash equivalent command: cmd > file ]] Run another tool and pipe its full output directly into a
|
|
66
|
-
group: "
|
|
65
|
+
"[[ bash equivalent command: cmd > file ]] Run another tool and pipe its full output directly into a membot logical_path, without the result flowing through the conversation. Use this when you need a large tool output (Google Docs via mcp_exec, web fetches, search dumps) captured for later inspection but you do NOT need to read the bytes yourself. You'll only see the storage ack (logical_path, version_id, short preview).",
|
|
66
|
+
group: "membot",
|
|
67
67
|
inputSchema,
|
|
68
68
|
outputSchema,
|
|
69
69
|
execute: async (input, ctx) => {
|
|
@@ -82,9 +82,9 @@ export const pipeToContextTool = {
|
|
|
82
82
|
return {
|
|
83
83
|
is_error: true,
|
|
84
84
|
error_type: "forbidden_tool",
|
|
85
|
-
message: `Tool "${inner.name}" cannot be piped (terminal tools and
|
|
85
|
+
message: `Tool "${inner.name}" cannot be piped (terminal tools and ${TOOL_NAME} itself are not allowed).`,
|
|
86
86
|
next_action_hint:
|
|
87
|
-
"Pipe a non-terminal tool (
|
|
87
|
+
"Pipe a non-terminal tool (mcp_exec, membot_read, etc.) instead.",
|
|
88
88
|
};
|
|
89
89
|
}
|
|
90
90
|
|
|
@@ -143,30 +143,32 @@ export const pipeToContextTool = {
|
|
|
143
143
|
}
|
|
144
144
|
|
|
145
145
|
try {
|
|
146
|
-
const
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
);
|
|
146
|
+
const written = await ctx.mem.write({
|
|
147
|
+
logical_path: input.logical_path,
|
|
148
|
+
content: innerOutput,
|
|
149
|
+
change_note: input.change_note,
|
|
150
|
+
});
|
|
152
151
|
return {
|
|
153
152
|
is_error: false,
|
|
154
|
-
|
|
155
|
-
|
|
153
|
+
logical_path: written.logical_path,
|
|
154
|
+
version_id: written.version_id,
|
|
155
|
+
bytes_written: written.size_bytes,
|
|
156
156
|
preview: innerOutput.slice(0, PREVIEW_CHARS),
|
|
157
157
|
};
|
|
158
158
|
} catch (err) {
|
|
159
|
-
if (err
|
|
159
|
+
if (isHelpfulError(err)) {
|
|
160
160
|
return {
|
|
161
161
|
is_error: true,
|
|
162
|
-
error_type: "
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
next_action_hint:
|
|
166
|
-
"Retry with on_conflict='overwrite' to replace, or pick a different path.",
|
|
162
|
+
error_type: "write_failed",
|
|
163
|
+
message: `Inner tool ran, but write to ${input.logical_path} failed: ${err.message}`,
|
|
164
|
+
next_action_hint: err.hint,
|
|
167
165
|
};
|
|
168
166
|
}
|
|
169
|
-
|
|
167
|
+
return {
|
|
168
|
+
is_error: true,
|
|
169
|
+
error_type: "internal_error",
|
|
170
|
+
message: err instanceof Error ? err.message : String(err),
|
|
171
|
+
};
|
|
170
172
|
}
|
|
171
173
|
},
|
|
172
174
|
} satisfies ToolDefinition<typeof inputSchema, typeof outputSchema>;
|
package/src/tools/registry.ts
CHANGED
|
@@ -1,27 +1,12 @@
|
|
|
1
1
|
// Capabilities tools
|
|
2
2
|
import { capabilitiesRefreshTool } from "./capabilities/refresh.ts";
|
|
3
|
-
// Context tools
|
|
4
|
-
import { pipeToContextTool } from "./context/pipe.ts";
|
|
5
|
-
import { readLargeResultTool } from "./context/read-large-result.ts";
|
|
6
|
-
// Context — directory operations
|
|
7
|
-
import { contextCreateDirTool } from "./dir/create.ts";
|
|
8
|
-
import { contextDirSizeTool } from "./dir/size.ts";
|
|
9
|
-
import { contextTreeTool } from "./dir/tree.ts";
|
|
10
|
-
// Context — file operations
|
|
11
|
-
import { contextCopyTool } from "./file/copy.ts";
|
|
12
|
-
import { contextCountLinesTool } from "./file/count-lines.ts";
|
|
13
|
-
import { contextDeleteTool } from "./file/delete.ts";
|
|
14
|
-
import { contextEditTool } from "./file/edit.ts";
|
|
15
|
-
import { contextExistsTool } from "./file/exists.ts";
|
|
16
|
-
import { contextInfoTool } from "./file/info.ts";
|
|
17
|
-
import { contextMoveTool } from "./file/move.ts";
|
|
18
|
-
import { contextReadTool } from "./file/read.ts";
|
|
19
|
-
import { contextWriteTool } from "./file/write.ts";
|
|
20
3
|
// MCP tools
|
|
21
4
|
import { mcpExecTool } from "./mcp/exec.ts";
|
|
22
5
|
import { mcpInfoTool } from "./mcp/info.ts";
|
|
23
6
|
import { mcpListToolsTool } from "./mcp/list-tools.ts";
|
|
24
7
|
import { mcpSearchTool } from "./mcp/search.ts";
|
|
8
|
+
// Membot tools (knowledge store)
|
|
9
|
+
import { registerMembotTools } from "./membot/index.ts";
|
|
25
10
|
// Prompt tools
|
|
26
11
|
import { promptCreateTool } from "./prompt/create.ts";
|
|
27
12
|
import { promptDeleteTool } from "./prompt/delete.ts";
|
|
@@ -32,8 +17,6 @@ import { promptReadTool } from "./prompt/read.ts";
|
|
|
32
17
|
import { createScheduleTool } from "./schedule/create.ts";
|
|
33
18
|
import { scheduleEditTool } from "./schedule/edit.ts";
|
|
34
19
|
import { listSchedulesTool } from "./schedule/list.ts";
|
|
35
|
-
// Search tools
|
|
36
|
-
import { searchTool } from "./search/index.ts";
|
|
37
20
|
// Skill tools
|
|
38
21
|
import { skillDeleteTool } from "./skill/delete.ts";
|
|
39
22
|
import { skillEditTool } from "./skill/edit.ts";
|
|
@@ -73,26 +56,15 @@ export function registerAllTools(): void {
|
|
|
73
56
|
registerTool(listTasksTool);
|
|
74
57
|
registerTool(viewTaskTool);
|
|
75
58
|
|
|
76
|
-
//
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
registerTool(contextReadTool);
|
|
81
|
-
registerTool(contextWriteTool);
|
|
82
|
-
registerTool(contextEditTool);
|
|
83
|
-
registerTool(contextDeleteTool);
|
|
84
|
-
registerTool(contextCopyTool);
|
|
85
|
-
registerTool(contextMoveTool);
|
|
86
|
-
registerTool(contextInfoTool);
|
|
87
|
-
registerTool(contextExistsTool);
|
|
88
|
-
registerTool(contextCountLinesTool);
|
|
59
|
+
// Knowledge store (membot) — add/read/write/edit/search/versions/refresh etc.
|
|
60
|
+
registerMembotTools();
|
|
61
|
+
|
|
62
|
+
// Prompts
|
|
89
63
|
registerTool(promptListTool);
|
|
90
64
|
registerTool(promptReadTool);
|
|
91
65
|
registerTool(promptCreateTool);
|
|
92
66
|
registerTool(promptEditTool);
|
|
93
67
|
registerTool(promptDeleteTool);
|
|
94
|
-
registerTool(readLargeResultTool);
|
|
95
|
-
registerTool(pipeToContextTool);
|
|
96
68
|
|
|
97
69
|
// Capabilities
|
|
98
70
|
registerTool(capabilitiesRefreshTool);
|
|
@@ -102,9 +74,6 @@ export function registerAllTools(): void {
|
|
|
102
74
|
registerTool(scheduleEditTool);
|
|
103
75
|
registerTool(listSchedulesTool);
|
|
104
76
|
|
|
105
|
-
// Search
|
|
106
|
-
registerTool(searchTool);
|
|
107
|
-
|
|
108
77
|
// Skill
|
|
109
78
|
registerTool(skillListTool);
|
|
110
79
|
registerTool(skillReadTool);
|
package/src/tools/tool.ts
CHANGED
|
@@ -1,19 +1,17 @@
|
|
|
1
1
|
import type { Tool as AnthropicTool } from "@anthropic-ai/sdk/resources/messages";
|
|
2
2
|
import type { McpxClient } from "@evantahler/mcpx";
|
|
3
|
+
import type { MembotClient } from "membot";
|
|
3
4
|
import { z } from "zod";
|
|
4
5
|
import type { BotholomewConfig } from "../config/schemas.ts";
|
|
5
|
-
import type { DbConnection } from "../db/connection.ts";
|
|
6
6
|
|
|
7
7
|
export interface ToolContext {
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
9
|
+
* Per-process membot client. Backs every `membot_*` tool. Membot manages
|
|
10
|
+
* its own DuckDB connection lifecycle internally (lazy claim, release
|
|
11
|
+
* between operations), so tools just call `ctx.mem.<op>(...)` directly —
|
|
12
|
+
* no per-call open/close needed.
|
|
13
13
|
*/
|
|
14
|
-
|
|
15
|
-
/** Path to the DuckDB file. Use with `withDb` for long-running tools. */
|
|
16
|
-
dbPath: string;
|
|
14
|
+
mem: MembotClient;
|
|
17
15
|
projectDir: string;
|
|
18
16
|
config: Required<BotholomewConfig>;
|
|
19
17
|
mcpxClient: McpxClient | null;
|
package/src/tui/App.tsx
CHANGED
|
@@ -186,18 +186,17 @@ function AppInner({
|
|
|
186
186
|
setUsage,
|
|
187
187
|
});
|
|
188
188
|
|
|
189
|
-
const
|
|
189
|
+
const sessionReady = sessionRef.current != null;
|
|
190
190
|
const inputBarHeader = useMemo(
|
|
191
191
|
() =>
|
|
192
|
-
|
|
192
|
+
sessionReady ? (
|
|
193
193
|
<StatusBar
|
|
194
194
|
projectDir={projectDir}
|
|
195
|
-
dbPath={sessionDbPath}
|
|
196
195
|
chatTitle={chatTitle}
|
|
197
196
|
onWorkerStatusChange={setWorkerRunning}
|
|
198
197
|
/>
|
|
199
198
|
) : null,
|
|
200
|
-
[projectDir,
|
|
199
|
+
[projectDir, sessionReady, chatTitle],
|
|
201
200
|
);
|
|
202
201
|
|
|
203
202
|
const allToolCalls = useMemo(
|