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.
- package/README.md +52 -111
- package/dist/index.js +1394 -581
- package/package.json +26 -54
- package/dist/capabilities/index.d.ts +0 -3
- package/dist/capabilities/index.js +0 -2
- package/dist/capabilities/manager.d.ts +0 -13
- package/dist/capabilities/manager.js +0 -115
- package/dist/capabilities/packs.d.ts +0 -2
- package/dist/capabilities/packs.js +0 -54
- package/dist/capabilities/types.d.ts +0 -21
- package/dist/capabilities/types.js +0 -1
- package/dist/channels/admin.d.ts +0 -10
- package/dist/channels/admin.js +0 -20
- package/dist/channels/command-handler.d.ts +0 -19
- package/dist/channels/command-handler.js +0 -235
- package/dist/channels/discord.d.ts +0 -17
- package/dist/channels/discord.js +0 -266
- package/dist/channels/index.d.ts +0 -7
- package/dist/channels/index.js +0 -6
- package/dist/channels/loader.d.ts +0 -7
- package/dist/channels/loader.js +0 -87
- package/dist/channels/pipeline.d.ts +0 -50
- package/dist/channels/pipeline.js +0 -92
- package/dist/channels/registry.d.ts +0 -36
- package/dist/channels/registry.js +0 -80
- package/dist/channels/send-helpers.d.ts +0 -19
- package/dist/channels/send-helpers.js +0 -21
- package/dist/channels/telegram.d.ts +0 -47
- package/dist/channels/telegram.js +0 -649
- package/dist/channels/types.d.ts +0 -41
- package/dist/channels/types.js +0 -1
- package/dist/channels/voice-state.d.ts +0 -29
- package/dist/channels/voice-state.js +0 -45
- package/dist/channels/webhook.d.ts +0 -16
- package/dist/channels/webhook.js +0 -222
- package/dist/channels/whatsapp.d.ts +0 -28
- package/dist/channels/whatsapp.js +0 -323
- package/dist/cli/capabilities.d.ts +0 -3
- package/dist/cli/capabilities.js +0 -72
- package/dist/cli/channel.d.ts +0 -3
- package/dist/cli/channel.js +0 -202
- package/dist/cli/commands.d.ts +0 -15
- package/dist/cli/commands.js +0 -279
- package/dist/cli/doctor.d.ts +0 -1
- package/dist/cli/doctor.js +0 -208
- package/dist/cli/handoff.d.ts +0 -8
- package/dist/cli/handoff.js +0 -33
- package/dist/cli/helpers.d.ts +0 -2
- package/dist/cli/helpers.js +0 -21
- package/dist/cli/mcp.d.ts +0 -3
- package/dist/cli/mcp.js +0 -47
- package/dist/cli/media.d.ts +0 -2
- package/dist/cli/media.js +0 -125
- package/dist/cli/setup.d.ts +0 -1
- package/dist/cli/setup.js +0 -239
- package/dist/cli/store.d.ts +0 -3
- package/dist/cli/store.js +0 -108
- package/dist/config.d.ts +0 -11
- package/dist/config.js +0 -115
- package/dist/cron/scheduler.d.ts +0 -22
- package/dist/cron/scheduler.js +0 -220
- package/dist/cron/store.d.ts +0 -12
- package/dist/cron/store.js +0 -83
- package/dist/daemon.d.ts +0 -1
- package/dist/daemon.js +0 -345
- package/dist/dashboard/html.d.ts +0 -1
- package/dist/dashboard/html.js +0 -849
- package/dist/dashboard/routes.d.ts +0 -17
- package/dist/dashboard/routes.js +0 -623
- package/dist/dashboard/server.d.ts +0 -1
- package/dist/dashboard/server.js +0 -104
- package/dist/db/connection.d.ts +0 -29
- package/dist/db/connection.js +0 -37
- package/dist/db/index.d.ts +0 -14
- package/dist/db/index.js +0 -127
- package/dist/db/migrations.d.ts +0 -2
- package/dist/db/migrations.js +0 -384
- package/dist/delegation/manager.d.ts +0 -18
- package/dist/delegation/manager.js +0 -89
- package/dist/index.d.ts +0 -2
- package/dist/knowledge/index.d.ts +0 -2
- package/dist/knowledge/index.js +0 -1
- package/dist/knowledge/manager.d.ts +0 -17
- package/dist/knowledge/manager.js +0 -160
- package/dist/knowledge/types.d.ts +0 -7
- package/dist/knowledge/types.js +0 -1
- package/dist/machines/forwarder.d.ts +0 -7
- package/dist/machines/forwarder.js +0 -35
- package/dist/machines/index.d.ts +0 -1
- package/dist/machines/index.js +0 -1
- package/dist/machines/registry.d.ts +0 -15
- package/dist/machines/registry.js +0 -46
- package/dist/mcp/handlers.d.ts +0 -37
- package/dist/mcp/handlers.js +0 -520
- package/dist/mcp/server.d.ts +0 -2
- package/dist/mcp/server.js +0 -86
- package/dist/mcp/tool-definitions.d.ts +0 -1225
- package/dist/mcp/tool-definitions.js +0 -412
- package/dist/mcp/validate.d.ts +0 -23
- package/dist/mcp/validate.js +0 -65
- package/dist/media/factory.d.ts +0 -6
- package/dist/media/factory.js +0 -36
- package/dist/media/generators/dall-e.d.ts +0 -10
- package/dist/media/generators/dall-e.js +0 -41
- package/dist/media/generators/elevenlabs-music.d.ts +0 -9
- package/dist/media/generators/elevenlabs-music.js +0 -34
- package/dist/media/generators/elevenlabs-sfx.d.ts +0 -9
- package/dist/media/generators/elevenlabs-sfx.js +0 -33
- package/dist/media/generators/kling.d.ts +0 -9
- package/dist/media/generators/kling.js +0 -47
- package/dist/media/generators/lyria.d.ts +0 -10
- package/dist/media/generators/lyria.js +0 -41
- package/dist/media/generators/nano-banana.d.ts +0 -10
- package/dist/media/generators/nano-banana.js +0 -45
- package/dist/media/generators/poll-util.d.ts +0 -12
- package/dist/media/generators/poll-util.js +0 -22
- package/dist/media/generators/recraft.d.ts +0 -9
- package/dist/media/generators/recraft.js +0 -52
- package/dist/media/generators/runway.d.ts +0 -9
- package/dist/media/generators/runway.js +0 -49
- package/dist/media/generators/stable-diffusion.d.ts +0 -9
- package/dist/media/generators/stable-diffusion.js +0 -35
- package/dist/media/generators/veo.d.ts +0 -9
- package/dist/media/generators/veo.js +0 -32
- package/dist/media/index.d.ts +0 -6
- package/dist/media/index.js +0 -8
- package/dist/media/loader.d.ts +0 -8
- package/dist/media/loader.js +0 -46
- package/dist/media/store.d.ts +0 -17
- package/dist/media/store.js +0 -69
- package/dist/media/types.d.ts +0 -43
- package/dist/media/types.js +0 -1
- package/dist/memory/extractor.d.ts +0 -5
- package/dist/memory/extractor.js +0 -157
- package/dist/notifications/index.d.ts +0 -4
- package/dist/notifications/index.js +0 -21
- package/dist/notifications/ntfy.d.ts +0 -9
- package/dist/notifications/ntfy.js +0 -25
- package/dist/notifications/pushover.d.ts +0 -9
- package/dist/notifications/pushover.js +0 -26
- package/dist/notifications/types.d.ts +0 -5
- package/dist/notifications/types.js +0 -1
- package/dist/notifications/webhook-provider.d.ts +0 -9
- package/dist/notifications/webhook-provider.js +0 -24
- package/dist/observability/analytics.d.ts +0 -30
- package/dist/observability/analytics.js +0 -118
- package/dist/pipe/anthropic-client.d.ts +0 -9
- package/dist/pipe/anthropic-client.js +0 -50
- package/dist/pipe/brain.d.ts +0 -16
- package/dist/pipe/brain.js +0 -89
- package/dist/pipe/memory-store.d.ts +0 -8
- package/dist/pipe/memory-store.js +0 -39
- package/dist/pipe/project-scanner.d.ts +0 -6
- package/dist/pipe/project-scanner.js +0 -26
- package/dist/pipe/types.d.ts +0 -34
- package/dist/pipe/types.js +0 -1
- package/dist/projects/index.d.ts +0 -4
- package/dist/projects/index.js +0 -2
- package/dist/projects/manager.d.ts +0 -13
- package/dist/projects/manager.js +0 -166
- package/dist/projects/router.d.ts +0 -17
- package/dist/projects/router.js +0 -246
- package/dist/projects/types.d.ts +0 -19
- package/dist/projects/types.js +0 -1
- package/dist/service/install.d.ts +0 -4
- package/dist/service/install.js +0 -146
- package/dist/service/templates.d.ts +0 -4
- package/dist/service/templates.js +0 -52
- package/dist/service/windows.d.ts +0 -8
- package/dist/service/windows.js +0 -59
- package/dist/session/budget-guard.d.ts +0 -20
- package/dist/session/budget-guard.js +0 -31
- package/dist/session/circuit-breaker.d.ts +0 -19
- package/dist/session/circuit-breaker.js +0 -91
- package/dist/session/context-compactor.d.ts +0 -32
- package/dist/session/context-compactor.js +0 -45
- package/dist/session/context-monitor.d.ts +0 -15
- package/dist/session/context-monitor.js +0 -44
- package/dist/session/handoff.d.ts +0 -21
- package/dist/session/handoff.js +0 -50
- package/dist/session/manager.d.ts +0 -60
- package/dist/session/manager.js +0 -416
- package/dist/session/memory-store.d.ts +0 -29
- package/dist/session/memory-store.js +0 -45
- package/dist/session/message-queue.d.ts +0 -28
- package/dist/session/message-queue.js +0 -52
- package/dist/session/pending-dispatcher.d.ts +0 -31
- package/dist/session/pending-dispatcher.js +0 -120
- package/dist/session/pending-store.d.ts +0 -60
- package/dist/session/pending-store.js +0 -118
- package/dist/session/stale-session.d.ts +0 -31
- package/dist/session/stale-session.js +0 -45
- package/dist/session/subprocess.d.ts +0 -32
- package/dist/session/subprocess.js +0 -230
- package/dist/session/tab-store.d.ts +0 -28
- package/dist/session/tab-store.js +0 -78
- package/dist/session/tool-classifier.d.ts +0 -4
- package/dist/session/tool-classifier.js +0 -56
- package/dist/tasks/scheduler.d.ts +0 -45
- package/dist/tasks/scheduler.js +0 -329
- package/dist/tasks/store.d.ts +0 -11
- package/dist/tasks/store.js +0 -103
- package/dist/timeline/index.d.ts +0 -3
- package/dist/timeline/index.js +0 -2
- package/dist/timeline/logger.d.ts +0 -8
- package/dist/timeline/logger.js +0 -11
- package/dist/timeline/query.d.ts +0 -11
- package/dist/timeline/query.js +0 -67
- package/dist/timeline/types.d.ts +0 -12
- package/dist/timeline/types.js +0 -1
- package/dist/types.d.ts +0 -225
- package/dist/types.js +0 -3
- package/dist/users/index.d.ts +0 -2
- package/dist/users/index.js +0 -1
- package/dist/users/service.d.ts +0 -17
- package/dist/users/service.js +0 -46
- package/dist/util/auto-heal.d.ts +0 -43
- package/dist/util/auto-heal.js +0 -107
- package/dist/util/install-info.d.ts +0 -37
- package/dist/util/install-info.js +0 -80
- package/dist/util/logger.d.ts +0 -18
- package/dist/util/logger.js +0 -118
- package/dist/util/paths.d.ts +0 -13
- package/dist/util/paths.js +0 -55
- package/dist/util/platform.d.ts +0 -2
- package/dist/util/platform.js +0 -11
- package/dist/util/progress.d.ts +0 -34
- package/dist/util/progress.js +0 -133
- package/dist/util/rate-limiter.d.ts +0 -14
- package/dist/util/rate-limiter.js +0 -50
- package/dist/util/retry.d.ts +0 -2
- package/dist/util/retry.js +0 -18
- package/dist/util/text.d.ts +0 -32
- package/dist/util/text.js +0 -101
- package/dist/version.d.ts +0 -1
- package/dist/version.js +0 -4
- package/dist/voice/index.d.ts +0 -17
- package/dist/voice/index.js +0 -42
- package/dist/voice/stt.d.ts +0 -16
- package/dist/voice/stt.js +0 -57
- package/dist/voice/tts.d.ts +0 -23
- package/dist/voice/tts.js +0 -84
- package/dist/watchers/evaluator.d.ts +0 -5
- package/dist/watchers/evaluator.js +0 -45
- package/dist/watchers/index.d.ts +0 -4
- package/dist/watchers/index.js +0 -3
- package/dist/watchers/scheduler.d.ts +0 -20
- package/dist/watchers/scheduler.js +0 -183
- package/dist/watchers/store.d.ts +0 -10
- package/dist/watchers/store.js +0 -56
- package/dist/watchers/types.d.ts +0 -15
- package/dist/watchers/types.js +0 -1
- package/scripts/postinstall.mjs +0 -50
package/dist/projects/types.d.ts
DELETED
|
@@ -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
|
-
}
|
package/dist/projects/types.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/service/install.js
DELETED
|
@@ -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;
|
package/dist/service/windows.js
DELETED
|
@@ -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;
|