beecork 1.7.1 → 2.0.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 (253) hide show
  1. package/README.md +52 -111
  2. package/dist/index.js +1394 -581
  3. package/package.json +26 -54
  4. package/dist/capabilities/index.d.ts +0 -3
  5. package/dist/capabilities/index.js +0 -2
  6. package/dist/capabilities/manager.d.ts +0 -13
  7. package/dist/capabilities/manager.js +0 -115
  8. package/dist/capabilities/packs.d.ts +0 -2
  9. package/dist/capabilities/packs.js +0 -54
  10. package/dist/capabilities/types.d.ts +0 -21
  11. package/dist/capabilities/types.js +0 -1
  12. package/dist/channels/admin.d.ts +0 -10
  13. package/dist/channels/admin.js +0 -20
  14. package/dist/channels/command-handler.d.ts +0 -19
  15. package/dist/channels/command-handler.js +0 -235
  16. package/dist/channels/discord.d.ts +0 -17
  17. package/dist/channels/discord.js +0 -266
  18. package/dist/channels/index.d.ts +0 -7
  19. package/dist/channels/index.js +0 -6
  20. package/dist/channels/loader.d.ts +0 -7
  21. package/dist/channels/loader.js +0 -87
  22. package/dist/channels/pipeline.d.ts +0 -50
  23. package/dist/channels/pipeline.js +0 -92
  24. package/dist/channels/registry.d.ts +0 -36
  25. package/dist/channels/registry.js +0 -80
  26. package/dist/channels/send-helpers.d.ts +0 -19
  27. package/dist/channels/send-helpers.js +0 -21
  28. package/dist/channels/telegram.d.ts +0 -47
  29. package/dist/channels/telegram.js +0 -649
  30. package/dist/channels/types.d.ts +0 -41
  31. package/dist/channels/types.js +0 -1
  32. package/dist/channels/voice-state.d.ts +0 -29
  33. package/dist/channels/voice-state.js +0 -45
  34. package/dist/channels/webhook.d.ts +0 -16
  35. package/dist/channels/webhook.js +0 -222
  36. package/dist/channels/whatsapp.d.ts +0 -28
  37. package/dist/channels/whatsapp.js +0 -323
  38. package/dist/cli/capabilities.d.ts +0 -3
  39. package/dist/cli/capabilities.js +0 -72
  40. package/dist/cli/channel.d.ts +0 -3
  41. package/dist/cli/channel.js +0 -202
  42. package/dist/cli/commands.d.ts +0 -15
  43. package/dist/cli/commands.js +0 -279
  44. package/dist/cli/doctor.d.ts +0 -1
  45. package/dist/cli/doctor.js +0 -208
  46. package/dist/cli/handoff.d.ts +0 -8
  47. package/dist/cli/handoff.js +0 -33
  48. package/dist/cli/helpers.d.ts +0 -2
  49. package/dist/cli/helpers.js +0 -21
  50. package/dist/cli/mcp.d.ts +0 -3
  51. package/dist/cli/mcp.js +0 -47
  52. package/dist/cli/media.d.ts +0 -2
  53. package/dist/cli/media.js +0 -125
  54. package/dist/cli/setup.d.ts +0 -1
  55. package/dist/cli/setup.js +0 -239
  56. package/dist/cli/store.d.ts +0 -3
  57. package/dist/cli/store.js +0 -108
  58. package/dist/config.d.ts +0 -11
  59. package/dist/config.js +0 -115
  60. package/dist/cron/scheduler.d.ts +0 -22
  61. package/dist/cron/scheduler.js +0 -220
  62. package/dist/cron/store.d.ts +0 -12
  63. package/dist/cron/store.js +0 -83
  64. package/dist/daemon.d.ts +0 -1
  65. package/dist/daemon.js +0 -345
  66. package/dist/dashboard/html.d.ts +0 -1
  67. package/dist/dashboard/html.js +0 -849
  68. package/dist/dashboard/routes.d.ts +0 -17
  69. package/dist/dashboard/routes.js +0 -623
  70. package/dist/dashboard/server.d.ts +0 -1
  71. package/dist/dashboard/server.js +0 -104
  72. package/dist/db/connection.d.ts +0 -29
  73. package/dist/db/connection.js +0 -37
  74. package/dist/db/index.d.ts +0 -14
  75. package/dist/db/index.js +0 -127
  76. package/dist/db/migrations.d.ts +0 -2
  77. package/dist/db/migrations.js +0 -384
  78. package/dist/delegation/manager.d.ts +0 -18
  79. package/dist/delegation/manager.js +0 -89
  80. package/dist/index.d.ts +0 -2
  81. package/dist/knowledge/index.d.ts +0 -2
  82. package/dist/knowledge/index.js +0 -1
  83. package/dist/knowledge/manager.d.ts +0 -17
  84. package/dist/knowledge/manager.js +0 -160
  85. package/dist/knowledge/types.d.ts +0 -7
  86. package/dist/knowledge/types.js +0 -1
  87. package/dist/machines/forwarder.d.ts +0 -7
  88. package/dist/machines/forwarder.js +0 -35
  89. package/dist/machines/index.d.ts +0 -1
  90. package/dist/machines/index.js +0 -1
  91. package/dist/machines/registry.d.ts +0 -15
  92. package/dist/machines/registry.js +0 -46
  93. package/dist/mcp/handlers.d.ts +0 -37
  94. package/dist/mcp/handlers.js +0 -520
  95. package/dist/mcp/server.d.ts +0 -2
  96. package/dist/mcp/server.js +0 -86
  97. package/dist/mcp/tool-definitions.d.ts +0 -1225
  98. package/dist/mcp/tool-definitions.js +0 -412
  99. package/dist/mcp/validate.d.ts +0 -23
  100. package/dist/mcp/validate.js +0 -65
  101. package/dist/media/factory.d.ts +0 -6
  102. package/dist/media/factory.js +0 -36
  103. package/dist/media/generators/dall-e.d.ts +0 -10
  104. package/dist/media/generators/dall-e.js +0 -41
  105. package/dist/media/generators/elevenlabs-music.d.ts +0 -9
  106. package/dist/media/generators/elevenlabs-music.js +0 -34
  107. package/dist/media/generators/elevenlabs-sfx.d.ts +0 -9
  108. package/dist/media/generators/elevenlabs-sfx.js +0 -33
  109. package/dist/media/generators/kling.d.ts +0 -9
  110. package/dist/media/generators/kling.js +0 -47
  111. package/dist/media/generators/lyria.d.ts +0 -10
  112. package/dist/media/generators/lyria.js +0 -41
  113. package/dist/media/generators/nano-banana.d.ts +0 -10
  114. package/dist/media/generators/nano-banana.js +0 -45
  115. package/dist/media/generators/poll-util.d.ts +0 -12
  116. package/dist/media/generators/poll-util.js +0 -22
  117. package/dist/media/generators/recraft.d.ts +0 -9
  118. package/dist/media/generators/recraft.js +0 -52
  119. package/dist/media/generators/runway.d.ts +0 -9
  120. package/dist/media/generators/runway.js +0 -49
  121. package/dist/media/generators/stable-diffusion.d.ts +0 -9
  122. package/dist/media/generators/stable-diffusion.js +0 -35
  123. package/dist/media/generators/veo.d.ts +0 -9
  124. package/dist/media/generators/veo.js +0 -32
  125. package/dist/media/index.d.ts +0 -6
  126. package/dist/media/index.js +0 -8
  127. package/dist/media/loader.d.ts +0 -8
  128. package/dist/media/loader.js +0 -46
  129. package/dist/media/store.d.ts +0 -17
  130. package/dist/media/store.js +0 -69
  131. package/dist/media/types.d.ts +0 -43
  132. package/dist/media/types.js +0 -1
  133. package/dist/memory/extractor.d.ts +0 -5
  134. package/dist/memory/extractor.js +0 -157
  135. package/dist/notifications/index.d.ts +0 -4
  136. package/dist/notifications/index.js +0 -21
  137. package/dist/notifications/ntfy.d.ts +0 -9
  138. package/dist/notifications/ntfy.js +0 -25
  139. package/dist/notifications/pushover.d.ts +0 -9
  140. package/dist/notifications/pushover.js +0 -26
  141. package/dist/notifications/types.d.ts +0 -5
  142. package/dist/notifications/types.js +0 -1
  143. package/dist/notifications/webhook-provider.d.ts +0 -9
  144. package/dist/notifications/webhook-provider.js +0 -24
  145. package/dist/observability/analytics.d.ts +0 -30
  146. package/dist/observability/analytics.js +0 -118
  147. package/dist/pipe/anthropic-client.d.ts +0 -9
  148. package/dist/pipe/anthropic-client.js +0 -50
  149. package/dist/pipe/brain.d.ts +0 -16
  150. package/dist/pipe/brain.js +0 -89
  151. package/dist/pipe/memory-store.d.ts +0 -8
  152. package/dist/pipe/memory-store.js +0 -39
  153. package/dist/pipe/project-scanner.d.ts +0 -6
  154. package/dist/pipe/project-scanner.js +0 -26
  155. package/dist/pipe/types.d.ts +0 -34
  156. package/dist/pipe/types.js +0 -1
  157. package/dist/projects/index.d.ts +0 -4
  158. package/dist/projects/index.js +0 -2
  159. package/dist/projects/manager.d.ts +0 -13
  160. package/dist/projects/manager.js +0 -166
  161. package/dist/projects/router.d.ts +0 -17
  162. package/dist/projects/router.js +0 -246
  163. package/dist/projects/types.d.ts +0 -19
  164. package/dist/projects/types.js +0 -1
  165. package/dist/service/install.d.ts +0 -4
  166. package/dist/service/install.js +0 -146
  167. package/dist/service/templates.d.ts +0 -4
  168. package/dist/service/templates.js +0 -52
  169. package/dist/service/windows.d.ts +0 -8
  170. package/dist/service/windows.js +0 -59
  171. package/dist/session/budget-guard.d.ts +0 -20
  172. package/dist/session/budget-guard.js +0 -31
  173. package/dist/session/circuit-breaker.d.ts +0 -19
  174. package/dist/session/circuit-breaker.js +0 -91
  175. package/dist/session/context-compactor.d.ts +0 -32
  176. package/dist/session/context-compactor.js +0 -45
  177. package/dist/session/context-monitor.d.ts +0 -15
  178. package/dist/session/context-monitor.js +0 -44
  179. package/dist/session/handoff.d.ts +0 -21
  180. package/dist/session/handoff.js +0 -50
  181. package/dist/session/manager.d.ts +0 -60
  182. package/dist/session/manager.js +0 -416
  183. package/dist/session/memory-store.d.ts +0 -29
  184. package/dist/session/memory-store.js +0 -45
  185. package/dist/session/message-queue.d.ts +0 -28
  186. package/dist/session/message-queue.js +0 -52
  187. package/dist/session/pending-dispatcher.d.ts +0 -31
  188. package/dist/session/pending-dispatcher.js +0 -120
  189. package/dist/session/pending-store.d.ts +0 -60
  190. package/dist/session/pending-store.js +0 -118
  191. package/dist/session/stale-session.d.ts +0 -31
  192. package/dist/session/stale-session.js +0 -45
  193. package/dist/session/subprocess.d.ts +0 -32
  194. package/dist/session/subprocess.js +0 -230
  195. package/dist/session/tab-store.d.ts +0 -28
  196. package/dist/session/tab-store.js +0 -78
  197. package/dist/session/tool-classifier.d.ts +0 -4
  198. package/dist/session/tool-classifier.js +0 -56
  199. package/dist/tasks/scheduler.d.ts +0 -45
  200. package/dist/tasks/scheduler.js +0 -329
  201. package/dist/tasks/store.d.ts +0 -11
  202. package/dist/tasks/store.js +0 -103
  203. package/dist/timeline/index.d.ts +0 -3
  204. package/dist/timeline/index.js +0 -2
  205. package/dist/timeline/logger.d.ts +0 -8
  206. package/dist/timeline/logger.js +0 -11
  207. package/dist/timeline/query.d.ts +0 -11
  208. package/dist/timeline/query.js +0 -67
  209. package/dist/timeline/types.d.ts +0 -12
  210. package/dist/timeline/types.js +0 -1
  211. package/dist/types.d.ts +0 -225
  212. package/dist/types.js +0 -3
  213. package/dist/users/index.d.ts +0 -2
  214. package/dist/users/index.js +0 -1
  215. package/dist/users/service.d.ts +0 -17
  216. package/dist/users/service.js +0 -46
  217. package/dist/util/auto-heal.d.ts +0 -43
  218. package/dist/util/auto-heal.js +0 -107
  219. package/dist/util/install-info.d.ts +0 -37
  220. package/dist/util/install-info.js +0 -80
  221. package/dist/util/logger.d.ts +0 -18
  222. package/dist/util/logger.js +0 -118
  223. package/dist/util/paths.d.ts +0 -13
  224. package/dist/util/paths.js +0 -55
  225. package/dist/util/platform.d.ts +0 -2
  226. package/dist/util/platform.js +0 -11
  227. package/dist/util/progress.d.ts +0 -34
  228. package/dist/util/progress.js +0 -133
  229. package/dist/util/rate-limiter.d.ts +0 -14
  230. package/dist/util/rate-limiter.js +0 -50
  231. package/dist/util/retry.d.ts +0 -2
  232. package/dist/util/retry.js +0 -18
  233. package/dist/util/text.d.ts +0 -32
  234. package/dist/util/text.js +0 -101
  235. package/dist/version.d.ts +0 -1
  236. package/dist/version.js +0 -4
  237. package/dist/voice/index.d.ts +0 -17
  238. package/dist/voice/index.js +0 -42
  239. package/dist/voice/stt.d.ts +0 -16
  240. package/dist/voice/stt.js +0 -57
  241. package/dist/voice/tts.d.ts +0 -23
  242. package/dist/voice/tts.js +0 -84
  243. package/dist/watchers/evaluator.d.ts +0 -5
  244. package/dist/watchers/evaluator.js +0 -45
  245. package/dist/watchers/index.d.ts +0 -4
  246. package/dist/watchers/index.js +0 -3
  247. package/dist/watchers/scheduler.d.ts +0 -20
  248. package/dist/watchers/scheduler.js +0 -183
  249. package/dist/watchers/store.d.ts +0 -10
  250. package/dist/watchers/store.js +0 -56
  251. package/dist/watchers/types.d.ts +0 -15
  252. package/dist/watchers/types.js +0 -1
  253. package/scripts/postinstall.mjs +0 -50
