beecork 1.7.0 → 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 (223) 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/daemon.d.ts +0 -1
  61. package/dist/daemon.js +0 -345
  62. package/dist/dashboard/html.d.ts +0 -1
  63. package/dist/dashboard/html.js +0 -849
  64. package/dist/dashboard/routes.d.ts +0 -17
  65. package/dist/dashboard/routes.js +0 -623
  66. package/dist/dashboard/server.d.ts +0 -1
  67. package/dist/dashboard/server.js +0 -104
  68. package/dist/db/connection.d.ts +0 -29
  69. package/dist/db/connection.js +0 -37
  70. package/dist/db/index.d.ts +0 -14
  71. package/dist/db/index.js +0 -127
  72. package/dist/db/migrations.d.ts +0 -2
  73. package/dist/db/migrations.js +0 -384
  74. package/dist/delegation/manager.d.ts +0 -18
  75. package/dist/delegation/manager.js +0 -89
  76. package/dist/index.d.ts +0 -2
  77. package/dist/knowledge/index.d.ts +0 -2
  78. package/dist/knowledge/index.js +0 -1
  79. package/dist/knowledge/manager.d.ts +0 -17
  80. package/dist/knowledge/manager.js +0 -160
  81. package/dist/knowledge/types.d.ts +0 -7
  82. package/dist/knowledge/types.js +0 -1
  83. package/dist/mcp/handlers.d.ts +0 -37
  84. package/dist/mcp/handlers.js +0 -520
  85. package/dist/mcp/server.d.ts +0 -2
  86. package/dist/mcp/server.js +0 -86
  87. package/dist/mcp/tool-definitions.d.ts +0 -1225
  88. package/dist/mcp/tool-definitions.js +0 -412
  89. package/dist/mcp/validate.d.ts +0 -23
  90. package/dist/mcp/validate.js +0 -65
  91. package/dist/media/factory.d.ts +0 -6
  92. package/dist/media/factory.js +0 -36
  93. package/dist/media/generators/dall-e.d.ts +0 -10
  94. package/dist/media/generators/dall-e.js +0 -41
  95. package/dist/media/generators/elevenlabs-music.d.ts +0 -9
  96. package/dist/media/generators/elevenlabs-music.js +0 -34
  97. package/dist/media/generators/elevenlabs-sfx.d.ts +0 -9
  98. package/dist/media/generators/elevenlabs-sfx.js +0 -33
  99. package/dist/media/generators/kling.d.ts +0 -9
  100. package/dist/media/generators/kling.js +0 -47
  101. package/dist/media/generators/lyria.d.ts +0 -10
  102. package/dist/media/generators/lyria.js +0 -41
  103. package/dist/media/generators/nano-banana.d.ts +0 -10
  104. package/dist/media/generators/nano-banana.js +0 -45
  105. package/dist/media/generators/poll-util.d.ts +0 -12
  106. package/dist/media/generators/poll-util.js +0 -22
  107. package/dist/media/generators/recraft.d.ts +0 -9
  108. package/dist/media/generators/recraft.js +0 -52
  109. package/dist/media/generators/runway.d.ts +0 -9
  110. package/dist/media/generators/runway.js +0 -49
  111. package/dist/media/generators/stable-diffusion.d.ts +0 -9
  112. package/dist/media/generators/stable-diffusion.js +0 -35
  113. package/dist/media/generators/veo.d.ts +0 -9
  114. package/dist/media/generators/veo.js +0 -32
  115. package/dist/media/index.d.ts +0 -6
  116. package/dist/media/index.js +0 -8
  117. package/dist/media/store.d.ts +0 -17
  118. package/dist/media/store.js +0 -69
  119. package/dist/media/types.d.ts +0 -43
  120. package/dist/media/types.js +0 -1
  121. package/dist/notifications/index.d.ts +0 -4
  122. package/dist/notifications/index.js +0 -21
  123. package/dist/notifications/ntfy.d.ts +0 -9
  124. package/dist/notifications/ntfy.js +0 -25
  125. package/dist/notifications/pushover.d.ts +0 -9
  126. package/dist/notifications/pushover.js +0 -26
  127. package/dist/notifications/types.d.ts +0 -5
  128. package/dist/notifications/types.js +0 -1
  129. package/dist/notifications/webhook-provider.d.ts +0 -9
  130. package/dist/notifications/webhook-provider.js +0 -24
  131. package/dist/observability/analytics.d.ts +0 -30
  132. package/dist/observability/analytics.js +0 -118
  133. package/dist/projects/index.d.ts +0 -4
  134. package/dist/projects/index.js +0 -2
  135. package/dist/projects/manager.d.ts +0 -13
  136. package/dist/projects/manager.js +0 -166
  137. package/dist/projects/router.d.ts +0 -17
  138. package/dist/projects/router.js +0 -246
  139. package/dist/projects/types.d.ts +0 -19
  140. package/dist/projects/types.js +0 -1
  141. package/dist/service/install.d.ts +0 -4
  142. package/dist/service/install.js +0 -146
  143. package/dist/service/templates.d.ts +0 -4
  144. package/dist/service/templates.js +0 -52
  145. package/dist/service/windows.d.ts +0 -8
  146. package/dist/service/windows.js +0 -59
  147. package/dist/session/budget-guard.d.ts +0 -20
  148. package/dist/session/budget-guard.js +0 -31
  149. package/dist/session/circuit-breaker.d.ts +0 -19
  150. package/dist/session/circuit-breaker.js +0 -91
  151. package/dist/session/context-compactor.d.ts +0 -32
  152. package/dist/session/context-compactor.js +0 -45
  153. package/dist/session/context-monitor.d.ts +0 -15
  154. package/dist/session/context-monitor.js +0 -44
  155. package/dist/session/handoff.d.ts +0 -21
  156. package/dist/session/handoff.js +0 -50
  157. package/dist/session/manager.d.ts +0 -60
  158. package/dist/session/manager.js +0 -379
  159. package/dist/session/memory-store.d.ts +0 -29
  160. package/dist/session/memory-store.js +0 -45
  161. package/dist/session/message-queue.d.ts +0 -28
  162. package/dist/session/message-queue.js +0 -52
  163. package/dist/session/pending-dispatcher.d.ts +0 -31
  164. package/dist/session/pending-dispatcher.js +0 -120
  165. package/dist/session/pending-store.d.ts +0 -60
  166. package/dist/session/pending-store.js +0 -118
  167. package/dist/session/stale-session.d.ts +0 -31
  168. package/dist/session/stale-session.js +0 -45
  169. package/dist/session/subprocess.d.ts +0 -25
  170. package/dist/session/subprocess.js +0 -189
  171. package/dist/session/tab-store.d.ts +0 -28
  172. package/dist/session/tab-store.js +0 -78
  173. package/dist/tasks/scheduler.d.ts +0 -45
  174. package/dist/tasks/scheduler.js +0 -329
  175. package/dist/tasks/store.d.ts +0 -11
  176. package/dist/tasks/store.js +0 -103
  177. package/dist/timeline/index.d.ts +0 -3
  178. package/dist/timeline/index.js +0 -2
  179. package/dist/timeline/logger.d.ts +0 -8
  180. package/dist/timeline/logger.js +0 -11
  181. package/dist/timeline/query.d.ts +0 -11
  182. package/dist/timeline/query.js +0 -67
  183. package/dist/timeline/types.d.ts +0 -12
  184. package/dist/timeline/types.js +0 -1
  185. package/dist/types.d.ts +0 -216
  186. package/dist/types.js +0 -3
  187. package/dist/util/auto-heal.d.ts +0 -43
  188. package/dist/util/auto-heal.js +0 -107
  189. package/dist/util/install-info.d.ts +0 -37
  190. package/dist/util/install-info.js +0 -80
  191. package/dist/util/logger.d.ts +0 -18
  192. package/dist/util/logger.js +0 -118
  193. package/dist/util/paths.d.ts +0 -13
  194. package/dist/util/paths.js +0 -55
  195. package/dist/util/platform.d.ts +0 -2
  196. package/dist/util/platform.js +0 -11
  197. package/dist/util/progress.d.ts +0 -34
  198. package/dist/util/progress.js +0 -133
  199. package/dist/util/rate-limiter.d.ts +0 -14
  200. package/dist/util/rate-limiter.js +0 -50
  201. package/dist/util/retry.d.ts +0 -2
  202. package/dist/util/retry.js +0 -18
  203. package/dist/util/text.d.ts +0 -32
  204. package/dist/util/text.js +0 -101
  205. package/dist/version.d.ts +0 -1
  206. package/dist/version.js +0 -4
  207. package/dist/voice/index.d.ts +0 -17
  208. package/dist/voice/index.js +0 -42
  209. package/dist/voice/stt.d.ts +0 -16
  210. package/dist/voice/stt.js +0 -57
  211. package/dist/voice/tts.d.ts +0 -23
  212. package/dist/voice/tts.js +0 -84
  213. package/dist/watchers/evaluator.d.ts +0 -5
  214. package/dist/watchers/evaluator.js +0 -45
  215. package/dist/watchers/index.d.ts +0 -4
  216. package/dist/watchers/index.js +0 -3
  217. package/dist/watchers/scheduler.d.ts +0 -20
  218. package/dist/watchers/scheduler.js +0 -183
  219. package/dist/watchers/store.d.ts +0 -10
  220. package/dist/watchers/store.js +0 -56
  221. package/dist/watchers/types.d.ts +0 -15
  222. package/dist/watchers/types.js +0 -1
  223. package/scripts/postinstall.mjs +0 -50
