agentgui 1.0.93 → 1.0.95
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/.prd +1 -0
- package/database.js +43 -1
- package/lib/claude-runner.js +24 -22
- package/package.json +5 -3
- package/server.js +209 -146
- package/static/index.html +354 -94
- package/static/js/client.js +218 -144
- package/static/js/features.js +243 -0
- package/static/js/websocket-manager.js +1 -1
- package/static/styles.css +46 -4
package/.prd
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
package/database.js
CHANGED
|
@@ -198,7 +198,9 @@ try {
|
|
|
198
198
|
gitBranch: 'TEXT',
|
|
199
199
|
sourcePath: 'TEXT',
|
|
200
200
|
lastSyncedAt: 'INTEGER',
|
|
201
|
-
workingDirectory: 'TEXT'
|
|
201
|
+
workingDirectory: 'TEXT',
|
|
202
|
+
claudeSessionId: 'TEXT',
|
|
203
|
+
isStreaming: 'INTEGER DEFAULT 0'
|
|
202
204
|
};
|
|
203
205
|
|
|
204
206
|
let addedColumns = false;
|
|
@@ -286,6 +288,46 @@ export const queries = {
|
|
|
286
288
|
};
|
|
287
289
|
},
|
|
288
290
|
|
|
291
|
+
setClaudeSessionId(conversationId, claudeSessionId) {
|
|
292
|
+
const stmt = db.prepare('UPDATE conversations SET claudeSessionId = ?, updated_at = ? WHERE id = ?');
|
|
293
|
+
stmt.run(claudeSessionId, Date.now(), conversationId);
|
|
294
|
+
},
|
|
295
|
+
|
|
296
|
+
getClaudeSessionId(conversationId) {
|
|
297
|
+
const stmt = db.prepare('SELECT claudeSessionId FROM conversations WHERE id = ?');
|
|
298
|
+
const row = stmt.get(conversationId);
|
|
299
|
+
return row?.claudeSessionId || null;
|
|
300
|
+
},
|
|
301
|
+
|
|
302
|
+
setIsStreaming(conversationId, isStreaming) {
|
|
303
|
+
const stmt = db.prepare('UPDATE conversations SET isStreaming = ?, updated_at = ? WHERE id = ?');
|
|
304
|
+
stmt.run(isStreaming ? 1 : 0, Date.now(), conversationId);
|
|
305
|
+
},
|
|
306
|
+
|
|
307
|
+
getIsStreaming(conversationId) {
|
|
308
|
+
const stmt = db.prepare('SELECT isStreaming FROM conversations WHERE id = ?');
|
|
309
|
+
const row = stmt.get(conversationId);
|
|
310
|
+
return row?.isStreaming === 1;
|
|
311
|
+
},
|
|
312
|
+
|
|
313
|
+
markSessionIncomplete(sessionId, errorMsg) {
|
|
314
|
+
const stmt = db.prepare('UPDATE sessions SET status = ?, error = ?, completed_at = ? WHERE id = ?');
|
|
315
|
+
stmt.run('incomplete', errorMsg || 'unknown', Date.now(), sessionId);
|
|
316
|
+
},
|
|
317
|
+
|
|
318
|
+
getSessionsProcessingLongerThan(minutes) {
|
|
319
|
+
const cutoff = Date.now() - (minutes * 60 * 1000);
|
|
320
|
+
const stmt = db.prepare('SELECT * FROM sessions WHERE status = ? AND started_at < ?');
|
|
321
|
+
return stmt.all('pending', cutoff);
|
|
322
|
+
},
|
|
323
|
+
|
|
324
|
+
cleanupOrphanedSessions(days) {
|
|
325
|
+
const cutoff = Date.now() - (days * 24 * 60 * 60 * 1000);
|
|
326
|
+
const stmt = db.prepare('DELETE FROM sessions WHERE status = ? AND started_at < ?');
|
|
327
|
+
const result = stmt.run('pending', cutoff);
|
|
328
|
+
return result.changes || 0;
|
|
329
|
+
},
|
|
330
|
+
|
|
289
331
|
createMessage(conversationId, role, content, idempotencyKey = null) {
|
|
290
332
|
if (idempotencyKey) {
|
|
291
333
|
const cached = this.getIdempotencyKey(idempotencyKey);
|
package/lib/claude-runner.js
CHANGED
|
@@ -1,23 +1,5 @@
|
|
|
1
1
|
import { spawn } from 'child_process';
|
|
2
2
|
|
|
3
|
-
/**
|
|
4
|
-
* Configuration for Claude runner
|
|
5
|
-
* @typedef {Object} ClaudeRunnerConfig
|
|
6
|
-
* @property {boolean} [skipPermissions=false] - Use --dangerously-skip-permissions flag
|
|
7
|
-
* @property {boolean} [verbose=true] - Use --verbose flag
|
|
8
|
-
* @property {string} [outputFormat='stream-json'] - Output format (stream-json, json, text)
|
|
9
|
-
* @property {number} [timeout=300000] - Timeout in milliseconds (default 5 minutes)
|
|
10
|
-
* @property {boolean} [print=true] - Use --print flag
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Run Claude with streaming JSON output
|
|
15
|
-
* @param {string} prompt - The prompt to send to Claude
|
|
16
|
-
* @param {string} cwd - Working directory
|
|
17
|
-
* @param {string} agentId - Agent identifier (for logging)
|
|
18
|
-
* @param {ClaudeRunnerConfig} [config={}] - Configuration options
|
|
19
|
-
* @returns {Promise<Array>} Array of parsed JSON objects from Claude output
|
|
20
|
-
*/
|
|
21
3
|
export async function runClaudeWithStreaming(prompt, cwd, agentId = 'claude-code', config = {}) {
|
|
22
4
|
return new Promise((resolve, reject) => {
|
|
23
5
|
const {
|
|
@@ -25,20 +7,25 @@ export async function runClaudeWithStreaming(prompt, cwd, agentId = 'claude-code
|
|
|
25
7
|
verbose = true,
|
|
26
8
|
outputFormat = 'stream-json',
|
|
27
9
|
timeout = 300000,
|
|
28
|
-
print = true
|
|
10
|
+
print = true,
|
|
11
|
+
resumeSessionId = null,
|
|
12
|
+
systemPrompt = null,
|
|
13
|
+
onEvent = null
|
|
29
14
|
} = config;
|
|
30
15
|
|
|
31
|
-
// Build flags array
|
|
32
16
|
const flags = [];
|
|
33
17
|
if (print) flags.push('--print');
|
|
34
18
|
if (verbose) flags.push('--verbose');
|
|
35
19
|
flags.push(`--output-format=${outputFormat}`);
|
|
36
20
|
if (skipPermissions) flags.push('--dangerously-skip-permissions');
|
|
21
|
+
if (resumeSessionId) flags.push('--resume', resumeSessionId);
|
|
22
|
+
if (systemPrompt) flags.push('--append-system-prompt', systemPrompt);
|
|
37
23
|
|
|
38
24
|
const proc = spawn('claude', flags, { cwd });
|
|
39
25
|
let jsonBuffer = '';
|
|
40
26
|
const outputs = [];
|
|
41
27
|
let timedOut = false;
|
|
28
|
+
let sessionId = null;
|
|
42
29
|
|
|
43
30
|
const timeoutHandle = setTimeout(() => {
|
|
44
31
|
timedOut = true;
|
|
@@ -61,6 +48,16 @@ export async function runClaudeWithStreaming(prompt, cwd, agentId = 'claude-code
|
|
|
61
48
|
try {
|
|
62
49
|
const parsed = JSON.parse(line);
|
|
63
50
|
outputs.push(parsed);
|
|
51
|
+
|
|
52
|
+
if (parsed.session_id) {
|
|
53
|
+
sessionId = parsed.session_id;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (onEvent) {
|
|
57
|
+
try { onEvent(parsed); } catch (e) {
|
|
58
|
+
console.error(`[claude-runner] onEvent error: ${e.message}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
64
61
|
} catch (e) {
|
|
65
62
|
console.error(`[claude-runner] JSON parse error on line: ${line.substring(0, 100)}`);
|
|
66
63
|
}
|
|
@@ -79,12 +76,17 @@ export async function runClaudeWithStreaming(prompt, cwd, agentId = 'claude-code
|
|
|
79
76
|
if (code === 0) {
|
|
80
77
|
if (jsonBuffer.trim()) {
|
|
81
78
|
try {
|
|
82
|
-
|
|
79
|
+
const parsed = JSON.parse(jsonBuffer);
|
|
80
|
+
outputs.push(parsed);
|
|
81
|
+
if (parsed.session_id) sessionId = parsed.session_id;
|
|
82
|
+
if (onEvent) {
|
|
83
|
+
try { onEvent(parsed); } catch (e) {}
|
|
84
|
+
}
|
|
83
85
|
} catch (e) {
|
|
84
86
|
console.error(`[claude-runner] Final JSON parse error: ${jsonBuffer.substring(0, 100)}`);
|
|
85
87
|
}
|
|
86
88
|
}
|
|
87
|
-
resolve(outputs);
|
|
89
|
+
resolve({ outputs, sessionId });
|
|
88
90
|
} else {
|
|
89
91
|
reject(new Error(`Claude CLI exited with code ${code} for agent ${agentId}`));
|
|
90
92
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentgui",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.95",
|
|
4
4
|
"description": "Multi-agent ACP client with real-time communication",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "server.js",
|
|
@@ -23,7 +23,9 @@
|
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"@anthropic-ai/claude-code": "^1.0.128",
|
|
25
25
|
"better-sqlite3": "^12.6.2",
|
|
26
|
+
"busboy": "^1.6.0",
|
|
27
|
+
"express": "^5.2.1",
|
|
28
|
+
"fsbrowse": "file:../fsbrowse",
|
|
26
29
|
"ws": "^8.14.2"
|
|
27
|
-
}
|
|
28
|
-
"devDependencies": {}
|
|
30
|
+
}
|
|
29
31
|
}
|