botholomew 0.6.3 → 0.7.1
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 +218 -1
- package/package.json +1 -1
- package/src/commands/chat.ts +1 -1
- package/src/commands/context.ts +227 -66
- package/src/context/chunker.ts +98 -1
- package/src/context/fetcher.ts +436 -0
- package/src/context/url-utils.ts +48 -0
- package/src/db/context.ts +8 -2
- package/src/db/sql/9-source-type.sql +1 -0
- package/src/skills/commands.ts +12 -1
- package/src/tui/App.tsx +33 -18
- package/src/tui/components/HelpPanel.tsx +1 -1
- package/src/tui/components/InputBar.tsx +176 -99
- package/src/tui/components/SlashCommandPopup.tsx +50 -0
- package/src/tui/slashCompletion.ts +38 -0
package/README.md
CHANGED
|
@@ -6,4 +6,221 @@
|
|
|
6
6
|
" "
|
|
7
7
|
```
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
**A local-first AI agent for knowledge work.** Botholomew is a long-running
|
|
10
|
+
autonomous agent that works its way through a task queue — reading email,
|
|
11
|
+
summarizing documents, researching topics, organizing notes, and maintaining
|
|
12
|
+
context over time — while you sleep, work, or chat with it.
|
|
13
|
+
|
|
14
|
+
Unlike coding agents, Botholomew has **no shell, no filesystem, and no network
|
|
15
|
+
tools** by default. Everything it touches lives inside a single DuckDB database
|
|
16
|
+
at `.botholomew/data.duckdb` and a handful of markdown files. External access
|
|
17
|
+
is granted deliberately, per project, through MCP servers.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Why Botholomew?
|
|
22
|
+
|
|
23
|
+
- **Autonomous.** A background daemon ticks on a schedule, claims tasks,
|
|
24
|
+
works them with Claude, and logs every interaction. You can close the
|
|
25
|
+
terminal and come back later.
|
|
26
|
+
- **Portable.** Each project is a `.botholomew/` directory — markdown +
|
|
27
|
+
DuckDB. Copy it, share it, check it in (or `.gitignore` it).
|
|
28
|
+
- **Local-first.** All data stays on your machine. Embeddings are indexed in
|
|
29
|
+
DuckDB's native vector store with HNSW. Model calls go direct to Anthropic
|
|
30
|
+
and OpenAI.
|
|
31
|
+
- **Extensible.** External tools come from MCP servers via
|
|
32
|
+
[MCPX](https://github.com/evantahler/mcpx) — run them locally (Gmail,
|
|
33
|
+
Slack, GitHub) or connect through an MCP gateway like
|
|
34
|
+
[Arcade.dev](https://www.arcade.dev/) to reach hundreds of
|
|
35
|
+
authenticated services without managing each server yourself.
|
|
36
|
+
Reusable workflows are defined as markdown "skills" (slash commands).
|
|
37
|
+
- **Safe by default.** The agent has no shell, no network, and no
|
|
38
|
+
filesystem access of its own. Everything it can touch lives in
|
|
39
|
+
`.botholomew/` — and every external capability is something you
|
|
40
|
+
explicitly add.
|
|
41
|
+
- **Self-healing.** An OS-level watchdog (launchd on macOS, systemd on Linux)
|
|
42
|
+
restarts the daemon if it dies, rotates logs, and runs on boot.
|
|
43
|
+
- **Self-modifying.** The agent maintains its own `beliefs.md` and
|
|
44
|
+
`goals.md` — it learns, updates its priors, and revises its goals as it
|
|
45
|
+
works.
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Install
|
|
50
|
+
|
|
51
|
+
Requires [Bun](https://bun.sh) 1.1+.
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
bun install -g botholomew
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Or run the dev build from a checkout:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
git clone https://github.com/evantahler/botholomew
|
|
61
|
+
cd botholomew
|
|
62
|
+
bun install
|
|
63
|
+
bun run dev -- --help
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Quickstart
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
# 1. Initialize a project in the current directory
|
|
72
|
+
botholomew init
|
|
73
|
+
|
|
74
|
+
# 2. Add your API keys to .botholomew/config.json, or export env vars
|
|
75
|
+
export ANTHROPIC_API_KEY=sk-ant-...
|
|
76
|
+
export OPENAI_API_KEY=sk-... # used for embeddings
|
|
77
|
+
|
|
78
|
+
# 3. Queue some work
|
|
79
|
+
botholomew task add "Summarize every markdown file in ~/notes"
|
|
80
|
+
|
|
81
|
+
# 4. Start the daemon (foreground — watch it work)
|
|
82
|
+
botholomew daemon start --foreground
|
|
83
|
+
|
|
84
|
+
# 5. Or chat with the agent interactively
|
|
85
|
+
botholomew chat
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## What a project looks like
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
my-project/
|
|
94
|
+
.botholomew/
|
|
95
|
+
soul.md # always-loaded identity (not agent-editable)
|
|
96
|
+
beliefs.md # always-loaded, agent-editable priors
|
|
97
|
+
goals.md # always-loaded, agent-editable goals
|
|
98
|
+
config.json # models, tick interval, API keys
|
|
99
|
+
data.duckdb # tasks, schedules, context, embeddings, logs
|
|
100
|
+
mcpx/servers.json # external MCP servers (Gmail, Slack, …)
|
|
101
|
+
skills/ # user-defined slash commands
|
|
102
|
+
summarize.md
|
|
103
|
+
standup.md
|
|
104
|
+
daemon.pid # PID file for the running daemon
|
|
105
|
+
daemon.log # rotating daemon logs
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Everything the agent can touch is here. No surprises.
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## The CLI
|
|
113
|
+
|
|
114
|
+
| Command | Purpose |
|
|
115
|
+
|---|---|
|
|
116
|
+
| `botholomew init` | Create `.botholomew/` with templates and a fresh database |
|
|
117
|
+
| `botholomew daemon start\|stop\|status` | Run, stop, or inspect the daemon |
|
|
118
|
+
| `botholomew daemon install\|uninstall` | Register/remove the OS watchdog |
|
|
119
|
+
| `botholomew daemon list` | List all Botholomew projects on this machine |
|
|
120
|
+
| `botholomew chat` | Interactive Ink/React TUI |
|
|
121
|
+
| `botholomew task list\|add\|view\|update\|reset\|delete` | Manage the task queue |
|
|
122
|
+
| `botholomew schedule list\|add\|enable\|trigger\|delete` | Recurring work |
|
|
123
|
+
| `botholomew context add\|list\|view\|search\|refresh\|remove` | Ingest & browse knowledge (files, folders, URLs) |
|
|
124
|
+
| `botholomew mcpx add\|list\|tools\|test` | Configure external MCP servers |
|
|
125
|
+
| `botholomew skill list\|show\|create` | Manage slash-command skills |
|
|
126
|
+
| `botholomew file\|dir\|search ...` | Direct access to the agent's virtual filesystem |
|
|
127
|
+
| `botholomew thread list\|view` | Browse the agent's interaction history |
|
|
128
|
+
| `botholomew upgrade` | Self-update |
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## How it works
|
|
133
|
+
|
|
134
|
+
```
|
|
135
|
+
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
|
|
136
|
+
│ Chat │ │ Daemon │ │ Watchdog │
|
|
137
|
+
│ (Ink TUI) │ │ (tick loop) │ │ launchd/ │
|
|
138
|
+
│ │ │ │ │ systemd │
|
|
139
|
+
└──────┬───────┘ └──────┬───────┘ └──────┬───────┘
|
|
140
|
+
│ │ │
|
|
141
|
+
│ enqueue tasks │ claims tasks │ every 60s:
|
|
142
|
+
│ browse history │ runs LLM tool loops │ check PID
|
|
143
|
+
│ invoke skills │ updates status │ restart if
|
|
144
|
+
│ │ logs to threads │ dead
|
|
145
|
+
│ │ │
|
|
146
|
+
└────────────┬───────────┴────────────┬───────────┘
|
|
147
|
+
│ │
|
|
148
|
+
┌─────▼────────────────────────▼─────┐
|
|
149
|
+
│ DuckDB │
|
|
150
|
+
│ ┌───────────┐ ┌──────────────┐ │
|
|
151
|
+
│ │ tasks │ │ context_items│ │
|
|
152
|
+
│ │ schedules │ │ embeddings │ │
|
|
153
|
+
│ │ threads │ │ (HNSW) │ │
|
|
154
|
+
│ └───────────┘ └──────────────┘ │
|
|
155
|
+
└─────┬───────────────────────────────┘
|
|
156
|
+
│
|
|
157
|
+
▼
|
|
158
|
+
MCPX ─► Gmail, Slack, GitHub, Firecrawl, …
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
See [docs/architecture.md](docs/architecture.md) for a deeper tour.
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## Deep dives
|
|
166
|
+
|
|
167
|
+
Topics worth understanding in detail:
|
|
168
|
+
|
|
169
|
+
- **[Architecture](docs/architecture.md)** — daemon, chat, watchdog, and how
|
|
170
|
+
they share a database.
|
|
171
|
+
- **[The virtual filesystem](docs/virtual-filesystem.md)** — why the agent's
|
|
172
|
+
"files" are actually DuckDB rows, and how `file_read`/`file_write` work.
|
|
173
|
+
- **[Context & hybrid search](docs/context-and-search.md)** — LLM-driven
|
|
174
|
+
chunking, OpenAI embeddings, and DuckDB's HNSW-accelerated keyword +
|
|
175
|
+
vector search.
|
|
176
|
+
- **[Tasks & schedules](docs/tasks-and-schedules.md)** — the claim loop, DAG
|
|
177
|
+
validation, stale-task recovery, and natural-language recurring schedules.
|
|
178
|
+
- **[The Tool class](docs/tools.md)** — one Zod definition, three consumers
|
|
179
|
+
(Anthropic tool-use, Commander CLI, tests).
|
|
180
|
+
- **[Persistent context](docs/persistent-context.md)** — `soul.md`,
|
|
181
|
+
`beliefs.md`, `goals.md`, frontmatter flags, and agent self-modification.
|
|
182
|
+
- **[Skills (slash commands)](docs/skills.md)** — reusable prompt templates
|
|
183
|
+
with positional arguments and tab completion.
|
|
184
|
+
- **[MCPX integration](docs/mcpx.md)** — configuring external servers and
|
|
185
|
+
how MCP tools are merged into the agent's toolset.
|
|
186
|
+
- **[The watchdog](docs/watchdog.md)** — launchd plists, systemd units, and
|
|
187
|
+
multi-project service naming.
|
|
188
|
+
- **[Configuration](docs/configuration.md)** — every key in `config.json`
|
|
189
|
+
and its default.
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## Tech stack
|
|
194
|
+
|
|
195
|
+
- **[Bun](https://bun.sh)** + TypeScript
|
|
196
|
+
- **[DuckDB](https://duckdb.org)** via `@duckdb/node-api`, with the
|
|
197
|
+
**[VSS extension](https://duckdb.org/docs/stable/extensions/vss)** for
|
|
198
|
+
native vector search
|
|
199
|
+
- **[Anthropic SDK](https://docs.anthropic.com/en/api/client-sdks)** for
|
|
200
|
+
Claude — the reasoning model
|
|
201
|
+
- **OpenAI embeddings API** (`text-embedding-3-small`, 1536-dim) for
|
|
202
|
+
semantic search
|
|
203
|
+
- **[MCPX](https://github.com/evantahler/mcpx)** for external tools
|
|
204
|
+
- **[Ink 6](https://github.com/vadimdemedes/ink)** + **React 19** for the
|
|
205
|
+
terminal UI
|
|
206
|
+
- **[Commander.js](https://github.com/tj/commander.js)** for the CLI
|
|
207
|
+
- **[Zod](https://zod.dev)** for tool input/output schemas
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## Contributing
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
bun install
|
|
215
|
+
bun test
|
|
216
|
+
bun run lint # tsc --noEmit + biome check
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
See [CLAUDE.md](CLAUDE.md) for conventions (always use `bun`, bump the
|
|
220
|
+
version in `package.json` on every merge to `main`, etc.).
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## License
|
|
225
|
+
|
|
226
|
+
MIT.
|
package/package.json
CHANGED
package/src/commands/chat.ts
CHANGED
|
@@ -12,7 +12,7 @@ export function registerChatCommand(program: Command) {
|
|
|
12
12
|
" Commands:\n" +
|
|
13
13
|
" /help Show keyboard shortcuts\n" +
|
|
14
14
|
" /tools Open tool call inspector\n" +
|
|
15
|
-
" /
|
|
15
|
+
" /exit End the chat session",
|
|
16
16
|
)
|
|
17
17
|
.option("--thread-id <id>", "Resume an existing chat thread")
|
|
18
18
|
.option("-p, --prompt <text>", "Start chat with an initial prompt")
|