@saccolabs/tars 1.0.7
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 +93 -0
- package/context/GEMINI.md +13 -0
- package/context/config/settings.json-template +36 -0
- package/context/skills/create-extension/SKILL.md +90 -0
- package/context/skills/create-skill/SKILL.md +33 -0
- package/context/skills/manage-extensions/SKILL.md +69 -0
- package/context/skills/tars-ops/SKILL.md +89 -0
- package/dist/cli/commands/discord.d.ts +4 -0
- package/dist/cli/commands/discord.js +48 -0
- package/dist/cli/commands/discord.js.map +1 -0
- package/dist/cli/commands/export.d.ts +3 -0
- package/dist/cli/commands/export.js +39 -0
- package/dist/cli/commands/export.js.map +1 -0
- package/dist/cli/commands/import.d.ts +1 -0
- package/dist/cli/commands/import.js +45 -0
- package/dist/cli/commands/import.js.map +1 -0
- package/dist/cli/commands/logs.d.ts +4 -0
- package/dist/cli/commands/logs.js +23 -0
- package/dist/cli/commands/logs.js.map +1 -0
- package/dist/cli/commands/memory.d.ts +1 -0
- package/dist/cli/commands/memory.js +35 -0
- package/dist/cli/commands/memory.js.map +1 -0
- package/dist/cli/commands/secret.d.ts +6 -0
- package/dist/cli/commands/secret.js +46 -0
- package/dist/cli/commands/secret.js.map +1 -0
- package/dist/cli/commands/setup.d.ts +4 -0
- package/dist/cli/commands/setup.js +329 -0
- package/dist/cli/commands/setup.js.map +1 -0
- package/dist/cli/commands/start.d.ts +1 -0
- package/dist/cli/commands/start.js +42 -0
- package/dist/cli/commands/start.js.map +1 -0
- package/dist/cli/commands/status.d.ts +1 -0
- package/dist/cli/commands/status.js +56 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/stop.d.ts +1 -0
- package/dist/cli/commands/stop.js +38 -0
- package/dist/cli/commands/stop.js.map +1 -0
- package/dist/cli/commands/uninstall.d.ts +1 -0
- package/dist/cli/commands/uninstall.js +91 -0
- package/dist/cli/commands/uninstall.js.map +1 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +54 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/config/config.d.ts +14 -0
- package/dist/config/config.js +69 -0
- package/dist/config/config.js.map +1 -0
- package/dist/discord/discord-bot.d.ts +32 -0
- package/dist/discord/discord-bot.js +151 -0
- package/dist/discord/discord-bot.js.map +1 -0
- package/dist/discord/message-formatter.d.ts +95 -0
- package/dist/discord/message-formatter.js +448 -0
- package/dist/discord/message-formatter.js.map +1 -0
- package/dist/memory/knowledge-store.d.ts +24 -0
- package/dist/memory/knowledge-store.js +126 -0
- package/dist/memory/knowledge-store.js.map +1 -0
- package/dist/memory/memory-manager.d.ts +24 -0
- package/dist/memory/memory-manager.js +101 -0
- package/dist/memory/memory-manager.js.map +1 -0
- package/dist/scripts/debug-cli.d.ts +1 -0
- package/dist/scripts/debug-cli.js +52 -0
- package/dist/scripts/debug-cli.js.map +1 -0
- package/dist/supervisor/gemini-cli.d.ts +28 -0
- package/dist/supervisor/gemini-cli.js +315 -0
- package/dist/supervisor/gemini-cli.js.map +1 -0
- package/dist/supervisor/heartbeat-service.d.ts +21 -0
- package/dist/supervisor/heartbeat-service.js +143 -0
- package/dist/supervisor/heartbeat-service.js.map +1 -0
- package/dist/supervisor/main.d.ts +1 -0
- package/dist/supervisor/main.js +242 -0
- package/dist/supervisor/main.js.map +1 -0
- package/dist/supervisor/session-manager.d.ts +47 -0
- package/dist/supervisor/session-manager.js +118 -0
- package/dist/supervisor/session-manager.js.map +1 -0
- package/dist/supervisor/supervisor.d.ts +32 -0
- package/dist/supervisor/supervisor.js +98 -0
- package/dist/supervisor/supervisor.js.map +1 -0
- package/dist/types/index.d.ts +42 -0
- package/dist/types/index.js +5 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/attachment-processor.d.ts +22 -0
- package/dist/utils/attachment-processor.js +79 -0
- package/dist/utils/attachment-processor.js.map +1 -0
- package/dist/utils/logger.d.ts +6 -0
- package/dist/utils/logger.js +15 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/secrets-manager.d.ts +27 -0
- package/dist/utils/secrets-manager.js +79 -0
- package/dist/utils/secrets-manager.js.map +1 -0
- package/dist/utils/version.d.ts +3 -0
- package/dist/utils/version.js +23 -0
- package/dist/utils/version.js.map +1 -0
- package/extensions/tasks/gemini-extension.json +14 -0
- package/extensions/tasks/package-lock.json +1209 -0
- package/extensions/tasks/package.json +19 -0
- package/extensions/tasks/src/server.ts +265 -0
- package/extensions/tasks/src/store.ts +92 -0
- package/extensions/tasks/tsconfig.json +14 -0
- package/package.json +55 -0
- package/src/prompts/system.md +25 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { KnowledgeStore } from './knowledge-store.js';
|
|
4
|
+
import logger from '../utils/logger.js';
|
|
5
|
+
/**
|
|
6
|
+
* MemoryManager - High-level interface for Tars' memory systems.
|
|
7
|
+
* Manages the transition from flat GEMINI.md to indexed storage.
|
|
8
|
+
*/
|
|
9
|
+
export class MemoryManager {
|
|
10
|
+
knowledgeStore;
|
|
11
|
+
config;
|
|
12
|
+
constructor(config) {
|
|
13
|
+
this.config = config;
|
|
14
|
+
this.knowledgeStore = new KnowledgeStore(config);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Initial sync of the "Brain" into the knowledge store.
|
|
18
|
+
* This includes GEMINI.md, skills, and session transcripts.
|
|
19
|
+
*/
|
|
20
|
+
async fullSync() {
|
|
21
|
+
try {
|
|
22
|
+
logger.info('🔄 Starting full memory sync...');
|
|
23
|
+
logger.debug(`📁 HomeDir: ${this.config.homeDir}`);
|
|
24
|
+
// 1. Sync GEMINI.md
|
|
25
|
+
const geminiPath = path.join(this.config.homeDir, '.gemini', 'GEMINI.md');
|
|
26
|
+
if (fs.existsSync(geminiPath)) {
|
|
27
|
+
const content = fs.readFileSync(geminiPath, 'utf-8');
|
|
28
|
+
await this.knowledgeStore.indexFile('GEMINI.md', content);
|
|
29
|
+
}
|
|
30
|
+
// 2. Sync Skills
|
|
31
|
+
const skillsDir = path.join(this.config.homeDir, '.gemini', 'skills');
|
|
32
|
+
if (fs.existsSync(skillsDir)) {
|
|
33
|
+
await this.syncDir(skillsDir, 'skills');
|
|
34
|
+
}
|
|
35
|
+
// 3. Sync Sessions (Episodic Memory)
|
|
36
|
+
await this.syncSessions();
|
|
37
|
+
logger.info('✅ Memory sync complete.');
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
logger.error(`❌ Memory sync failed: ${error.message}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Finds and indexes past session conversations for episodic memory.
|
|
45
|
+
*/
|
|
46
|
+
async syncSessions() {
|
|
47
|
+
const tmpDir = path.join(this.config.homeDir, '.gemini', 'tmp');
|
|
48
|
+
if (!fs.existsSync(tmpDir))
|
|
49
|
+
return;
|
|
50
|
+
const projectDirs = fs.readdirSync(tmpDir);
|
|
51
|
+
for (const dir of projectDirs) {
|
|
52
|
+
const chatsDir = path.join(tmpDir, dir, 'chats');
|
|
53
|
+
if (!fs.existsSync(chatsDir))
|
|
54
|
+
continue;
|
|
55
|
+
const files = fs.readdirSync(chatsDir).filter((f) => f.endsWith('.json'));
|
|
56
|
+
for (const file of files) {
|
|
57
|
+
try {
|
|
58
|
+
const fullPath = path.join(chatsDir, file);
|
|
59
|
+
const raw = fs.readFileSync(fullPath, 'utf-8');
|
|
60
|
+
const session = JSON.parse(raw);
|
|
61
|
+
if (session.messages && session.messages.length > 0) {
|
|
62
|
+
const transcript = session.messages
|
|
63
|
+
.map((m) => {
|
|
64
|
+
const role = m.type === 'user' ? 'USER' : 'ASSISTANT';
|
|
65
|
+
const text = Array.isArray(m.content)
|
|
66
|
+
? m.content.map((c) => c.text).join(' ')
|
|
67
|
+
: m.content || '[Action]';
|
|
68
|
+
return `${role}: ${text}`;
|
|
69
|
+
})
|
|
70
|
+
.join('\n\n');
|
|
71
|
+
await this.knowledgeStore.indexFile(`history/${file}`, transcript);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
// Skip invalid session files
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
async syncDir(dir, category) {
|
|
81
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
82
|
+
for (const entry of entries) {
|
|
83
|
+
const fullPath = path.join(dir, entry.name);
|
|
84
|
+
if (entry.isDirectory()) {
|
|
85
|
+
await this.syncDir(fullPath, category);
|
|
86
|
+
}
|
|
87
|
+
else if (entry.name.endsWith('.md')) {
|
|
88
|
+
const content = fs.readFileSync(fullPath, 'utf-8');
|
|
89
|
+
const relPath = path.relative(path.join(this.config.homeDir, '.gemini'), fullPath);
|
|
90
|
+
await this.knowledgeStore.indexFile(relPath, content);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Search memory for relevant snippets.
|
|
96
|
+
*/
|
|
97
|
+
async search(query, limit = 5) {
|
|
98
|
+
return this.knowledgeStore.search(query, limit);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=memory-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-manager.js","sourceRoot":"","sources":["../../src/memory/memory-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Config } from '../config/config.js';
|
|
2
|
+
import { GeminiCli } from '../supervisor/gemini-cli.js';
|
|
3
|
+
import { execSync } from 'child_process';
|
|
4
|
+
async function main() {
|
|
5
|
+
console.log('🔍 Starting Debug CLI...');
|
|
6
|
+
console.log(`PATH: ${process.env.PATH}`);
|
|
7
|
+
try {
|
|
8
|
+
const geminiPath = execSync('which gemini').toString().trim();
|
|
9
|
+
console.log(`✅ Found gemini at: ${geminiPath}`);
|
|
10
|
+
}
|
|
11
|
+
catch (e) {
|
|
12
|
+
console.warn('⚠️ Could not find gemini in PATH');
|
|
13
|
+
}
|
|
14
|
+
const config = Config.getInstance();
|
|
15
|
+
console.log(`🏠 Home Dir: ${config.homeDir}`);
|
|
16
|
+
const cli = new GeminiCli(config);
|
|
17
|
+
console.log('🚀 Running prompt: "write a haiku"');
|
|
18
|
+
let capturedSessionId;
|
|
19
|
+
try {
|
|
20
|
+
await cli.run('write a haiku', (event) => {
|
|
21
|
+
console.log('--------------------------------------------------');
|
|
22
|
+
console.log(`📨 Event Type: ${event.type}`);
|
|
23
|
+
console.log(`📝 Raw Event: ${JSON.stringify(event, null, 2)}`);
|
|
24
|
+
if (event.sessionId) {
|
|
25
|
+
console.log(`✅ Session ID found in event: ${event.sessionId}`);
|
|
26
|
+
if (!capturedSessionId)
|
|
27
|
+
capturedSessionId = event.sessionId;
|
|
28
|
+
}
|
|
29
|
+
if (event.type === 'init') {
|
|
30
|
+
if (event.session_id) {
|
|
31
|
+
console.log(`✅ Session ID found in init (snake_case): ${event.session_id}`);
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
console.warn('⚠️ No session_id in init event!');
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
console.log('--------------------------------------------------');
|
|
39
|
+
console.log('✅ Run complete.');
|
|
40
|
+
if (capturedSessionId) {
|
|
41
|
+
console.log(`🎉 Final Session ID captured: ${capturedSessionId}`);
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
console.error('❌ NO SESSION ID CAPTURED during run.');
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
console.error('❌ Error during run:', error);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
main().catch(console.error);
|
|
52
|
+
//# sourceMappingURL=debug-cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debug-cli.js","sourceRoot":"","sources":["../../src/scripts/debug-cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAGxD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,KAAK,UAAU,IAAI;IACf,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;IACxC,OAAO,CAAC,GAAG,CAAC,SAAS,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;IAEzC,IAAI,CAAC;QACD,MAAM,UAAU,GAAG,QAAQ,CAAC,cAAc,CAAC,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;QAC9D,OAAO,CAAC,GAAG,CAAC,sBAAsB,UAAU,EAAE,CAAC,CAAC;IACpD,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACT,OAAO,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC;IACrD,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;IACpC,OAAO,CAAC,GAAG,CAAC,gBAAgB,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IAE9C,MAAM,GAAG,GAAG,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC;IAElC,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;IAElD,IAAI,iBAAqC,CAAC;IAE1C,IAAI,CAAC;QACD,MAAM,GAAG,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC,KAAK,EAAE,EAAE;YACrC,OAAO,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAC;YAClE,OAAO,CAAC,GAAG,CAAC,kBAAkB,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;YAC5C,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;YAE/D,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;gBAClB,OAAO,CAAC,GAAG,CAAC,gCAAgC,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC;gBAC/D,IAAI,CAAC,iBAAiB;oBAAE,iBAAiB,GAAG,KAAK,CAAC,SAAS,CAAC;YAChE,CAAC;YAED,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBACxB,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;oBACnB,OAAO,CAAC,GAAG,CAAC,4CAA4C,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC;gBAChF,CAAC;qBAAM,CAAC;oBACJ,OAAO,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;gBACpD,CAAC;YACL,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,OAAO,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAC;QAClE,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;QAC/B,IAAI,iBAAiB,EAAE,CAAC;YACpB,OAAO,CAAC,GAAG,CAAC,iCAAiC,iBAAiB,EAAE,CAAC,CAAC;QACtE,CAAC;aAAM,CAAC;YACJ,OAAO,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC;QAC1D,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,qBAAqB,EAAE,KAAK,CAAC,CAAC;IAChD,CAAC;AACL,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import EventEmitter from 'node:events';
|
|
2
|
+
import { Config } from '../config/config.js';
|
|
3
|
+
/**
|
|
4
|
+
* Wrapper for the Gemini CLI process
|
|
5
|
+
*/
|
|
6
|
+
export declare class GeminiCli extends EventEmitter {
|
|
7
|
+
private config;
|
|
8
|
+
constructor(config: Config);
|
|
9
|
+
/**
|
|
10
|
+
* Executes a prompt via Gemini CLI with streaming events.
|
|
11
|
+
*/
|
|
12
|
+
run(prompt: string, onEvent: (event: any) => void, sessionId?: string, extensions?: string[]): Promise<void>;
|
|
13
|
+
/**
|
|
14
|
+
* Synchronous execution (collects all output)
|
|
15
|
+
*/
|
|
16
|
+
runSync(prompt: string, sessionId?: string, extensions?: string[]): Promise<string>;
|
|
17
|
+
/**
|
|
18
|
+
* Removes the last interaction (user prompt + assistant response) from the history.
|
|
19
|
+
* Used for "Silent Heartbeats" to prevent context bloat.
|
|
20
|
+
*/
|
|
21
|
+
pruneLastTurn(sessionId: string): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Compacts the session by removing non-essential metadata (like resultDisplay)
|
|
24
|
+
* to prevent hitting token/quota limits.
|
|
25
|
+
*/
|
|
26
|
+
compactSession(sessionId: string): Promise<void>;
|
|
27
|
+
private getSessionFilePath;
|
|
28
|
+
}
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import EventEmitter from 'node:events';
|
|
3
|
+
import logger from '../utils/logger.js';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import fs from 'fs';
|
|
6
|
+
import crypto from 'crypto';
|
|
7
|
+
/**
|
|
8
|
+
* Wrapper for the Gemini CLI process
|
|
9
|
+
*/
|
|
10
|
+
export class GeminiCli extends EventEmitter {
|
|
11
|
+
config;
|
|
12
|
+
constructor(config) {
|
|
13
|
+
super();
|
|
14
|
+
this.config = config;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Executes a prompt via Gemini CLI with streaming events.
|
|
18
|
+
*/
|
|
19
|
+
run(prompt, onEvent, sessionId, extensions = []) {
|
|
20
|
+
return new Promise((resolve, reject) => {
|
|
21
|
+
const args = ['--output-format', 'stream-json', '--yolo', '--prompt', prompt];
|
|
22
|
+
if (sessionId) {
|
|
23
|
+
args.push('--resume', sessionId);
|
|
24
|
+
}
|
|
25
|
+
// Add extensions (MCP servers) if any
|
|
26
|
+
for (const ext of extensions) {
|
|
27
|
+
args.push('--extensions', ext);
|
|
28
|
+
}
|
|
29
|
+
const childDescription = `Gemini CLI (Session: ${sessionId || 'new'})`;
|
|
30
|
+
// Re-homing environment for subprocess
|
|
31
|
+
const env = {
|
|
32
|
+
...process.env,
|
|
33
|
+
HOME: this.config.homeDir,
|
|
34
|
+
GEMINI_CLI_HOME: this.config.homeDir,
|
|
35
|
+
GEMINI_SYSTEM_MD: this.config.systemPromptPath,
|
|
36
|
+
PWD: process.cwd()
|
|
37
|
+
};
|
|
38
|
+
logger.info(`🚀 [GeminiCli] Spawning: gemini ${args.join(' ')}`);
|
|
39
|
+
const child = spawn('gemini', args, {
|
|
40
|
+
env,
|
|
41
|
+
cwd: process.cwd(),
|
|
42
|
+
stdio: ['ignore', 'pipe', 'pipe']
|
|
43
|
+
});
|
|
44
|
+
const debugFile = `/tmp/gemini-debug-${Date.now()}.log`;
|
|
45
|
+
const debugStream = fs.createWriteStream(debugFile);
|
|
46
|
+
let stdoutBuffer = '';
|
|
47
|
+
let usageStats = { inputTokens: 0, outputTokens: 0, cachedTokens: 0 };
|
|
48
|
+
let hasResolved = false;
|
|
49
|
+
// --- Timeout Logic ---
|
|
50
|
+
// 1. Total Safety Timeout (5m) - Absolute max for any task
|
|
51
|
+
// 2. Idleness Timeout (120s) - Reset every time we get data
|
|
52
|
+
let idleTimeout;
|
|
53
|
+
const TOTAL_TIMEOUT = 300000;
|
|
54
|
+
const IDLE_TIMEOUT = 120000;
|
|
55
|
+
const resetIdleTimeout = () => {
|
|
56
|
+
clearTimeout(idleTimeout);
|
|
57
|
+
idleTimeout = setTimeout(() => {
|
|
58
|
+
if (hasResolved)
|
|
59
|
+
return;
|
|
60
|
+
logger.warn(`🕒 ${childDescription} idle for ${IDLE_TIMEOUT / 1000}s. Killing...`);
|
|
61
|
+
cleanup(null, new Error('Idle timeout'));
|
|
62
|
+
child.kill('SIGKILL');
|
|
63
|
+
}, IDLE_TIMEOUT);
|
|
64
|
+
};
|
|
65
|
+
const totalTimeout = setTimeout(() => {
|
|
66
|
+
if (hasResolved)
|
|
67
|
+
return;
|
|
68
|
+
logger.warn(`🕒 ${childDescription} reached absolute limit (${TOTAL_TIMEOUT / 1000}s). Killing...`);
|
|
69
|
+
cleanup(null, new Error('Absolute timeout'));
|
|
70
|
+
child.kill('SIGKILL');
|
|
71
|
+
}, TOTAL_TIMEOUT);
|
|
72
|
+
resetIdleTimeout();
|
|
73
|
+
// ---------------------
|
|
74
|
+
const cleanup = (code, error) => {
|
|
75
|
+
if (hasResolved)
|
|
76
|
+
return;
|
|
77
|
+
hasResolved = true;
|
|
78
|
+
clearTimeout(totalTimeout);
|
|
79
|
+
clearTimeout(idleTimeout);
|
|
80
|
+
debugStream.end();
|
|
81
|
+
if (error) {
|
|
82
|
+
reject(error);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
logger.info(`⏹️ ${childDescription} closed with code ${code}`);
|
|
86
|
+
if (code === 0 || code === null) {
|
|
87
|
+
onEvent({ type: 'done', usageStats });
|
|
88
|
+
resolve();
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
reject(new Error(`${childDescription} exited with code ${code}`));
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
child.stdout.on('data', (data) => {
|
|
95
|
+
resetIdleTimeout(); // Reset timer on any output
|
|
96
|
+
const chunk = data.toString();
|
|
97
|
+
debugStream.write(chunk);
|
|
98
|
+
stdoutBuffer += chunk;
|
|
99
|
+
const lines = stdoutBuffer.split('\n');
|
|
100
|
+
stdoutBuffer = lines.pop() || '';
|
|
101
|
+
for (const line of lines) {
|
|
102
|
+
if (!line.trim())
|
|
103
|
+
continue;
|
|
104
|
+
try {
|
|
105
|
+
const event = JSON.parse(line);
|
|
106
|
+
// --- Normalize Event ---
|
|
107
|
+
// 1. Tool Calls
|
|
108
|
+
if (event.type === 'tool_use') {
|
|
109
|
+
event.type = 'tool_call';
|
|
110
|
+
event.toolName = event.tool_name;
|
|
111
|
+
event.toolArgs = event.parameters;
|
|
112
|
+
}
|
|
113
|
+
// 2. Tool Responses
|
|
114
|
+
if (event.type === 'tool_result') {
|
|
115
|
+
event.type = 'tool_response';
|
|
116
|
+
event.toolId = event.tool_id;
|
|
117
|
+
event.content = event.output;
|
|
118
|
+
}
|
|
119
|
+
// 3. Thoughts
|
|
120
|
+
if (event.thoughts && !event.content) {
|
|
121
|
+
onEvent({
|
|
122
|
+
type: 'thought',
|
|
123
|
+
content: Array.isArray(event.thoughts)
|
|
124
|
+
? event.thoughts.join('\n')
|
|
125
|
+
: event.thoughts
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
if (event.type === 'message' && event.thoughts) {
|
|
129
|
+
// If message has thoughts, emit them separately or as a combined event
|
|
130
|
+
onEvent({
|
|
131
|
+
type: 'thought',
|
|
132
|
+
content: Array.isArray(event.thoughts)
|
|
133
|
+
? event.thoughts.join('\n')
|
|
134
|
+
: event.thoughts
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
// 4. Session & Stats
|
|
138
|
+
if (event.stats) {
|
|
139
|
+
usageStats = {
|
|
140
|
+
inputTokens: event.stats.input_tokens || event.stats.input || 0,
|
|
141
|
+
outputTokens: event.stats.output_tokens || event.stats.output || 0,
|
|
142
|
+
cachedTokens: event.stats.cached || 0
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
if (event.session_id && !event.sessionId) {
|
|
146
|
+
event.sessionId = event.session_id;
|
|
147
|
+
}
|
|
148
|
+
onEvent(event);
|
|
149
|
+
// If we see a 'done' event, the CLI is effectively finished
|
|
150
|
+
if (event.type === 'done' ||
|
|
151
|
+
(event.type === 'result' && event.status === 'success')) {
|
|
152
|
+
cleanup(0);
|
|
153
|
+
child.kill('SIGTERM');
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
catch (e) {
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
child.stderr.on('data', (data) => {
|
|
162
|
+
const error = data.toString();
|
|
163
|
+
logger.warn(`[Gemini CLI Stderr] ${error.trim()}`);
|
|
164
|
+
});
|
|
165
|
+
child.on('close', (code) => {
|
|
166
|
+
cleanup(code);
|
|
167
|
+
});
|
|
168
|
+
child.on('error', (err) => {
|
|
169
|
+
logger.error(`Failed to start ${childDescription}: ${err.message}`);
|
|
170
|
+
reject(err);
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Synchronous execution (collects all output)
|
|
176
|
+
*/
|
|
177
|
+
async runSync(prompt, sessionId, extensions = []) {
|
|
178
|
+
let fullContent = '';
|
|
179
|
+
await this.run(prompt, (event) => {
|
|
180
|
+
if ((event.type === 'message' || event.type === 'text') &&
|
|
181
|
+
event.role === 'assistant' &&
|
|
182
|
+
event.content) {
|
|
183
|
+
fullContent += event.content;
|
|
184
|
+
}
|
|
185
|
+
}, sessionId, extensions);
|
|
186
|
+
// Always try to compact after interaction
|
|
187
|
+
if (sessionId) {
|
|
188
|
+
await this.compactSession(sessionId);
|
|
189
|
+
}
|
|
190
|
+
return fullContent;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Removes the last interaction (user prompt + assistant response) from the history.
|
|
194
|
+
* Used for "Silent Heartbeats" to prevent context bloat.
|
|
195
|
+
*/
|
|
196
|
+
async pruneLastTurn(sessionId) {
|
|
197
|
+
try {
|
|
198
|
+
const filePath = this.getSessionFilePath(sessionId);
|
|
199
|
+
if (!filePath)
|
|
200
|
+
return;
|
|
201
|
+
const raw = fs.readFileSync(filePath, 'utf-8');
|
|
202
|
+
const session = JSON.parse(raw);
|
|
203
|
+
if (session.messages && session.messages.length > 0) {
|
|
204
|
+
let lastUserIndex = -1;
|
|
205
|
+
for (let i = session.messages.length - 1; i >= 0; i--) {
|
|
206
|
+
if (session.messages[i].type === 'user') {
|
|
207
|
+
lastUserIndex = i;
|
|
208
|
+
break;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
if (lastUserIndex !== -1) {
|
|
212
|
+
session.messages = session.messages.slice(0, lastUserIndex);
|
|
213
|
+
fs.writeFileSync(filePath, JSON.stringify(session, null, 2));
|
|
214
|
+
logger.debug(`✂️ Pruned session history at index ${lastUserIndex}`);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
else if (session.history && session.history.length > 0) {
|
|
218
|
+
// Compatibility for alternate formats
|
|
219
|
+
let lastUserIndex = -1;
|
|
220
|
+
for (let i = session.history.length - 1; i >= 0; i--) {
|
|
221
|
+
if (session.history[i].role === 'user') {
|
|
222
|
+
lastUserIndex = i;
|
|
223
|
+
break;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
if (lastUserIndex !== -1) {
|
|
227
|
+
session.history = session.history.slice(0, lastUserIndex);
|
|
228
|
+
fs.writeFileSync(filePath, JSON.stringify(session, null, 2));
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
catch (error) {
|
|
233
|
+
logger.error(`❌ Pruning failed: ${error.message}`);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Compacts the session by removing non-essential metadata (like resultDisplay)
|
|
238
|
+
* to prevent hitting token/quota limits.
|
|
239
|
+
*/
|
|
240
|
+
async compactSession(sessionId) {
|
|
241
|
+
try {
|
|
242
|
+
const filePath = this.getSessionFilePath(sessionId);
|
|
243
|
+
if (!filePath)
|
|
244
|
+
return;
|
|
245
|
+
const stats = fs.statSync(filePath);
|
|
246
|
+
if (stats.size < 50 * 1024)
|
|
247
|
+
return; // Only compact if > 50KB
|
|
248
|
+
logger.info(`🧹 Compacting bloated session (${(stats.size / 1024).toFixed(1)} KB)...`);
|
|
249
|
+
const raw = fs.readFileSync(filePath, 'utf-8');
|
|
250
|
+
const session = JSON.parse(raw);
|
|
251
|
+
const cleanMessages = (msgs) => {
|
|
252
|
+
if (!msgs)
|
|
253
|
+
return msgs;
|
|
254
|
+
return msgs.map((m) => {
|
|
255
|
+
if (m.resultDisplay)
|
|
256
|
+
delete m.resultDisplay;
|
|
257
|
+
if (m.thoughts && m.thoughts.length > 3)
|
|
258
|
+
m.thoughts = m.thoughts.slice(-3);
|
|
259
|
+
if (m.content && Array.isArray(m.content)) {
|
|
260
|
+
m.content = m.content.map((item) => {
|
|
261
|
+
if (item.result) {
|
|
262
|
+
item.result = item.result.map((r) => {
|
|
263
|
+
if (r.functionResponse?.response?.resultDisplay) {
|
|
264
|
+
delete r.functionResponse.response.resultDisplay;
|
|
265
|
+
}
|
|
266
|
+
return r;
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
return item;
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
return m;
|
|
273
|
+
});
|
|
274
|
+
};
|
|
275
|
+
if (session.messages)
|
|
276
|
+
session.messages = cleanMessages(session.messages);
|
|
277
|
+
if (session.history)
|
|
278
|
+
session.history = cleanMessages(session.history);
|
|
279
|
+
fs.writeFileSync(filePath, JSON.stringify(session, null, 2));
|
|
280
|
+
const newStats = fs.statSync(filePath);
|
|
281
|
+
logger.info(`✨ Compacted: ${(stats.size / 1024).toFixed(1)} KB -> ${(newStats.size / 1024).toFixed(1)} KB`);
|
|
282
|
+
}
|
|
283
|
+
catch (error) {
|
|
284
|
+
logger.error(`❌ Compaction failed: ${error.message}`);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
getSessionFilePath(sessionId) {
|
|
288
|
+
try {
|
|
289
|
+
// The Gemini CLI calculates the project hash based on the current working directory (repo root)
|
|
290
|
+
// when it detects a git repo or project context.
|
|
291
|
+
const projectDir = process.cwd();
|
|
292
|
+
const projectHash = crypto.createHash('sha256').update(projectDir).digest('hex');
|
|
293
|
+
const chatsDir = path.join(this.config.homeDir, '.gemini', 'tmp', projectHash, 'chats');
|
|
294
|
+
if (!fs.existsSync(chatsDir)) {
|
|
295
|
+
logger.debug(`[GeminiCli] Chats directory not found: ${chatsDir}`);
|
|
296
|
+
return null;
|
|
297
|
+
}
|
|
298
|
+
const files = fs
|
|
299
|
+
.readdirSync(chatsDir)
|
|
300
|
+
.filter((f) => f.startsWith('session-') &&
|
|
301
|
+
f.includes(sessionId.substring(0, 8)) &&
|
|
302
|
+
f.endsWith('.json'))
|
|
303
|
+
.map((f) => ({
|
|
304
|
+
name: f,
|
|
305
|
+
time: fs.statSync(path.join(chatsDir, f)).mtime.getTime()
|
|
306
|
+
}))
|
|
307
|
+
.sort((a, b) => b.time - a.time);
|
|
308
|
+
return files.length > 0 ? path.join(chatsDir, files[0].name) : null;
|
|
309
|
+
}
|
|
310
|
+
catch {
|
|
311
|
+
return null;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
//# sourceMappingURL=gemini-cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemini-cli.js","sourceRoot":"","sources":["../../src/supervisor/gemini-cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Supervisor } from './supervisor.js';
|
|
2
|
+
import { Config } from '../config/config.js';
|
|
3
|
+
/**
|
|
4
|
+
* HeartbeatService - Manages background task execution via file polling
|
|
5
|
+
*/
|
|
6
|
+
export declare class HeartbeatService {
|
|
7
|
+
private readonly supervisor;
|
|
8
|
+
private readonly config;
|
|
9
|
+
private interval;
|
|
10
|
+
private isExecuting;
|
|
11
|
+
private processor;
|
|
12
|
+
constructor(supervisor: Supervisor, config: Config);
|
|
13
|
+
start(): Promise<void>;
|
|
14
|
+
stop(): void;
|
|
15
|
+
private tick;
|
|
16
|
+
private autonomousCheck;
|
|
17
|
+
private runTask;
|
|
18
|
+
private calculateNextRun;
|
|
19
|
+
private loadTasks;
|
|
20
|
+
private saveTasks;
|
|
21
|
+
}
|