botholomew 0.12.5 → 0.14.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.
Files changed (107) hide show
  1. package/README.md +91 -68
  2. package/package.json +2 -2
  3. package/src/chat/agent.ts +59 -86
  4. package/src/chat/session.ts +29 -25
  5. package/src/commands/capabilities.ts +1 -1
  6. package/src/commands/context.ts +178 -926
  7. package/src/commands/db.ts +9 -13
  8. package/src/commands/init.ts +4 -1
  9. package/src/commands/nuke.ts +57 -90
  10. package/src/commands/schedule.ts +103 -124
  11. package/src/commands/skill.ts +2 -2
  12. package/src/commands/task.ts +86 -95
  13. package/src/commands/thread.ts +107 -112
  14. package/src/commands/worker.ts +88 -88
  15. package/src/constants.ts +93 -16
  16. package/src/context/capabilities.ts +10 -10
  17. package/src/context/fetcher.ts +9 -10
  18. package/src/context/reindex.ts +189 -0
  19. package/src/context/store.ts +803 -0
  20. package/src/db/doctor.ts +1 -8
  21. package/src/db/embeddings.ts +227 -175
  22. package/src/db/sql/19-disk_backed_index.sql +36 -0
  23. package/src/db/sql/20-drop_db_tables_for_files.sql +19 -0
  24. package/src/fs/atomic.ts +217 -0
  25. package/src/fs/compat.ts +86 -0
  26. package/src/fs/sandbox.ts +293 -0
  27. package/src/init/index.ts +69 -52
  28. package/src/init/templates.ts +1 -1
  29. package/src/mcpx/client.ts +1 -1
  30. package/src/schedules/schema.ts +19 -0
  31. package/src/schedules/store.ts +296 -0
  32. package/src/skills/commands.ts +1 -3
  33. package/src/tasks/schema.ts +47 -0
  34. package/src/tasks/store.ts +486 -0
  35. package/src/threads/store.ts +559 -0
  36. package/src/tools/capabilities/refresh.ts +42 -21
  37. package/src/tools/context/pipe.ts +15 -71
  38. package/src/tools/context/update-beliefs.ts +3 -3
  39. package/src/tools/context/update-goals.ts +3 -3
  40. package/src/tools/dir/create.ts +26 -23
  41. package/src/tools/dir/size.ts +46 -17
  42. package/src/tools/dir/tree.ts +74 -279
  43. package/src/tools/file/copy.ts +50 -24
  44. package/src/tools/file/count-lines.ts +34 -10
  45. package/src/tools/file/delete.ts +53 -23
  46. package/src/tools/file/edit.ts +39 -14
  47. package/src/tools/file/exists.ts +12 -26
  48. package/src/tools/file/info.ts +27 -85
  49. package/src/tools/file/move.ts +39 -24
  50. package/src/tools/file/read.ts +32 -80
  51. package/src/tools/file/write.ts +14 -91
  52. package/src/tools/registry.ts +8 -7
  53. package/src/tools/schedule/create.ts +2 -2
  54. package/src/tools/schedule/list.ts +7 -3
  55. package/src/tools/search/fuse.ts +12 -33
  56. package/src/tools/search/index.ts +36 -43
  57. package/src/tools/search/regexp.ts +29 -17
  58. package/src/tools/search/semantic.ts +137 -51
  59. package/src/tools/skill/delete.ts +1 -1
  60. package/src/tools/skill/list.ts +1 -1
  61. package/src/tools/skill/write.ts +1 -1
  62. package/src/tools/task/create.ts +41 -16
  63. package/src/tools/task/delete.ts +3 -3
  64. package/src/tools/task/list.ts +6 -3
  65. package/src/tools/task/update.ts +31 -9
  66. package/src/tools/task/view.ts +6 -6
  67. package/src/tools/thread/list.ts +2 -2
  68. package/src/tools/thread/search.ts +208 -0
  69. package/src/tools/thread/view.ts +50 -5
  70. package/src/tools/tool.ts +5 -0
  71. package/src/tools/util/sleep.ts +77 -0
  72. package/src/tools/worker/spawn.ts +28 -14
  73. package/src/tui/App.tsx +12 -19
  74. package/src/tui/components/ContextPanel.tsx +83 -316
  75. package/src/tui/components/SchedulePanel.tsx +34 -48
  76. package/src/tui/components/SleepProgress.tsx +70 -0
  77. package/src/tui/components/StatusBar.tsx +15 -15
  78. package/src/tui/components/TaskPanel.tsx +34 -38
  79. package/src/tui/components/ThreadPanel.tsx +29 -38
  80. package/src/tui/components/ToolCall.tsx +10 -0
  81. package/src/tui/components/WorkerPanel.tsx +21 -19
  82. package/src/tui/markdown.ts +2 -8
  83. package/src/utils/title.ts +5 -7
  84. package/src/utils/v7-date.ts +47 -0
  85. package/src/worker/heartbeat.ts +46 -24
  86. package/src/worker/index.ts +13 -15
  87. package/src/worker/llm.ts +30 -37
  88. package/src/worker/prompt.ts +19 -41
  89. package/src/worker/schedules.ts +48 -69
  90. package/src/worker/spawn.ts +11 -11
  91. package/src/worker/tick.ts +39 -43
  92. package/src/workers/store.ts +247 -0
  93. package/src/commands/tools.ts +0 -367
  94. package/src/context/describer.ts +0 -140
  95. package/src/context/drives.ts +0 -110
  96. package/src/context/ingest.ts +0 -162
  97. package/src/context/refresh.ts +0 -183
  98. package/src/db/context.ts +0 -637
  99. package/src/db/daemon-state.ts +0 -6
  100. package/src/db/reembed.ts +0 -113
  101. package/src/db/schedules.ts +0 -213
  102. package/src/db/tasks.ts +0 -347
  103. package/src/db/threads.ts +0 -276
  104. package/src/db/workers.ts +0 -212
  105. package/src/tools/context/list-drives.ts +0 -36
  106. package/src/tools/context/refresh.ts +0 -165
  107. package/src/tools/context/search.ts +0 -54
