beecork 1.5.0 → 1.7.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.
- package/dist/capabilities/index.d.ts +1 -1
- package/dist/capabilities/index.js +1 -1
- package/dist/capabilities/manager.js +13 -9
- package/dist/capabilities/packs.js +3 -1
- package/dist/channels/command-handler.js +46 -14
- package/dist/channels/discord.d.ts +3 -6
- package/dist/channels/discord.js +40 -23
- package/dist/channels/index.d.ts +1 -1
- package/dist/channels/loader.js +13 -3
- package/dist/channels/pipeline.js +14 -5
- package/dist/channels/registry.d.ts +17 -1
- package/dist/channels/registry.js +33 -4
- package/dist/channels/telegram.d.ts +20 -5
- package/dist/channels/telegram.js +177 -42
- package/dist/channels/types.d.ts +11 -28
- package/dist/channels/voice-state.js +3 -1
- package/dist/channels/webhook.d.ts +1 -4
- package/dist/channels/webhook.js +26 -11
- package/dist/channels/whatsapp.d.ts +8 -4
- package/dist/channels/whatsapp.js +65 -29
- package/dist/cli/capabilities.js +4 -4
- package/dist/cli/channel.js +16 -6
- package/dist/cli/commands.js +12 -9
- package/dist/cli/doctor.js +80 -25
- package/dist/cli/handoff.d.ts +7 -14
- package/dist/cli/handoff.js +9 -44
- package/dist/cli/mcp.js +5 -5
- package/dist/cli/media.js +21 -8
- package/dist/cli/setup.js +9 -8
- package/dist/cli/store.js +29 -12
- package/dist/config.js +5 -10
- package/dist/daemon.js +88 -38
- package/dist/dashboard/html.js +80 -12
- package/dist/dashboard/routes.js +143 -79
- package/dist/dashboard/server.js +5 -1
- package/dist/db/connection.d.ts +29 -0
- package/dist/db/connection.js +37 -0
- package/dist/db/index.js +30 -12
- package/dist/db/migrations.js +84 -28
- package/dist/delegation/manager.js +10 -4
- package/dist/index.js +39 -59
- package/dist/knowledge/manager.js +26 -12
- package/dist/mcp/handlers.js +126 -57
- package/dist/mcp/server.js +20 -10
- package/dist/mcp/tool-definitions.js +68 -20
- package/dist/mcp/validate.d.ts +23 -0
- package/dist/mcp/validate.js +65 -0
- package/dist/media/factory.js +18 -14
- package/dist/media/generators/dall-e.js +2 -2
- package/dist/media/generators/kling.js +4 -4
- package/dist/media/generators/lyria.js +1 -1
- package/dist/media/generators/nano-banana.d.ts +1 -1
- package/dist/media/generators/nano-banana.js +2 -2
- package/dist/media/generators/poll-util.js +4 -4
- package/dist/media/generators/recraft.js +3 -3
- package/dist/media/generators/runway.js +4 -4
- package/dist/media/generators/stable-diffusion.js +2 -2
- package/dist/media/generators/veo.js +1 -1
- package/dist/media/index.js +1 -1
- package/dist/media/store.d.ts +7 -0
- package/dist/media/store.js +18 -4
- package/dist/media/types.d.ts +22 -0
- package/dist/notifications/index.d.ts +2 -4
- package/dist/notifications/index.js +6 -19
- package/dist/notifications/ntfy.js +3 -3
- package/dist/observability/analytics.js +35 -13
- package/dist/projects/index.d.ts +1 -1
- package/dist/projects/index.js +1 -1
- package/dist/projects/manager.d.ts +0 -4
- package/dist/projects/manager.js +51 -28
- package/dist/projects/router.d.ts +2 -0
- package/dist/projects/router.js +70 -45
- package/dist/service/install.js +15 -5
- package/dist/service/windows.js +1 -1
- package/dist/session/budget-guard.d.ts +20 -0
- package/dist/session/budget-guard.js +31 -0
- package/dist/session/circuit-breaker.d.ts +5 -3
- package/dist/session/circuit-breaker.js +45 -20
- package/dist/session/context-compactor.d.ts +32 -0
- package/dist/session/context-compactor.js +45 -0
- package/dist/session/context-monitor.js +2 -2
- package/dist/session/handoff.d.ts +21 -0
- package/dist/session/handoff.js +50 -0
- package/dist/session/manager.d.ts +17 -5
- package/dist/session/manager.js +153 -146
- package/dist/session/memory-store.d.ts +29 -0
- package/dist/session/memory-store.js +45 -0
- package/dist/session/message-queue.d.ts +28 -0
- package/dist/session/message-queue.js +52 -0
- package/dist/session/pending-dispatcher.d.ts +31 -0
- package/dist/session/pending-dispatcher.js +120 -0
- package/dist/session/pending-store.d.ts +60 -0
- package/dist/session/pending-store.js +118 -0
- package/dist/session/stale-session.d.ts +31 -0
- package/dist/session/stale-session.js +45 -0
- package/dist/session/subprocess.d.ts +2 -0
- package/dist/session/subprocess.js +33 -11
- package/dist/session/tab-store.js +4 -3
- package/dist/tasks/scheduler.d.ts +7 -0
- package/dist/tasks/scheduler.js +46 -6
- package/dist/tasks/store.js +20 -6
- package/dist/timeline/logger.js +3 -1
- package/dist/timeline/query.js +9 -3
- package/dist/types.d.ts +34 -9
- package/dist/util/auto-heal.js +15 -5
- package/dist/util/install-info.js +3 -1
- package/dist/util/logger.d.ts +1 -1
- package/dist/util/logger.js +63 -24
- package/dist/util/paths.d.ts +1 -0
- package/dist/util/paths.js +12 -2
- package/dist/util/retry.js +1 -1
- package/dist/util/text.js +13 -7
- package/dist/voice/index.js +5 -1
- package/dist/voice/stt.js +14 -6
- package/dist/voice/tts.js +1 -1
- package/dist/watchers/scheduler.js +9 -2
- package/package.json +18 -13
- package/dist/session/tool-classifier.d.ts +0 -4
- package/dist/session/tool-classifier.js +0 -56
|
@@ -0,0 +1,45 @@
|
|
|
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,7 +1,7 @@
|
|
|
1
1
|
import { logger } from '../util/logger.js';
|
|
2
2
|
const DEFAULT_CONTEXT_WINDOW = 200_000; // Claude's context window in tokens
|
|
3
|
-
const WARNING_THRESHOLD = 0.
|
|
4
|
-
const CHECKPOINT_THRESHOLD = 0.
|
|
3
|
+
const WARNING_THRESHOLD = 0.8;
|
|
4
|
+
const CHECKPOINT_THRESHOLD = 0.9;
|
|
5
5
|
export class ContextMonitor {
|
|
6
6
|
tabName;
|
|
7
7
|
cumulativeTokens = 0;
|
|
@@ -0,0 +1,21 @@
|
|
|
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;
|
|
@@ -0,0 +1,50 @@
|
|
|
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,4 +1,5 @@
|
|
|
1
1
|
import type { BeecorkConfig, Tab } from '../types.js';
|
|
2
|
+
export type { StreamResult } from '../types.js';
|
|
2
3
|
export interface SendResult {
|
|
3
4
|
text: string;
|
|
4
5
|
costUsd: number;
|
|
@@ -7,11 +8,25 @@ export interface SendResult {
|
|
|
7
8
|
error: boolean;
|
|
8
9
|
}
|
|
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
|
+
*/
|
|
10
24
|
export declare class TabManager {
|
|
11
25
|
private config;
|
|
12
26
|
private subprocesses;
|
|
13
|
-
private
|
|
14
|
-
private
|
|
27
|
+
private queue;
|
|
28
|
+
private budget;
|
|
29
|
+
private tabCostCache;
|
|
15
30
|
private onNotify;
|
|
16
31
|
constructor(config: BeecorkConfig);
|
|
17
32
|
/** Set a callback for sending notifications (e.g., via Telegram) */
|
|
@@ -30,7 +45,6 @@ export declare class TabManager {
|
|
|
30
45
|
listTabs(): Tab[];
|
|
31
46
|
/** Get a specific tab */
|
|
32
47
|
getTab(tabName: string): Tab | undefined;
|
|
33
|
-
private queryTab;
|
|
34
48
|
/** Stop a tab's running subprocess */
|
|
35
49
|
stopTab(tabName: string): void;
|
|
36
50
|
/** Update a tab's system_prompt. Returns true if the tab existed. */
|
|
@@ -39,8 +53,6 @@ export declare class TabManager {
|
|
|
39
53
|
closeTab(tabName: string): boolean;
|
|
40
54
|
/** Stop all running subprocesses (clean shutdown) */
|
|
41
55
|
stopAll(): void;
|
|
42
|
-
/** Process pending messages from MCP server IPC */
|
|
43
|
-
processPendingMessages(): void;
|
|
44
56
|
private executeMessage;
|
|
45
57
|
private processNextInQueue;
|
|
46
58
|
private updateTabStatus;
|