botholomew 0.18.1 → 0.18.2
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 +3 -8
- package/package.json +10 -10
- package/src/cli.ts +2 -2
- package/src/commands/{context.ts → membot.ts} +13 -13
- package/src/tools/membot/adapter.ts +1 -1
- package/src/tui/components/ContextPanel.tsx +18 -8
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@ agent's world is a per-project knowledge store managed by
|
|
|
19
19
|
search, and delete is addressed by `logical_path` (a DB key, not a
|
|
20
20
|
filesystem path), so a prompt-injected attempt to reach `~/.ssh/id_rsa`
|
|
21
21
|
has nowhere to land. Local files and URLs are brought in through
|
|
22
|
-
`botholomew
|
|
22
|
+
`botholomew membot add`. External capabilities (email, Slack, the web,
|
|
23
23
|
and hundreds of other services) are granted deliberately, per project,
|
|
24
24
|
through MCP servers wired up via
|
|
25
25
|
[MCPX](https://github.com/evantahler/mcpx).
|
|
@@ -165,11 +165,6 @@ semantic search, append-only versioning, and URL refresh all live there.
|
|
|
165
165
|
|
|
166
166
|

|
|
167
167
|
|
|
168
|
-
Pulling a remote document straight into the knowledge store via an
|
|
169
|
-
LLM-driven fetcher (`mcp_search` → `mcp_exec` → `membot_pipe`):
|
|
170
|
-
|
|
171
|
-

|
|
172
|
-
|
|
173
168
|
| Command | Purpose |
|
|
174
169
|
|---|---|
|
|
175
170
|
| `botholomew init` | Initialize the current directory as a project (refuses on iCloud/Dropbox/NFS without `--force`) |
|
|
@@ -178,8 +173,8 @@ LLM-driven fetcher (`mcp_search` → `mcp_exec` → `membot_pipe`):
|
|
|
178
173
|
| `botholomew chat` | Interactive Ink/React TUI |
|
|
179
174
|
| `botholomew task list\|add\|view\|update\|reset\|delete` | Manage the task queue (markdown files in `tasks/`) |
|
|
180
175
|
| `botholomew schedule list\|add\|view\|enable\|disable\|trigger\|delete` | Recurring work (markdown files in `schedules/`) |
|
|
181
|
-
| `botholomew
|
|
182
|
-
| `botholomew
|
|
176
|
+
| `botholomew membot add\|ls\|tree\|read\|write\|search\|info\|versions\|diff\|refresh\|…` | Knowledge-store passthrough to [`membot`](https://github.com/evantahler/membot) — `--config` is resolved from `membot_scope` (default `~/.membot`) |
|
|
177
|
+
| `botholomew membot import-global` | Seed the project from `~/.membot` (copies `index.duckdb` + `config.json` in) |
|
|
183
178
|
| `botholomew capabilities` | Rescan built-in + MCPX tools and rewrite `prompts/capabilities.md` |
|
|
184
179
|
| `botholomew prompts list\|show\|create\|edit\|delete\|validate` | CRUD over the markdown files in `prompts/` (with strict frontmatter validation) |
|
|
185
180
|
| `botholomew mcpx servers\|list\|add\|remove\|info\|search\|exec\|ping\|auth\|deauth\|import-global\|…` | Configure external MCP servers (passthrough to `mcpx`) |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "botholomew",
|
|
3
|
-
"version": "0.18.
|
|
3
|
+
"version": "0.18.2",
|
|
4
4
|
"description": "An autonomous AI agent for knowledge work — works your task queue while you sleep.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -27,31 +27,31 @@
|
|
|
27
27
|
"docs:preview": "vitepress preview docs"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@anthropic-ai/sdk": "^0.
|
|
31
|
-
"@evantahler/mcpx": "0.21.
|
|
32
|
-
"ansis": "^4.
|
|
30
|
+
"@anthropic-ai/sdk": "^0.95.2",
|
|
31
|
+
"@evantahler/mcpx": "0.21.7",
|
|
32
|
+
"ansis": "^4.3.0",
|
|
33
33
|
"commander": "^14.0.0",
|
|
34
34
|
"gray-matter": "^4.0.3",
|
|
35
35
|
"ink": "^7.0.1",
|
|
36
36
|
"ink-spinner": "^5.0.0",
|
|
37
37
|
"ink-text-input": "^6.0.0",
|
|
38
38
|
"istextorbinary": "^9.5.0",
|
|
39
|
-
"membot": "^0.
|
|
39
|
+
"membot": "^0.15.0",
|
|
40
40
|
"nanospinner": "^1.2.2",
|
|
41
|
-
"react": "^19.2.
|
|
41
|
+
"react": "^19.2.6",
|
|
42
42
|
"uuid": "^14.0.0",
|
|
43
43
|
"wrap-ansi": "^10.0.0",
|
|
44
|
-
"zod": "^4.4.
|
|
44
|
+
"zod": "^4.4.3"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"@biomejs/biome": "^2.4.
|
|
47
|
+
"@biomejs/biome": "^2.4.15",
|
|
48
48
|
"@types/bun": "latest",
|
|
49
49
|
"@types/react": "^19.2.0",
|
|
50
50
|
"@types/uuid": "^11.0.0",
|
|
51
51
|
"typescript": "^6.0.3",
|
|
52
52
|
"vitepress": "^1.5.0",
|
|
53
|
-
"vitepress-plugin-llms": "^1.12.
|
|
54
|
-
"vue": "^3.5.
|
|
53
|
+
"vitepress-plugin-llms": "^1.12.2",
|
|
54
|
+
"vue": "^3.5.34"
|
|
55
55
|
},
|
|
56
56
|
"trustedDependencies": [
|
|
57
57
|
"protobufjs"
|
package/src/cli.ts
CHANGED
|
@@ -5,9 +5,9 @@ import { program } from "commander";
|
|
|
5
5
|
import { registerCapabilitiesCommand } from "./commands/capabilities.ts";
|
|
6
6
|
import { registerChatCommand } from "./commands/chat.ts";
|
|
7
7
|
import { registerCheckUpdateCommand } from "./commands/check-update.ts";
|
|
8
|
-
import { registerContextCommand } from "./commands/context.ts";
|
|
9
8
|
import { registerInitCommand } from "./commands/init.ts";
|
|
10
9
|
import { registerMcpxCommand } from "./commands/mcpx.ts";
|
|
10
|
+
import { registerMembotCommand } from "./commands/membot.ts";
|
|
11
11
|
import { registerNukeCommand } from "./commands/nuke.ts";
|
|
12
12
|
import { registerPrepareCommand } from "./commands/prepare.ts";
|
|
13
13
|
import { registerPromptsCommand } from "./commands/prompts.ts";
|
|
@@ -44,7 +44,7 @@ registerTaskCommand(program);
|
|
|
44
44
|
registerThreadCommand(program);
|
|
45
45
|
registerScheduleCommand(program);
|
|
46
46
|
registerChatCommand(program);
|
|
47
|
-
|
|
47
|
+
registerMembotCommand(program);
|
|
48
48
|
registerCapabilitiesCommand(program);
|
|
49
49
|
registerPromptsCommand(program);
|
|
50
50
|
registerMcpxCommand(program);
|
|
@@ -29,11 +29,11 @@ function getDir(program: Command): string {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
/**
|
|
32
|
-
* Slice process.argv from the token after "
|
|
32
|
+
* Slice process.argv from the token after "membot" so flags (including
|
|
33
33
|
* --help) and positional args flow through to upstream membot verbatim.
|
|
34
34
|
*/
|
|
35
|
-
function
|
|
36
|
-
const idx = process.argv.indexOf("
|
|
35
|
+
function getRawMembotArgs(): string[] {
|
|
36
|
+
const idx = process.argv.indexOf("membot");
|
|
37
37
|
return idx === -1 ? [] : process.argv.slice(idx + 1);
|
|
38
38
|
}
|
|
39
39
|
|
|
@@ -121,37 +121,37 @@ function registerImportGlobal(parent: Command, program: Command): void {
|
|
|
121
121
|
});
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
-
export function
|
|
125
|
-
const
|
|
126
|
-
.command("
|
|
124
|
+
export function registerMembotCommand(program: Command) {
|
|
125
|
+
const membot = program
|
|
126
|
+
.command("membot")
|
|
127
127
|
.description(
|
|
128
|
-
"Manage the project's knowledge store
|
|
128
|
+
"Manage the project's knowledge store (passthrough to membot: add, search, ls, read, …)",
|
|
129
129
|
);
|
|
130
130
|
|
|
131
131
|
// Botholomew-specific helpers first so they show up before the membot
|
|
132
132
|
// passthrough subcommands in --help.
|
|
133
|
-
registerImportGlobal(
|
|
133
|
+
registerImportGlobal(membot, program);
|
|
134
134
|
|
|
135
135
|
// One Commander subcommand per membot Operation. We don't redeclare any
|
|
136
136
|
// flags — Commander hands the raw argv slice to membot, which owns the
|
|
137
137
|
// canonical schema.
|
|
138
138
|
for (const op of OPERATIONS) {
|
|
139
139
|
const name = defaultCliName(op);
|
|
140
|
-
|
|
140
|
+
membot
|
|
141
141
|
.command(name)
|
|
142
142
|
.description(op.description.split("\n")[0] ?? op.description)
|
|
143
143
|
.allowUnknownOption(true)
|
|
144
144
|
.helpOption(false)
|
|
145
145
|
.argument("[args...]", "arguments forwarded to membot")
|
|
146
146
|
.action(async () => {
|
|
147
|
-
const exitCode = await runMembot(getDir(program),
|
|
147
|
+
const exitCode = await runMembot(getDir(program), getRawMembotArgs());
|
|
148
148
|
if (exitCode !== 0) process.exit(exitCode);
|
|
149
149
|
});
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
-
// `botholomew
|
|
153
|
-
|
|
154
|
-
const exitCode = await runMembot(getDir(program),
|
|
152
|
+
// `botholomew membot` (no subcommand) → membot's default action.
|
|
153
|
+
membot.action(async () => {
|
|
154
|
+
const exitCode = await runMembot(getDir(program), getRawMembotArgs());
|
|
155
155
|
if (exitCode !== 0) process.exit(exitCode);
|
|
156
156
|
});
|
|
157
157
|
}
|
|
@@ -103,7 +103,7 @@ export function adaptOperation(
|
|
|
103
103
|
error_type: "internal_error",
|
|
104
104
|
message: err instanceof Error ? err.message : String(err),
|
|
105
105
|
next_action_hint:
|
|
106
|
-
"Check the project's membot store (run `botholomew
|
|
106
|
+
"Check the project's membot store (run `botholomew membot stats`) and try again. If this persists, file a bug.",
|
|
107
107
|
};
|
|
108
108
|
}
|
|
109
109
|
},
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { Box, Text, useInput } from "ink";
|
|
2
2
|
import type { MembotClient } from "membot";
|
|
3
3
|
import { memo, useCallback, useEffect, useMemo, useState } from "react";
|
|
4
|
-
import {
|
|
4
|
+
import { loadConfig } from "../../config/loader.ts";
|
|
5
|
+
import { openMembot, resolveMembotDir } from "../../mem/client.ts";
|
|
5
6
|
import {
|
|
6
7
|
detailPaneBorderProps,
|
|
7
8
|
type FocusState,
|
|
@@ -36,8 +37,8 @@ const PAGE_SCROLL_LINES = 10;
|
|
|
36
37
|
* Browse the membot knowledge store. Each row is a current-version entry; the
|
|
37
38
|
* detail pane shows the cleaned markdown surrogate. Membot has no real
|
|
38
39
|
* directories — `logical_path` segments are just slashes — so this is a flat
|
|
39
|
-
* paginated list rather than a tree drill-in. Use `botholomew
|
|
40
|
-
* `botholomew
|
|
40
|
+
* paginated list rather than a tree drill-in. Use `botholomew membot tree` /
|
|
41
|
+
* `botholomew membot search` for hierarchical or content-based discovery.
|
|
41
42
|
*/
|
|
42
43
|
export const ContextPanel = memo(function ContextPanel({
|
|
43
44
|
projectDir,
|
|
@@ -47,13 +48,22 @@ export const ContextPanel = memo(function ContextPanel({
|
|
|
47
48
|
const detailWidth = Math.max(1, termCols - SIDEBAR_WIDTH - 5);
|
|
48
49
|
|
|
49
50
|
// One MembotClient per panel mount. Membot manages its DB lock per-op so
|
|
50
|
-
// sharing the file with the chat session / workers is safe.
|
|
51
|
+
// sharing the file with the chat session / workers is safe. The data dir is
|
|
52
|
+
// resolved from `membot_scope` (global → ~/.membot, project → <projectDir>)
|
|
53
|
+
// so the tab agrees with the worker / chat session / CLI.
|
|
51
54
|
const [client, setClient] = useState<MembotClient | null>(null);
|
|
52
55
|
useEffect(() => {
|
|
53
|
-
|
|
54
|
-
|
|
56
|
+
let cancelled = false;
|
|
57
|
+
let opened: MembotClient | null = null;
|
|
58
|
+
(async () => {
|
|
59
|
+
const config = await loadConfig(projectDir);
|
|
60
|
+
if (cancelled) return;
|
|
61
|
+
opened = openMembot(resolveMembotDir(projectDir, config));
|
|
62
|
+
setClient(opened);
|
|
63
|
+
})();
|
|
55
64
|
return () => {
|
|
56
|
-
|
|
65
|
+
cancelled = true;
|
|
66
|
+
if (opened) void opened.close();
|
|
57
67
|
};
|
|
58
68
|
}, [projectDir]);
|
|
59
69
|
|
|
@@ -227,7 +237,7 @@ export const ContextPanel = memo(function ContextPanel({
|
|
|
227
237
|
</Box>
|
|
228
238
|
{entries.length === 0 ? (
|
|
229
239
|
<Box paddingX={1}>
|
|
230
|
-
<Text dimColor>(empty — try `botholomew
|
|
240
|
+
<Text dimColor>(empty — try `botholomew membot add …`)</Text>
|
|
231
241
|
</Box>
|
|
232
242
|
) : (
|
|
233
243
|
visibleItems.map((entry, vi) => {
|