@@ -5,16 +5,17 @@ import type { BotholomewConfig } from "../config/schemas.ts";
5
5
  import { getDbPath } from "../constants.ts";
6
6
  import { withDb } from "../db/connection.ts";
7
7
  import { migrate } from "../db/schema.ts";
8
+ import { createMcpxClient } from "../mcpx/client.ts";
9
+ import { loadSkills } from "../skills/loader.ts";
10
+ import type { SkillDefinition } from "../skills/parser.ts";
8
11
  import {
9
12
  createThread,
10
13
  endThread,
14
+ ensureThreadsDir,
11
15
  getThread,
12
16
  logInteraction,
13
17
  reopenThread,
14
- } from "../db/threads.ts";
15
- import { createMcpxClient } from "../mcpx/client.ts";
16
- import { loadSkills } from "../skills/loader.ts";
17
- import type { SkillDefinition } from "../skills/parser.ts";
18
+ } from "../threads/store.ts";
18
19
  import { generateThreadTitle } from "../utils/title.ts";
19
20
  import { type ChatTurnCallbacks, runChatTurn } from "./agent.ts";
20
21
 
@@ -56,26 +57,25 @@ export async function startChatSession(
56
57
 
57
58
  if (!config.anthropic_api_key) {
58
59
  throw new Error(
59
- "no API key found. add anthropic_api_key to .botholomew/config.json",
60
+ "no API key found. add anthropic_api_key to config/config.json",
60
61
  );
61
62
  }
62
63
 
63
64
  const dbPath = getDbPath(projectDir);
64
65
  await withDb(dbPath, (conn) => migrate(conn));
66
+ await ensureThreadsDir(projectDir);
65
67
 
66
68
  let threadId: string;
67
69
  const messages: MessageParam[] = [];
68
70
 
69
71
  if (existingThreadId) {
70
72
  // Resume existing thread
71
- const result = await withDb(dbPath, (conn) =>
72
- getThread(conn, existingThreadId),
73
- );
73
+ const result = await getThread(projectDir, existingThreadId);
74
74
  if (!result) {
75
75
  throw new Error(`Thread not found: ${existingThreadId}`);
76
76
  }
77
77
  threadId = existingThreadId;
78
- await withDb(dbPath, (conn) => reopenThread(conn, threadId));
78
+ await reopenThread(projectDir, threadId);
79
79
 
80
80
  // Rebuild message history from interactions
81
81
  let firstUserMessage: string | undefined;
@@ -91,11 +91,14 @@ export async function startChatSession(
91
91
 
92
92
  // Backfill title for threads that still have the default
93
93
  if (result.thread.title === "New chat" && firstUserMessage) {
94
- void generateThreadTitle(config, dbPath, threadId, firstUserMessage);
94
+ void generateThreadTitle(config, projectDir, threadId, firstUserMessage);
95
95
  }
96
96
  } else {
97
- threadId = await withDb(dbPath, (conn) =>
98
- createThread(conn, "chat_session", undefined, "New chat"),
97
+ threadId = await createThread(
98
+ projectDir,
99
+ "chat_session",
100
+ undefined,
101
+ "New chat",
99
102
  );
100
103
  }
101
104
 
@@ -133,13 +136,11 @@ export async function sendMessage(
133
136
  session.skills = await loadSkills(session.projectDir);
134
137
 
135
138
  // Log and append user message
136
- await withDb(session.dbPath, (conn) =>
137
- logInteraction(conn, session.threadId, {
138
- role: "user",
139
- kind: "message",
140
- content: userMessage,
141
- }),
142
- );
139
+ await logInteraction(session.projectDir, session.threadId, {
140
+ role: "user",
141
+ kind: "message",
142
+ content: userMessage,
143
+ });
143
144
 
144
145
  session.messages.push({ role: "user", content: userMessage });
145
146
 
@@ -147,7 +148,7 @@ export async function sendMessage(
147
148
  if (session.messages.length === 1) {
148
149
  void generateThreadTitle(
149
150
  session.config,
150
- session.dbPath,
151
+ session.projectDir,
151
152
  session.threadId,
152
153
  userMessage,
153
154
  );
@@ -166,7 +167,7 @@ export async function sendMessage(
166
167
  }
167
168
 
168
169
  export async function endChatSession(session: ChatSession): Promise<void> {
169
- await withDb(session.dbPath, (conn) => endThread(conn, session.threadId));
170
+ await endThread(session.projectDir, session.threadId);
170
171
  await session.cleanup();
171
172
  }
172
173
 
@@ -180,10 +181,13 @@ export async function clearChatSession(
180
181
  session: ChatSession,
181
182
  ): Promise<{ previousThreadId: string; newThreadId: string }> {
182
183
  const previousThreadId = session.threadId;
183
- const newThreadId = await withDb(session.dbPath, async (conn) => {
184
- await endThread(conn, previousThreadId);
185
- return createThread(conn, "chat_session", undefined, "New chat");
186
- });
184
+ await endThread(session.projectDir, previousThreadId);
185
+ const newThreadId = await createThread(
186
+ session.projectDir,
187
+ "chat_session",
188
+ undefined,
189
+ "New chat",
190
+ );
187
191
  session.threadId = newThreadId;
188
192
  session.messages.length = 0;
189
193
  session.activeStream = null;
@@ -9,7 +9,7 @@ export function registerCapabilitiesCommand(program: Command) {
9
9
  program
10
10
  .command("capabilities")
11
11
  .description(
12
- "Regenerate .botholomew/capabilities.md by scanning built-in tools and MCPX tools",
12
+ "Regenerate prompts/capabilities.md by scanning built-in tools and MCPX tools",
13
13
  )
14
14
  .option("--no-mcp", "Skip MCPX tool enumeration (built-in tools only)")
15
15
  .action((opts: { mcp?: boolean }) =>