@@ -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;
@@ -1,50 +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
- import { getDb } from '../db/index.js';
10
- import { TabStore } from './tab-store.js';
11
- export function exportTab(tabName) {
12
- const tab = TabStore.findByName(tabName);
13
- if (!tab)
14
- return null;
15
- const messages = getDb()
16
- .prepare('SELECT role, content FROM messages WHERE tab_id = ? ORDER BY created_at DESC LIMIT 5')
17
- .all(tab.id);
18
- return {
19
- name: tab.name,
20
- sessionId: tab.sessionId,
21
- workingDir: tab.workingDir,
22
- status: tab.status,
23
- lastActivity: tab.lastActivityAt,
24
- recentMessages: messages.reverse(),
25
- };
26
- }
27
- export function formatHandoffInfo(info) {
28
- const lines = [
29
- `Session Handoff — tab "${info.name}"`,
30
- '',
31
- `Session ID: ${info.sessionId}`,
32
- `Working dir: ${info.workingDir}`,
33
- `Status: ${info.status}`,
34
- `Last activity: ${info.lastActivity}`,
35
- '',
36
- 'To resume in terminal:',
37
- ` beecork attach ${info.name}`,
38
- '',
39
- 'Or manually:',
40
- ` cd ${info.workingDir}`,
41
- ` claude --session-id ${info.sessionId} --resume`,
42
- ];
43
- if (info.recentMessages.length > 0) {
44
- lines.push('', 'Recent context:');
45
- for (const msg of info.recentMessages) {
46
- lines.push(` [${msg.role}] ${msg.content.slice(0, 150)}${msg.content.length > 150 ? '...' : ''}`);
47
- }
48
- }
49
- return lines.join('\n');
50
- }
@@ -1,60 +0,0 @@
1
- import type { BeecorkConfig, Tab } from '../types.js';
2
- export type { StreamResult } from '../types.js';
3
- export interface SendResult {
4
- text: string;
5
- costUsd: number;
6
- durationMs: number;
7
- sessionId: string;
8
- error: boolean;
9
- }
10
- export type NotifyCallback = (text: string) => Promise<void>;
11
- /**
12
- * TabManager orchestrates per-tab Claude subprocess lifecycles. Heavy lifting
13
- * (queueing, budget enforcement, stale-session recovery, context compaction,
14
- * pending-message dispatch) is delegated to collaborators in this directory
15
- * so this class stays focused on:
16
- *
17
- * - tab CRUD (ensureTab, listTabs, stopTab, closeTab, stopAll)
18
- * - subprocess orchestration (executeMessage)
19
- * - wiring the collaborators together
20
- *
21
- * The split happened in the 2026-05-15 audit fix; see the audit file for the
22
- * rationale. Before the split this file was 467 lines and 10 responsibilities.
23
- */
24
- export declare class TabManager {
25
- private config;
26
- private subprocesses;
27
- private queue;
28
- private budget;
29
- private tabCostCache;
30
- private onNotify;
31
- constructor(config: BeecorkConfig);
32
- /** Set a callback for sending notifications (e.g., via Telegram) */
33
- setNotifyCallback(cb: NotifyCallback): void;
34
- /** Ensure a tab exists in the database. Creates it if missing. */
35
- ensureTab(tabName: string, workingDirOverride?: string): Tab;
36
- /** Send a message to a tab. Creates the tab if it doesn't exist. Queues if busy. */
37
- sendMessage(tabName: string, prompt: string, options?: {
38
- resume?: boolean;
39
- onTextChunk?: (text: string) => void;
40
- onToolUse?: (toolName: string, toolInput: Record<string, unknown>) => void;
41
- projectPath?: string;
42
- _compactionDepth?: number;
43
- }): Promise<SendResult>;
44
- /** Get all tabs from the database */
45
- listTabs(): Tab[];
46
- /** Get a specific tab */
47
- getTab(tabName: string): Tab | undefined;
48
- /** Stop a tab's running subprocess */
49
- stopTab(tabName: string): void;
50
- /** Update a tab's system_prompt. Returns true if the tab existed. */
51
- setSystemPrompt(tabName: string, systemPrompt: string): boolean;
52
- /** Close a tab — stop subprocess and delete its rows. Returns true if the tab existed. */
53
- closeTab(tabName: string): boolean;
54
- /** Stop all running subprocesses (clean shutdown) */
55
- stopAll(): void;
56
- private executeMessage;
57
- private processNextInQueue;
58
- private updateTabStatus;
59
- private clearQueue;
60
- }