@@ -1,19 +0,0 @@
1
- export interface Project {
2
- id: string;
3
- name: string;
4
- path: string;
5
- type: 'user-project' | 'category';
6
- lastUsedAt: string;
7
- createdAt: string;
8
- }
9
- export interface RouteDecision {
10
- project: Project;
11
- tabName: string;
12
- isNewTab: boolean;
13
- confidence: number;
14
- needsConfirmation: boolean;
15
- reason: string;
16
- }
17
- export interface RoutingContext {
18
- userId?: string;
19
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,4 +0,0 @@
1
- export declare function installService(): string;
2
- export declare function uninstallService(): string;
3
- export declare function startService(): void;
4
- export declare function stopService(): void;
@@ -1,146 +0,0 @@
1
- import fs from 'node:fs';
2
- import path from 'node:path';
3
- import { execSync } from 'node:child_process';
4
- import { getPlatform } from '../util/platform.js';
5
- import { ensureBeecorkDirs } from '../util/paths.js';
6
- import { getLaunchdPlist, getSystemdUnit, getLaunchdPlistPath, getSystemdUnitPath, } from './templates.js';
7
- import { installWindowsService, startWindowsService, stopWindowsService, uninstallWindowsService, } from './windows.js';
8
- function findNodePath() {
9
- try {
10
- const cmd = process.platform === 'win32' ? 'where node' : 'which node';
11
- return execSync(cmd, { encoding: 'utf-8' }).trim().split(/\r?\n/)[0];
12
- }
13
- catch {
14
- return process.platform === 'win32' ? 'node' : '/usr/local/bin/node';
15
- }
16
- }
17
- function findDaemonPath() {
18
- // import.meta.url is dist/service/install.js — daemon is at dist/daemon.js (one level up)
19
- const thisFileUrl = new URL(import.meta.url);
20
- const thisFile = process.platform === 'win32'
21
- ? thisFileUrl.pathname.replace(/^\/([A-Za-z]:)/, '$1') // strip leading / on Windows drive paths
22
- : thisFileUrl.pathname;
23
- const distDir = path.dirname(path.dirname(thisFile)); // go up from service/ to dist/
24
- const daemonPath = path.join(distDir, 'daemon.js');
25
- if (fs.existsSync(daemonPath))
26
- return daemonPath;
27
- // Fallback: maybe we're in src/ during development
28
- const srcDaemon = path.resolve(distDir, '..', 'dist', 'daemon.js');
29
- if (fs.existsSync(srcDaemon))
30
- return srcDaemon;
31
- throw new Error('Could not find daemon.js. Make sure beecork is built (npm run build).');
32
- }
33
- export function installService() {
34
- ensureBeecorkDirs();
35
- const platform = getPlatform();
36
- const nodePath = findNodePath();
37
- const daemonPath = findDaemonPath();
38
- if (platform === 'windows') {
39
- installWindowsService(`${nodePath}" "${daemonPath}`);
40
- return 'Windows Task Scheduler';
41
- }
42
- else if (platform === 'mac') {
43
- return installLaunchd(nodePath, daemonPath);
44
- }
45
- else {
46
- return installSystemd(nodePath, daemonPath);
47
- }
48
- }
49
- export function uninstallService() {
50
- const platform = getPlatform();
51
- if (platform === 'windows') {
52
- uninstallWindowsService();
53
- return 'Windows Task Scheduler';
54
- }
55
- else if (platform === 'mac') {
56
- return uninstallLaunchd();
57
- }
58
- else {
59
- return uninstallSystemd();
60
- }
61
- }
62
- export function startService() {
63
- const platform = getPlatform();
64
- if (platform === 'windows') {
65
- startWindowsService();
66
- }
67
- else if (platform === 'mac') {
68
- const plistPath = getLaunchdPlistPath();
69
- execSync(`launchctl load "${plistPath}"`, { stdio: 'inherit' });
70
- }
71
- else {
72
- execSync('systemctl --user start beecork', { stdio: 'inherit' });
73
- }
74
- }
75
- export function stopService() {
76
- const platform = getPlatform();
77
- if (platform === 'windows') {
78
- stopWindowsService();
79
- }
80
- else if (platform === 'mac') {
81
- const plistPath = getLaunchdPlistPath();
82
- try {
83
- execSync(`launchctl unload "${plistPath}"`, { stdio: 'inherit' });
84
- }
85
- catch {
86
- /* not loaded */
87
- }
88
- }
89
- else {
90
- try {
91
- execSync('systemctl --user stop beecork', { stdio: 'inherit' });
92
- }
93
- catch {
94
- /* not running */
95
- }
96
- }
97
- }
98
- function installLaunchd(nodePath, daemonPath) {
99
- const plistPath = getLaunchdPlistPath();
100
- const plistDir = path.dirname(plistPath);
101
- fs.mkdirSync(plistDir, { recursive: true });
102
- const content = getLaunchdPlist(nodePath, daemonPath);
103
- fs.writeFileSync(plistPath, content);
104
- return plistPath;
105
- }
106
- function uninstallLaunchd() {
107
- const plistPath = getLaunchdPlistPath();
108
- try {
109
- execSync(`launchctl unload "${plistPath}"`, { stdio: 'pipe' });
110
- }
111
- catch {
112
- /* ok */
113
- }
114
- if (fs.existsSync(plistPath))
115
- fs.unlinkSync(plistPath);
116
- return plistPath;
117
- }
118
- function installSystemd(nodePath, daemonPath) {
119
- const unitPath = getSystemdUnitPath();
120
- const unitDir = path.dirname(unitPath);
121
- fs.mkdirSync(unitDir, { recursive: true });
122
- const content = getSystemdUnit(nodePath, daemonPath);
123
- fs.writeFileSync(unitPath, content);
124
- execSync('systemctl --user daemon-reload', { stdio: 'pipe' });
125
- execSync('systemctl --user enable beecork', { stdio: 'pipe' });
126
- return unitPath;
127
- }
128
- function uninstallSystemd() {
129
- const unitPath = getSystemdUnitPath();
130
- try {
131
- execSync('systemctl --user disable beecork', { stdio: 'pipe' });
132
- }
133
- catch {
134
- /* ok */
135
- }
136
- try {
137
- execSync('systemctl --user stop beecork', { stdio: 'pipe' });
138
- }
139
- catch {
140
- /* ok */
141
- }
142
- if (fs.existsSync(unitPath))
143
- fs.unlinkSync(unitPath);
144
- execSync('systemctl --user daemon-reload', { stdio: 'pipe' });
145
- return unitPath;
146
- }
@@ -1,4 +0,0 @@
1
- export declare function getLaunchdPlist(nodePath: string, daemonPath: string): string;
2
- export declare function getSystemdUnit(nodePath: string, daemonPath: string): string;
3
- export declare function getLaunchdPlistPath(): string;
4
- export declare function getSystemdUnitPath(): string;
@@ -1,52 +0,0 @@
1
- import os from 'node:os';
2
- export function getLaunchdPlist(nodePath, daemonPath) {
3
- const home = os.homedir();
4
- return `<?xml version="1.0" encoding="UTF-8"?>
5
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
6
- <plist version="1.0">
7
- <dict>
8
- <key>Label</key>
9
- <string>com.beecork.daemon</string>
10
- <key>ProgramArguments</key>
11
- <array>
12
- <string>${nodePath}</string>
13
- <string>${daemonPath}</string>
14
- </array>
15
- <key>RunAtLoad</key>
16
- <true/>
17
- <key>KeepAlive</key>
18
- <true/>
19
- <key>StandardOutPath</key>
20
- <string>${home}/.beecork/logs/daemon.stdout.log</string>
21
- <key>StandardErrorPath</key>
22
- <string>${home}/.beecork/logs/daemon.stderr.log</string>
23
- <key>EnvironmentVariables</key>
24
- <dict>
25
- <key>PATH</key>
26
- <string>/usr/local/bin:/usr/bin:/bin:${home}/.local/bin:${home}/.nvm/versions/node/current/bin</string>
27
- <key>HOME</key>
28
- <string>${home}</string>
29
- </dict>
30
- </dict>
31
- </plist>`;
32
- }
33
- export function getSystemdUnit(nodePath, daemonPath) {
34
- return `[Unit]
35
- Description=Beecork - Claude Code always-on infrastructure
36
- After=network.target
37
-
38
- [Service]
39
- ExecStart=${nodePath} ${daemonPath}
40
- Restart=always
41
- RestartSec=5
42
- Environment=PATH=/usr/local/bin:/usr/bin:/bin:%h/.local/bin
43
-
44
- [Install]
45
- WantedBy=default.target`;
46
- }
47
- export function getLaunchdPlistPath() {
48
- return `${os.homedir()}/Library/LaunchAgents/com.beecork.daemon.plist`;
49
- }
50
- export function getSystemdUnitPath() {
51
- return `${os.homedir()}/.config/systemd/user/beecork.service`;
52
- }
@@ -1,8 +0,0 @@
1
- /** Install Beecork as a Windows Task Scheduler task */
2
- export declare function installWindowsService(binPath: string): void;
3
- /** Start the Windows service */
4
- export declare function startWindowsService(): void;
5
- /** Stop the Windows service */
6
- export declare function stopWindowsService(): void;
7
- /** Uninstall the Windows service */
8
- export declare function uninstallWindowsService(): void;
@@ -1,59 +0,0 @@
1
- import fs from 'node:fs';
2
- import path from 'node:path';
3
- import { execSync } from 'node:child_process';
4
- const TASK_NAME = 'BeecorkDaemon';
5
- /** Install Beecork as a Windows Task Scheduler task */
6
- export function installWindowsService(binPath) {
7
- const appData = process.env.APPDATA || path.join(process.env.USERPROFILE || '', 'AppData', 'Roaming');
8
- const logPath = path.join(appData, '.beecork', 'logs', 'daemon.log');
9
- // Ensure log directory exists
10
- fs.mkdirSync(path.dirname(logPath), { recursive: true });
11
- // Create a wrapper script that runs beecork daemon
12
- const wrapperPath = path.join(appData, '.beecork', 'start-daemon.bat');
13
- fs.writeFileSync(wrapperPath, `@echo off\r\n"${binPath}" daemon >> "${logPath}" 2>&1\r\n`);
14
- try {
15
- // Remove existing task if any
16
- execSync(`schtasks /Delete /TN "${TASK_NAME}" /F 2>nul`, { stdio: 'ignore' });
17
- }
18
- catch { }
19
- // Create scheduled task that runs at logon
20
- execSync(`schtasks /Create /TN "${TASK_NAME}" /TR "${wrapperPath}" /SC ONLOGON /RL HIGHEST /F`, {
21
- stdio: 'inherit',
22
- });
23
- console.log(`Windows service installed: ${TASK_NAME}`);
24
- console.log('The daemon will start automatically when you log in.');
25
- }
26
- /** Start the Windows service */
27
- export function startWindowsService() {
28
- try {
29
- execSync(`schtasks /Run /TN "${TASK_NAME}"`, { stdio: 'inherit' });
30
- console.log('Beecork daemon started.');
31
- }
32
- catch {
33
- console.error('Failed to start. Run manually: beecork daemon');
34
- }
35
- }
36
- /** Stop the Windows service */
37
- export function stopWindowsService() {
38
- try {
39
- execSync(`schtasks /End /TN "${TASK_NAME}"`, { stdio: 'inherit' });
40
- console.log('Beecork daemon stopped.');
41
- }
42
- catch {
43
- // Try killing the process directly
44
- try {
45
- execSync('taskkill /F /IM node.exe /FI "WINDOWTITLE eq beecork*"', { stdio: 'ignore' });
46
- }
47
- catch { }
48
- }
49
- }
50
- /** Uninstall the Windows service */
51
- export function uninstallWindowsService() {
52
- try {
53
- execSync(`schtasks /Delete /TN "${TASK_NAME}" /F`, { stdio: 'inherit' });
54
- console.log('Beecork service uninstalled.');
55
- }
56
- catch {
57
- console.error('Failed to uninstall service.');
58
- }
59
- }
@@ -1,20 +0,0 @@
1
- /**
2
- * Per-tab spend budget enforcement, extracted from TabManager.
3
- *
4
- * Pure function (with a tiny stateful wrapper) so it can be unit-tested without
5
- * a database or a running subprocess: feed in current spend + tab name, get a
6
- * decision back. The caller (TabManager.executeMessage) handles the side
7
- * effects (notify + early return).
8
- */
9
- export interface BudgetDecision {
10
- allowed: boolean;
11
- /** When allowed=false, the message to surface to the caller. */
12
- reason?: string;
13
- /** When the tab has crossed the 80% threshold, the warning text to notify. */
14
- warning?: string;
15
- }
16
- export declare class BudgetGuard {
17
- private maxBudgetUsd;
18
- constructor(maxBudgetUsd: number | undefined);
19
- check(currentSpend: number, tabName: string): BudgetDecision;
20
- }
@@ -1,31 +0,0 @@
1
- /**
2
- * Per-tab spend budget enforcement, extracted from TabManager.
3
- *
4
- * Pure function (with a tiny stateful wrapper) so it can be unit-tested without
5
- * a database or a running subprocess: feed in current spend + tab name, get a
6
- * decision back. The caller (TabManager.executeMessage) handles the side
7
- * effects (notify + early return).
8
- */
9
- export class BudgetGuard {
10
- maxBudgetUsd;
11
- constructor(maxBudgetUsd) {
12
- this.maxBudgetUsd = maxBudgetUsd;
13
- }
14
- check(currentSpend, tabName) {
15
- if (!this.maxBudgetUsd)
16
- return { allowed: true };
17
- if (currentSpend >= this.maxBudgetUsd) {
18
- return {
19
- allowed: false,
20
- reason: `Budget limit reached for tab "${tabName}": $${currentSpend.toFixed(2)} / $${this.maxBudgetUsd.toFixed(2)}`,
21
- };
22
- }
23
- if (currentSpend >= this.maxBudgetUsd * 0.8) {
24
- return {
25
- allowed: true,
26
- warning: `⚠️ Budget warning: tab "${tabName}" at $${currentSpend.toFixed(2)} / $${this.maxBudgetUsd.toFixed(2)} (80%)`,
27
- };
28
- }
29
- return { allowed: true };
30
- }
31
- }
@@ -1,19 +0,0 @@
1
- import type { CircuitBreakerConfig, StreamContentToolUse } from '../types.js';
2
- export type CircuitBreakerAction = 'ok' | 'warn' | 'notify' | 'break';
3
- export declare class CircuitBreaker {
4
- private tabName;
5
- private ring;
6
- private ringHead;
7
- private ringSize;
8
- private config;
9
- private tripped;
10
- private warned;
11
- private notified;
12
- private readonly WARN_THRESHOLD;
13
- private readonly NOTIFY_THRESHOLD;
14
- constructor(tabName: string, config?: Partial<CircuitBreakerConfig>);
15
- /** Record a tool call. Returns the action to take. */
16
- recordToolCall(toolUse: StreamContentToolUse): CircuitBreakerAction;
17
- reset(): void;
18
- get isTripped(): boolean;
19
- }
@@ -1,91 +0,0 @@
1
- import { logger } from '../util/logger.js';
2
- const DEFAULT_CONFIG = {
3
- maxRepeats: 20,
4
- windowSize: 30,
5
- };
6
- /**
7
- * Detects loops in claude tool-use streams using consecutive-identical-call
8
- * counting. The signature is a hash of the tool name + input — JSON.stringify
9
- * would be O(input-size) per call and a 50KB Write tool input would allocate
10
- * 50KB just to compare equality, so we use a quick-hash strategy that's
11
- * length-independent.
12
- */
13
- function hashSignature(toolUse) {
14
- // FNV-1a 32-bit hash of the JSON repr — fast, collision-rare for short inputs.
15
- // For correctness we only need equality (was this the same call as before),
16
- // not reversibility, so a hash is sufficient.
17
- const s = `${toolUse.name}:${JSON.stringify(toolUse.input)}`;
18
- let h = 0x811c9dc5;
19
- for (let i = 0; i < s.length; i++) {
20
- h ^= s.charCodeAt(i);
21
- h = Math.imul(h, 0x01000193);
22
- }
23
- return `${toolUse.name}#${(h >>> 0).toString(36)}`;
24
- }
25
- export class CircuitBreaker {
26
- tabName;
27
- // Ring buffer to avoid per-call array reslice
28
- ring;
29
- ringHead = 0;
30
- ringSize = 0;
31
- config;
32
- tripped = false;
33
- warned = false;
34
- notified = false;
35
- WARN_THRESHOLD = 5;
36
- NOTIFY_THRESHOLD = 10;
37
- constructor(tabName, config) {
38
- this.tabName = tabName;
39
- this.config = { ...DEFAULT_CONFIG, ...config };
40
- this.ring = new Array(this.config.windowSize);
41
- }
42
- /** Record a tool call. Returns the action to take. */
43
- recordToolCall(toolUse) {
44
- if (this.tripped)
45
- return 'break';
46
- const signature = hashSignature(toolUse);
47
- this.ring[this.ringHead] = signature;
48
- this.ringHead = (this.ringHead + 1) % this.config.windowSize;
49
- if (this.ringSize < this.config.windowSize)
50
- this.ringSize++;
51
- // Count consecutive identical signatures walking backwards from the last
52
- // write. (ringHead points at the NEXT slot, so the most-recent is head-1.)
53
- let repeatCount = 0;
54
- for (let i = 0; i < this.ringSize; i++) {
55
- const idx = (this.ringHead - 1 - i + this.config.windowSize) % this.config.windowSize;
56
- if (this.ring[idx] === signature) {
57
- repeatCount++;
58
- }
59
- else {
60
- break;
61
- }
62
- }
63
- if (repeatCount >= this.config.maxRepeats) {
64
- logger.warn(`[${this.tabName}] Circuit breaker tripped: ${toolUse.name} repeated ${repeatCount} times`);
65
- this.tripped = true;
66
- return 'break';
67
- }
68
- if (repeatCount >= this.NOTIFY_THRESHOLD && !this.notified) {
69
- logger.warn(`[${this.tabName}] Loop detected: ${toolUse.name} repeated ${repeatCount} times — notifying user`);
70
- this.notified = true;
71
- return 'notify';
72
- }
73
- if (repeatCount >= this.WARN_THRESHOLD && !this.warned) {
74
- logger.info(`[${this.tabName}] Loop detected: ${toolUse.name} repeated ${repeatCount} times — warning`);
75
- this.warned = true;
76
- return 'warn';
77
- }
78
- return 'ok';
79
- }
80
- reset() {
81
- this.ring.fill(undefined);
82
- this.ringHead = 0;
83
- this.ringSize = 0;
84
- this.tripped = false;
85
- this.warned = false;
86
- this.notified = false;
87
- }
88
- get isTripped() {
89
- return this.tripped;
90
- }
91
- }
@@ -1,32 +0,0 @@
1
- /**
2
- * Context-window compaction: when Claude's context fills, summarize the
3
- * conversation, rotate to a fresh session, and continue with the summary as
4
- * the new system seed.
5
- *
6
- * Extracted from TabManager.executeMessage. Owns the recursion-depth limit
7
- * (MAX_DEPTH = 2) and the "fall back to original result" failure mode so
8
- * compaction errors degrade gracefully instead of orphaning the message.
9
- */
10
- import type Database from 'better-sqlite3';
11
- import type { SendResult } from './manager.js';
12
- import type { Tab } from '../types.js';
13
- export type NotifyFn = ((text: string) => Promise<void>) | null;
14
- export interface SendMessageFn {
15
- (tabName: string, prompt: string, options?: {
16
- onTextChunk?: (text: string) => void;
17
- _compactionDepth?: number;
18
- }): Promise<SendResult>;
19
- }
20
- export declare const ContextCompactor: {
21
- MAX_DEPTH: number;
22
- /**
23
- * Compact and continue the session. Returns the continuation result if
24
- * compaction succeeds, or the original result if anything goes wrong so the
25
- * user always gets *something* back.
26
- *
27
- * Important: callers should always run `processNextInQueue` (or equivalent)
28
- * after this resolves regardless of which path it took — the queue drain
29
- * obligation does not depend on compaction success.
30
- */
31
- compact(tab: Tab, enrichedPrompt: string, originalResult: SendResult, onTextChunk: ((text: string) => void) | undefined, currentDepth: number, sendMessage: SendMessageFn, notify: NotifyFn, db: Database.Database): Promise<SendResult>;
32
- };
@@ -1,45 +0,0 @@
1
- /**
2
- * Context-window compaction: when Claude's context fills, summarize the
3
- * conversation, rotate to a fresh session, and continue with the summary as
4
- * the new system seed.
5
- *
6
- * Extracted from TabManager.executeMessage. Owns the recursion-depth limit
7
- * (MAX_DEPTH = 2) and the "fall back to original result" failure mode so
8
- * compaction errors degrade gracefully instead of orphaning the message.
9
- */
10
- import { v4 as uuidv4 } from 'uuid';
11
- import { logger } from '../util/logger.js';
12
- export const ContextCompactor = {
13
- MAX_DEPTH: 2,
14
- /**
15
- * Compact and continue the session. Returns the continuation result if
16
- * compaction succeeds, or the original result if anything goes wrong so the
17
- * user always gets *something* back.
18
- *
19
- * Important: callers should always run `processNextInQueue` (or equivalent)
20
- * after this resolves regardless of which path it took — the queue drain
21
- * obligation does not depend on compaction success.
22
- */
23
- async compact(tab, enrichedPrompt, originalResult, onTextChunk, currentDepth, sendMessage, notify, db) {
24
- logger.info(`[${tab.name}] Compacting context (depth ${currentDepth + 1}/${ContextCompactor.MAX_DEPTH}) — requesting summary then restarting session`);
25
- notify?.(`🔄 [${tab.name}] Context window full — compacting and continuing...`).catch((err) => logger.warn('Notify failed:', err));
26
- try {
27
- const summaryPrompt = 'Summarize your progress in this session concisely: completed steps, current state, remaining steps, and all important identifiers (file paths, URLs, variable names). Output ONLY the summary.';
28
- const summaryResult = await sendMessage(tab.name, summaryPrompt, {
29
- _compactionDepth: currentDepth + 1,
30
- });
31
- const newSessionId = uuidv4();
32
- db.prepare('UPDATE tabs SET session_id = ? WHERE id = ?').run(newSessionId, tab.id);
33
- logger.info(`[${tab.name}] Context compacted — new session ${newSessionId.slice(0, 8)}...`);
34
- const continuationPrompt = `[CONTEXT RESTORED FROM PREVIOUS SESSION]\n${summaryResult.text}\n\n[Continue the original task: "${enrichedPrompt.slice(0, 500)}"]`;
35
- return await sendMessage(tab.name, continuationPrompt, {
36
- onTextChunk,
37
- _compactionDepth: currentDepth + 1,
38
- });
39
- }
40
- catch (err) {
41
- logger.error(`[${tab.name}] Compaction failed:`, err);
42
- return originalResult;
43
- }
44
- },
45
- };
@@ -1,15 +0,0 @@
1
- import type { StreamUsage } from '../types.js';
2
- export type ContextAction = 'ok' | 'warn' | 'checkpoint';
3
- export declare class ContextMonitor {
4
- private tabName;
5
- private cumulativeTokens;
6
- private contextWindow;
7
- private warned;
8
- private checkpointed;
9
- constructor(tabName: string, contextWindow?: number);
10
- /** Record token usage from a StreamAssistant or StreamResult event. Returns action needed. */
11
- recordUsage(usage: StreamUsage): ContextAction;
12
- get tokenCount(): number;
13
- get usageRatio(): number;
14
- reset(): void;
15
- }
@@ -1,44 +0,0 @@
1
- import { logger } from '../util/logger.js';
2
- const DEFAULT_CONTEXT_WINDOW = 200_000; // Claude's context window in tokens
3
- const WARNING_THRESHOLD = 0.8;
4
- const CHECKPOINT_THRESHOLD = 0.9;
5
- export class ContextMonitor {
6
- tabName;
7
- cumulativeTokens = 0;
8
- contextWindow;
9
- warned = false;
10
- checkpointed = false;
11
- constructor(tabName, contextWindow = DEFAULT_CONTEXT_WINDOW) {
12
- this.tabName = tabName;
13
- this.contextWindow = contextWindow;
14
- }
15
- /** Record token usage from a StreamAssistant or StreamResult event. Returns action needed. */
16
- recordUsage(usage) {
17
- // Only count input_tokens — this already includes cached tokens.
18
- // output_tokens don't consume context window; cache subtypes are part of input_tokens.
19
- this.cumulativeTokens += usage.input_tokens;
20
- const ratio = this.cumulativeTokens / this.contextWindow;
21
- if (ratio >= CHECKPOINT_THRESHOLD && !this.checkpointed) {
22
- this.checkpointed = true;
23
- logger.warn(`[${this.tabName}] Context at ${Math.round(ratio * 100)}% — checkpoint needed`);
24
- return 'checkpoint';
25
- }
26
- if (ratio >= WARNING_THRESHOLD && !this.warned) {
27
- this.warned = true;
28
- logger.info(`[${this.tabName}] Context at ${Math.round(ratio * 100)}% — warning`);
29
- return 'warn';
30
- }
31
- return 'ok';
32
- }
33
- get tokenCount() {
34
- return this.cumulativeTokens;
35
- }
36
- get usageRatio() {
37
- return this.cumulativeTokens / this.contextWindow;
38
- }
39
- reset() {
40
- this.cumulativeTokens = 0;
41
- this.warned = false;
42
- this.checkpointed = false;
43
- }
44
- }
@@ -1,21 +0,0 @@
1
- /**
2
- * Session handoff helpers — used by both the CLI (`beecork attach`) and the
3
- * shared command handler (`/handoff` from any channel).
4
- *
5
- * Moved here from `cli/handoff.ts` so daemon-shared code (channels, MCP) can
6
- * import without reaching into the CLI layer. The CLI-specific `attachTab`
7
- * (which spawns claude and calls process.exit) stays in `cli/handoff.ts`.
8
- */
9
- export interface TabHandoffInfo {
10
- name: string;
11
- sessionId: string;
12
- workingDir: string;
13
- status: string;
14
- lastActivity: string;
15
- recentMessages: Array<{
16
- role: string;
17
- content: string;
18
- }>;
19
- }
20
- export declare function exportTab(tabName: string): TabHandoffInfo | null;
21
- export declare function formatHandoffInfo(info: TabHandoffInfo): string;