botholomew 0.7.13 → 0.8.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.
Files changed (54) hide show
  1. package/README.md +37 -32
  2. package/package.json +1 -1
  3. package/src/chat/agent.ts +13 -11
  4. package/src/cli.ts +2 -2
  5. package/src/commands/chat.ts +29 -44
  6. package/src/commands/nuke.ts +11 -8
  7. package/src/commands/schedule.ts +1 -1
  8. package/src/commands/thread.ts +2 -2
  9. package/src/commands/with-db.ts +1 -1
  10. package/src/commands/worker.ts +231 -0
  11. package/src/config/schemas.ts +12 -0
  12. package/src/constants.ts +1 -27
  13. package/src/db/schedules.ts +66 -0
  14. package/src/db/schema.ts +16 -4
  15. package/src/db/sql/12-workers.sql +66 -0
  16. package/src/db/tasks.ts +25 -1
  17. package/src/db/threads.ts +1 -1
  18. package/src/db/workers.ts +207 -0
  19. package/src/init/index.ts +3 -1
  20. package/src/tools/context/read-large-result.ts +1 -1
  21. package/src/tools/mcp/exec.ts +1 -1
  22. package/src/tools/mcp/search.ts +1 -1
  23. package/src/tools/registry.ts +5 -0
  24. package/src/tools/thread/list.ts +2 -2
  25. package/src/tools/worker/spawn.ts +50 -0
  26. package/src/tui/App.tsx +15 -7
  27. package/src/tui/components/HelpPanel.tsx +5 -5
  28. package/src/tui/components/StatusBar.tsx +22 -18
  29. package/src/tui/components/TabBar.tsx +3 -2
  30. package/src/tui/components/ThreadPanel.tsx +7 -7
  31. package/src/tui/components/WorkerPanel.tsx +207 -0
  32. package/src/utils/title.ts +1 -1
  33. package/src/worker/heartbeat.ts +78 -0
  34. package/src/worker/index.ts +200 -0
  35. package/src/{daemon → worker}/llm.ts +5 -5
  36. package/src/{daemon → worker}/prompt.ts +2 -2
  37. package/src/worker/run.ts +26 -0
  38. package/src/{daemon → worker}/schedules.ts +30 -2
  39. package/src/worker/spawn.ts +48 -0
  40. package/src/{daemon → worker}/tick.ts +93 -35
  41. package/src/commands/daemon.ts +0 -152
  42. package/src/daemon/ensure-running.ts +0 -16
  43. package/src/daemon/healthcheck.ts +0 -47
  44. package/src/daemon/index.ts +0 -106
  45. package/src/daemon/run.ts +0 -14
  46. package/src/daemon/spawn.ts +0 -38
  47. package/src/daemon/watchdog.ts +0 -306
  48. package/src/utils/pid.ts +0 -55
  49. package/src/utils/project-registry.ts +0 -48
  50. /package/src/{daemon → worker}/context.ts +0 -0
  51. /package/src/{daemon → worker}/fake-llm.ts +0 -0
  52. /package/src/{daemon → worker}/fake-mcp.ts +0 -0
  53. /package/src/{daemon → worker}/large-results.ts +0 -0
  54. /package/src/{daemon → worker}/llm-client.ts +0 -0
package/src/utils/pid.ts DELETED
@@ -1,55 +0,0 @@
1
- import { unlink } from "node:fs/promises";
2
- import { getPidPath } from "../constants.ts";
3
-
4
- export function writePidFile(projectDir: string, pid: number): void {
5
- Bun.write(getPidPath(projectDir), String(pid));
6
- }
7
-
8
- export async function readPidFile(projectDir: string): Promise<number | null> {
9
- const file = Bun.file(getPidPath(projectDir));
10
- if (!(await file.exists())) return null;
11
- const text = await file.text();
12
- const pid = parseInt(text.trim(), 10);
13
- return Number.isNaN(pid) ? null : pid;
14
- }
15
-
16
- export async function removePidFile(projectDir: string): Promise<void> {
17
- try {
18
- await unlink(getPidPath(projectDir));
19
- } catch {
20
- // ignore if file doesn't exist
21
- }
22
- }
23
-
24
- export function isProcessAlive(pid: number): boolean {
25
- try {
26
- process.kill(pid, 0);
27
- return true;
28
- } catch {
29
- return false;
30
- }
31
- }
32
-
33
- export async function getDaemonStatus(
34
- projectDir: string,
35
- ): Promise<{ pid: number } | null> {
36
- const pid = await readPidFile(projectDir);
37
- if (pid === null) return null;
38
- if (!isProcessAlive(pid)) {
39
- await removePidFile(projectDir);
40
- return null;
41
- }
42
- return { pid };
43
- }
44
-
45
- export async function stopDaemon(projectDir: string): Promise<boolean> {
46
- const pid = await readPidFile(projectDir);
47
- if (pid === null) return false;
48
- if (!isProcessAlive(pid)) {
49
- await removePidFile(projectDir);
50
- return false;
51
- }
52
- process.kill(pid, "SIGTERM");
53
- await removePidFile(projectDir);
54
- return true;
55
- }
@@ -1,48 +0,0 @@
1
- import { mkdir } from "node:fs/promises";
2
- import { join } from "node:path";
3
- import { HOME_CONFIG_DIR, sanitizePathForServiceName } from "../constants.ts";
4
-
5
- const REGISTRY_PATH = join(HOME_CONFIG_DIR, "projects.json");
6
-
7
- interface ProjectEntry {
8
- projectDir: string;
9
- installedAt: string;
10
- }
11
-
12
- type ProjectRegistry = Record<string, ProjectEntry>;
13
-
14
- export async function readRegistry(): Promise<ProjectRegistry> {
15
- const file = Bun.file(REGISTRY_PATH);
16
- if (!(await file.exists())) return {};
17
- try {
18
- return (await file.json()) as ProjectRegistry;
19
- } catch {
20
- return {};
21
- }
22
- }
23
-
24
- async function writeRegistry(registry: ProjectRegistry): Promise<void> {
25
- await mkdir(HOME_CONFIG_DIR, { recursive: true });
26
- await Bun.write(REGISTRY_PATH, `${JSON.stringify(registry, null, 2)}\n`);
27
- }
28
-
29
- export async function registerProject(projectDir: string): Promise<void> {
30
- const registry = await readRegistry();
31
- const key = sanitizePathForServiceName(projectDir);
32
- registry[key] = { projectDir, installedAt: new Date().toISOString() };
33
- await writeRegistry(registry);
34
- }
35
-
36
- export async function unregisterProject(projectDir: string): Promise<void> {
37
- const registry = await readRegistry();
38
- const key = sanitizePathForServiceName(projectDir);
39
- delete registry[key];
40
- await writeRegistry(registry);
41
- }
42
-
43
- export async function listRegisteredProjects(): Promise<
44
- Array<{ projectDir: string; installedAt: string }>
45
- > {
46
- const registry = await readRegistry();
47
- return Object.values(registry);
48
- }
File without changes
File without changes
File without changes
File without changes
File without changes