agentgui 1.0.931 → 1.0.932
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/AGENTS.md +17 -12
- package/database.js +31 -2
- package/lib/http-handler.js +11 -25
- package/lib/routes-registry.js +4 -48
- package/lib/server-startup.js +3 -11
- package/lib/ws-setup.js +2 -1
- package/package.json +3 -3
- package/server.js +7 -1
- package/site/app/js/app.js +64 -68
- package/site/app/js/backend.js +1 -1
- package/static/lib/xstate.umd.min.js +1 -1
- package/lib/db-queries-chunks.js +0 -195
- package/lib/db-queries-chunks2.js +0 -82
- package/lib/db-queries-cleanup.js +0 -74
- package/lib/db-queries-del.js +0 -141
- package/lib/db-queries-events.js +0 -68
- package/lib/db-queries-import.js +0 -133
- package/lib/db-queries-messages.js +0 -102
- package/lib/db-queries-sessions.js +0 -112
- package/lib/db-queries-streams.js +0 -100
- package/lib/db-queries.js +0 -89
- package/lib/jsonl-parser.js +0 -190
- package/lib/jsonl-watcher.js +0 -64
- package/lib/routes-agent-actions.js +0 -61
- package/lib/routes-auth-config.js +0 -30
- package/lib/routes-conversations.js +0 -96
- package/lib/routes-debug.js +0 -119
- package/lib/routes-messages.js +0 -139
- package/lib/routes-runs.js +0 -156
- package/lib/routes-scripts.js +0 -135
- package/lib/routes-sessions.js +0 -144
- package/lib/routes-threads.js +0 -100
- package/lib/routes-util.js +0 -110
- package/lib/ws-handlers-conv.js +0 -138
- package/lib/ws-handlers-conv2.js +0 -169
- package/lib/ws-handlers-msg.js +0 -121
- package/lib/ws-handlers-queue.js +0 -56
- package/lib/ws-handlers-run.js +0 -182
- package/lib/ws-handlers-scripts.js +0 -66
- package/lib/ws-handlers-session.js +0 -105
- package/lib/ws-handlers-session2.js +0 -85
- package/lib/ws-legacy-handlers.js +0 -51
- package/static/app.js +0 -261
- package/static/css/app-shell.css +0 -419
- package/static/css/brand-bible.css +0 -591
- package/static/css/colors_and_type.css +0 -568
- package/static/css/gmail-skin.css +0 -663
- package/static/css/main.css +0 -4015
- package/static/css/tools-popup.css +0 -472
- package/static/index.html +0 -418
- package/static/js/agent-auth.js +0 -146
- package/static/js/app-shortcuts.js +0 -30
- package/static/js/audio-recorder-processor.js +0 -18
- package/static/js/client-agents.js +0 -155
- package/static/js/client-cache.js +0 -171
- package/static/js/client-conv.js +0 -198
- package/static/js/client-events.js +0 -164
- package/static/js/client-exec.js +0 -160
- package/static/js/client-helpers.js +0 -199
- package/static/js/client-load.js +0 -175
- package/static/js/client-render.js +0 -132
- package/static/js/client-scroll.js +0 -178
- package/static/js/client-status.js +0 -167
- package/static/js/client-streaming.js +0 -117
- package/static/js/client-streaming2.js +0 -116
- package/static/js/client-streaming3.js +0 -153
- package/static/js/client-streaming4.js +0 -194
- package/static/js/client-ui-controls.js +0 -170
- package/static/js/client-ui.js +0 -128
- package/static/js/client-ui2.js +0 -160
- package/static/js/client-url.js +0 -93
- package/static/js/client-utils.js +0 -174
- package/static/js/client-ws-msg.js +0 -88
- package/static/js/client-ws.js +0 -161
- package/static/js/client.js +0 -145
- package/static/js/codec.js +0 -4
- package/static/js/conv-list-machine.js +0 -145
- package/static/js/conv-list-renderer.js +0 -198
- package/static/js/conv-machine.js +0 -110
- package/static/js/conv-sidebar-actions.js +0 -188
- package/static/js/conv-sidebar-clone.js +0 -91
- package/static/js/conversations.js +0 -116
- package/static/js/dialogs-types.js +0 -111
- package/static/js/dialogs.js +0 -53
- package/static/js/event-filter-config.js +0 -36
- package/static/js/event-processor.js +0 -181
- package/static/js/features.js +0 -187
- package/static/js/image-loader-element.js +0 -76
- package/static/js/image-loader.js +0 -146
- package/static/js/prompt-machine.js +0 -108
- package/static/js/recording-machine.js +0 -49
- package/static/js/script-runner.js +0 -192
- package/static/js/state-barrier.js +0 -105
- package/static/js/streaming-renderer-dispatch.js +0 -144
- package/static/js/streaming-renderer-events.js +0 -163
- package/static/js/streaming-renderer-events2.js +0 -125
- package/static/js/streaming-renderer-params.js +0 -38
- package/static/js/streaming-renderer-render-misc.js +0 -107
- package/static/js/streaming-renderer-render.js +0 -181
- package/static/js/streaming-renderer-render2.js +0 -149
- package/static/js/streaming-renderer-render3.js +0 -142
- package/static/js/streaming-renderer-static.js +0 -181
- package/static/js/streaming-renderer-static2.js +0 -140
- package/static/js/streaming-renderer-stream.js +0 -170
- package/static/js/streaming-renderer-text.js +0 -185
- package/static/js/streaming-renderer-tools.js +0 -189
- package/static/js/streaming-renderer-tools2.js +0 -92
- package/static/js/streaming-renderer.js +0 -200
- package/static/js/syntax-highlighter-render.js +0 -72
- package/static/js/syntax-highlighter.js +0 -131
- package/static/js/terminal-machine.js +0 -51
- package/static/js/terminal.js +0 -178
- package/static/js/ui-components-rendering.js +0 -62
- package/static/js/ui-components.js +0 -88
- package/static/js/websocket-manager.js +0 -107
- package/static/js/ws-client.js +0 -87
- package/static/js/ws-core.js +0 -162
- package/static/js/ws-latency.js +0 -88
- package/static/js/ws-machine.js +0 -68
- package/static/lib/msgpackr.min.js +0 -2
- package/static/theme.js +0 -74
- package/static/vendor/highlight-js.css +0 -10
- package/static/vendor/highlight.min.js +0 -1244
- package/static/vendor/prism-dark.css +0 -129
- package/static/vendor/rippleui.css +0 -35
- package/static/vendor/xterm-addon-fit.min.js +0 -8
- package/static/vendor/xterm.css +0 -8
- package/static/vendor/xterm.min.js +0 -8
package/AGENTS.md
CHANGED
|
@@ -1,22 +1,27 @@
|
|
|
1
1
|
# AgentGUI — Agent Notes
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## Architecture (2026-05-19 pivot — single surface)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
One surface. `server.js` serves `site/app/` at `/` and mounts `ccsniff`'s `/v1/history/*` Express router in-process. The legacy `static/` tree and the legacy `lib/routes-*`/`lib/db-queries-*`/`lib/jsonl-watcher.js` modules are gone. `acptoapi` is no longer used by this project.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
- `site/app/index.html` — shell + CSS, imports `anentrypoint-design` from unpkg
|
|
8
|
+
- `site/app/js/backend.js` — same-origin client (`DEFAULT_BACKEND = ''`); `?backend=` query override for cross-origin debugging
|
|
9
|
+
- `site/app/js/app.js` — webjsx view + state, kits-only rendering (PageHeader, SearchInput, TextField, EventList, Panel, Row, Section); exposes `window.__agentgui`
|
|
10
|
+
- `server.js` — boots ACP/agents/websocket plugins, mounts `createHistoryRouter()` from `ccsniff` at `/`, serves `site/app/` as static root
|
|
11
|
+
- Plugins kept (lib/plugins/): acp, agents, database, files, stream, websocket, workflow
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
Dependencies:
|
|
14
|
+
- `ccsniff` (>=1.1.0) — exports `createHistoryRouter({projectsDir})` mountable on Express; serves `/v1/history/{sessions,sessions/:sid/events,search,snapshot,reindex,stream}`. Reads `~/.claude/projects` (override via `CLAUDE_PROJECTS_DIR`).
|
|
15
|
+
- `anentrypoint-design` (>=0.0.119) — kit library, single-file ESM from unpkg
|
|
14
16
|
|
|
15
|
-
|
|
16
|
-
- `acptoapi` provides chat / messages / models endpoints (existing) + new history endpoints (`/v1/history/sessions`, `/v1/history/sessions/:sid/events`, `/v1/history/search`, `/v1/history/stream`) — see `c:\dev\acptoapi\lib\history\` (ccsniff functionality merged in 2026-05-02).
|
|
17
|
-
- `anentrypoint-design` provides AppShell / Chat / FileGrid / etc. — single-file ESM from unpkg, no install.
|
|
17
|
+
## Browser Witness (2026-05-19)
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
Local server on PORT=3056 (default), `bun server.js`:
|
|
20
|
+
- `GET /health` → 200 JSON
|
|
21
|
+
- `GET /v1/history/sessions` → `{"sessions":[]}` from ccsniff
|
|
22
|
+
- `GET /` → site/app/index.html
|
|
23
|
+
- WS `/sync` → opens, sync_connected
|
|
24
|
+
- Browser at `localhost:3056/`: AppShell renders, nav=[chat,history,settings], SSE `hello` received (live.connected=true, eventCount=1), 0 console errors, backend resolves to `''` (same origin).
|
|
20
25
|
|
|
21
26
|
## Learning audit
|
|
22
27
|
|
package/database.js
CHANGED
|
@@ -5,7 +5,36 @@ import { createRequire } from 'module';
|
|
|
5
5
|
import { initSchema } from './database-schema.js';
|
|
6
6
|
import { migrateFromJson, migrateToACP, migrateConversationColumns } from './database-migrations.js';
|
|
7
7
|
import { migrateACPSchema, migrateBackfillMessages, migrateFTS, migrateAutoVacuum } from './database-migrations-acp.js';
|
|
8
|
-
|
|
8
|
+
// db-queries layer removed; queries is now a no-op proxy. History is served by ccsniff.
|
|
9
|
+
function createQueries(db) {
|
|
10
|
+
const noop = () => undefined;
|
|
11
|
+
const target = {
|
|
12
|
+
_db: db,
|
|
13
|
+
cleanup: noop,
|
|
14
|
+
cleanupEmptyConversations: () => 0,
|
|
15
|
+
cleanupOrphanedSessions: () => 0,
|
|
16
|
+
clearAllStreamingFlags: () => 0,
|
|
17
|
+
getStreamingConversations: () => [],
|
|
18
|
+
getResumableConversations: () => [],
|
|
19
|
+
getActiveSessions: () => [],
|
|
20
|
+
getSessionsProcessingLongerThan: () => [],
|
|
21
|
+
getConversationsList: () => [],
|
|
22
|
+
getConversation: () => null,
|
|
23
|
+
getSession: () => null,
|
|
24
|
+
getLatestSession: () => null,
|
|
25
|
+
getAllSessions: () => [],
|
|
26
|
+
getStreamChunks: () => [],
|
|
27
|
+
getExecutionEvents: () => [],
|
|
28
|
+
searchAgents: () => [],
|
|
29
|
+
};
|
|
30
|
+
return new Proxy(target, {
|
|
31
|
+
get(t, k) {
|
|
32
|
+
if (k in t) return t[k];
|
|
33
|
+
if (typeof k === 'symbol') return undefined;
|
|
34
|
+
return () => undefined;
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
}
|
|
9
38
|
|
|
10
39
|
const require = createRequire(import.meta.url);
|
|
11
40
|
|
|
@@ -75,6 +104,6 @@ function generateId(prefix) {
|
|
|
75
104
|
return `${prefix}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
76
105
|
}
|
|
77
106
|
|
|
78
|
-
export const queries = createQueries(db
|
|
107
|
+
export const queries = createQueries(db);
|
|
79
108
|
|
|
80
109
|
export default { queries };
|
package/lib/http-handler.js
CHANGED
|
@@ -33,7 +33,7 @@ export function createHttpHandler({ BASE_URL, expressApp, queries, sendJSON, ser
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
const pathOnly = req.url.split('?')[0];
|
|
36
|
-
if (pathOnly.startsWith(BASE_URL + '/api/upload/') || pathOnly.startsWith(BASE_URL + '/files/')) return expressApp(req, res);
|
|
36
|
+
if (pathOnly.startsWith(BASE_URL + '/api/upload/') || pathOnly.startsWith(BASE_URL + '/files/') || pathOnly.startsWith('/v1/history')) return expressApp(req, res);
|
|
37
37
|
|
|
38
38
|
if (req.url === '/favicon.ico' || req.url === BASE_URL + '/favicon.ico') {
|
|
39
39
|
const svg = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><rect width="100" height="100" rx="20" fill="#3b82f6"/><text x="50" y="68" font-size="50" font-family="sans-serif" font-weight="bold" fill="white" text-anchor="middle">G</text></svg>';
|
|
@@ -41,13 +41,14 @@ export function createHttpHandler({ BASE_URL, expressApp, queries, sendJSON, ser
|
|
|
41
41
|
res.end(svg); return;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
// serve index.html at root directly (no redirect)
|
|
45
45
|
|
|
46
46
|
let routePath = req.url;
|
|
47
47
|
if (req.url.startsWith(BASE_URL + '/')) { routePath = req.url.slice(BASE_URL.length); }
|
|
48
48
|
else if (req.url === BASE_URL) { routePath = '/'; }
|
|
49
49
|
else if (req.url.startsWith('/api/') || req.url.startsWith('/js/') || req.url.startsWith('/css/') ||
|
|
50
50
|
req.url.startsWith('/vendor/') || req.url.startsWith('/sync') || req.url === '/' ||
|
|
51
|
+
req.url === '/health' || req.url.startsWith('/v1/') ||
|
|
51
52
|
req.url.startsWith('/conversations/')) { routePath = req.url; }
|
|
52
53
|
else { res.writeHead(404); res.end('Not found'); return; }
|
|
53
54
|
|
|
@@ -56,7 +57,7 @@ export function createHttpHandler({ BASE_URL, expressApp, queries, sendJSON, ser
|
|
|
56
57
|
try {
|
|
57
58
|
const pathOnly = routePath.split('?')[0];
|
|
58
59
|
|
|
59
|
-
if (pathOnly === '/api/health' && req.method === 'GET') {
|
|
60
|
+
if ((pathOnly === '/api/health' || pathOnly === '/health') && req.method === 'GET') {
|
|
60
61
|
let dbStatus = { ok: true };
|
|
61
62
|
try { queries._db.prepare('SELECT 1').get(); } catch (e) { dbStatus = { ok: false, error: e.message }; }
|
|
62
63
|
const queueSizes = {};
|
|
@@ -65,28 +66,13 @@ export function createHttpHandler({ BASE_URL, expressApp, queries, sendJSON, ser
|
|
|
65
66
|
return;
|
|
66
67
|
}
|
|
67
68
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
if (scriptsHandler) { await scriptsHandler(req, res); return; }
|
|
76
|
-
const runsHandler = routes.runs._match(req.method, pathOnly);
|
|
77
|
-
if (runsHandler) { await runsHandler(req, res); return; }
|
|
78
|
-
const agentHandler = routes.agents._match(req.method, pathOnly);
|
|
79
|
-
if (agentHandler) { await agentHandler(req, res); return; }
|
|
80
|
-
const agentActionsHandler = routes.agentActions._match(req.method, pathOnly);
|
|
81
|
-
if (agentActionsHandler) { await agentActionsHandler(req, res); return; }
|
|
82
|
-
const authConfigHandler = routes.authConfig._match(req.method, pathOnly);
|
|
83
|
-
if (authConfigHandler) { await authConfigHandler(req, res); return; }
|
|
84
|
-
const utilHandler = routes.util._match(req.method, pathOnly);
|
|
85
|
-
if (utilHandler) { await utilHandler(req, res); return; }
|
|
86
|
-
const threadHandler = routes.threads._match(req.method, pathOnly);
|
|
87
|
-
if (threadHandler) { await threadHandler(req, res); return; }
|
|
88
|
-
const debugHandler = routes.debug._match(req.method, pathOnly);
|
|
89
|
-
if (debugHandler) { await debugHandler(req, res); return; }
|
|
69
|
+
// Legacy REST handlers removed. History served by ccsniff at /v1/history/*.
|
|
70
|
+
for (const key of Object.keys(routes)) {
|
|
71
|
+
try {
|
|
72
|
+
const h = routes[key]?._match?.(req.method, pathOnly);
|
|
73
|
+
if (h) { await h(req, res); return; }
|
|
74
|
+
} catch (_) {}
|
|
75
|
+
}
|
|
90
76
|
if (routePath.startsWith('/api/image/')) {
|
|
91
77
|
const imagePath = routePath.slice('/api/image/'.length);
|
|
92
78
|
const decodedPath = decodeURIComponent(imagePath);
|
package/lib/routes-registry.js
CHANGED
|
@@ -1,50 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import { register as registerConvRoutes } from './routes-conversations.js';
|
|
5
|
-
import { register as registerAgentRoutes } from './routes-agents.js';
|
|
6
|
-
import { register as registerMessagesRoutes } from './routes-messages.js';
|
|
7
|
-
import { register as registerSessionsRoutes } from './routes-sessions.js';
|
|
8
|
-
import { register as registerRunsRoutes } from './routes-runs.js';
|
|
9
|
-
import { register as registerScriptsRoutes } from './routes-scripts.js';
|
|
10
|
-
import { register as registerAgentActionsRoutes } from './routes-agent-actions.js';
|
|
11
|
-
import { register as registerAuthConfigRoutes } from './routes-auth-config.js';
|
|
12
|
-
import { register as registerConvHandlers } from './ws-handlers-conv.js';
|
|
13
|
-
import { register as registerConvHandlers2 } from './ws-handlers-conv2.js';
|
|
14
|
-
import { register as registerSessionHandlers } from './ws-handlers-session.js';
|
|
15
|
-
import { register as registerSessionHandlers2 } from './ws-handlers-session2.js';
|
|
16
|
-
import { register as registerRunHandlers } from './ws-handlers-run.js';
|
|
17
|
-
import { register as registerUtilHandlers } from './ws-handlers-util.js';
|
|
18
|
-
import { register as registerScriptHandlers } from './ws-handlers-scripts.js';
|
|
19
|
-
import { register as registerQueueHandlers } from './ws-handlers-queue.js';
|
|
20
|
-
import { register as registerMsgHandlers } from './ws-handlers-msg.js';
|
|
21
|
-
import { getAgentDescriptor } from './agent-descriptors.js';
|
|
22
|
-
import { getProviderConfigs, saveProviderConfig } from './provider-config.js';
|
|
23
|
-
|
|
1
|
+
// Legacy route/ws registry stripped down. Old REST routes and WS handlers
|
|
2
|
+
// removed in favor of ccsniff /v1/history/* and the static site/app client.
|
|
3
|
+
// Keep as a no-op shim so server.js can still call it.
|
|
24
4
|
export function createRegistry(wsRouter, deps) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
routes.util = registerUtilRoutes({ sendJSON, parseBody, queries, STARTUP_CWD, PKG_VERSION });
|
|
28
|
-
routes.threads = registerThreadRoutes({ sendJSON, parseBody, queries });
|
|
29
|
-
routes.debug = registerDebugRoutes({ sendJSON, queries, activeExecutions, messageQueues, syncClients, wsOptimizer, _errLogPath: errLogPath });
|
|
30
|
-
routes.conv = registerConvRoutes({ sendJSON, parseBody, queries, activeExecutions, broadcastSync });
|
|
31
|
-
routes.agents = registerAgentRoutes({ sendJSON, parseBody, queries, discoveredAgents, getACPStatus, modelCache, getModelsForAgent, debugLog });
|
|
32
|
-
routes.messages = registerMessagesRoutes({ queries, sendJSON, parseBody, broadcastSync, processMessageWithStreaming, activeExecutions, messageQueues, debugLog, logError });
|
|
33
|
-
routes.sessions = registerSessionsRoutes({ queries, sendJSON, activeExecutions, rateLimitState, debugLog });
|
|
34
|
-
routes.runs = registerRunsRoutes({ sendJSON, parseBody, queries, broadcastSync, processMessageWithStreaming, activeExecutions, activeProcessesByRunId, discoveredAgents, STARTUP_CWD });
|
|
35
|
-
routes.scripts = registerScriptsRoutes({ sendJSON, parseBody, queries, broadcastSync, activeScripts, activeExecutions, processMessageWithStreaming, STARTUP_CWD });
|
|
36
|
-
routes.agentActions = registerAgentActionsRoutes({ sendJSON, queries, broadcastSync, discoveredAgents, activeScripts, modelCache, PORT, BASE_URL, rootDir });
|
|
37
|
-
routes.authConfig = registerAuthConfigRoutes({ sendJSON, parseBody, getProviderConfigs, saveProviderConfig });
|
|
38
|
-
|
|
39
|
-
registerConvHandlers(wsRouter, { queries, activeExecutions, rateLimitState, broadcastSync, processMessageWithStreaming, cleanupExecution, getJsonlWatcher });
|
|
40
|
-
registerConvHandlers2(wsRouter, { queries, activeExecutions, rateLimitState, broadcastSync, processMessageWithStreaming, cleanupExecution, getJsonlWatcher });
|
|
41
|
-
registerMsgHandlers(wsRouter, { queries, activeExecutions, messageQueues, broadcastSync, processMessageWithStreaming, logError });
|
|
42
|
-
registerQueueHandlers(wsRouter, { queries, messageQueues, broadcastSync });
|
|
43
|
-
debugLog('[INIT] registerSessionHandlers, agents: ' + discoveredAgents.length);
|
|
44
|
-
registerSessionHandlers(wsRouter, { db: queries, discoveredAgents, modelCache, getAgentDescriptor, activeScripts, broadcastSync });
|
|
45
|
-
registerSessionHandlers2(wsRouter, { discoveredAgents, modelCache, activeScripts, broadcastSync });
|
|
46
|
-
debugLog('[INIT] registerSessionHandlers completed');
|
|
47
|
-
registerRunHandlers(wsRouter, { queries, discoveredAgents, activeExecutions, activeProcessesByRunId, broadcastSync, processMessageWithStreaming, cleanupExecution });
|
|
48
|
-
registerUtilHandlers(wsRouter, { queries, wsOptimizer, broadcastSync, getProviderConfigs, saveProviderConfig, STARTUP_CWD, discoveredAgents });
|
|
49
|
-
registerScriptHandlers(wsRouter, { queries, broadcastSync, STARTUP_CWD, activeScripts });
|
|
5
|
+
// intentionally empty
|
|
50
6
|
}
|
package/lib/server-startup.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
// JsonlWatcher removed; history now served by ccsniff in-process.
|
|
2
|
+
const JsonlWatcher = null;
|
|
2
3
|
|
|
3
4
|
export function createOnServerReady({ queries, broadcastSync, warmAssetCache, staticDir, discoveredAgents, PORT, BASE_URL, watch, setWatcher, resumeInterruptedStreams, activeExecutions, debugLog, installGMAgentConfigs, startACPTools, getACPStatus, execMachine, performAutoImport, performAgentHealthCheck, recoverStaleSessions }) {
|
|
4
5
|
let jsonlWatcher = null;
|
|
@@ -21,16 +22,7 @@ export function createOnServerReady({ queries, broadcastSync, warmAssetCache, st
|
|
|
21
22
|
try { queries.cleanup(); console.log('[cleanup] Scheduled DB cleanup complete'); } catch (e) { console.error('[cleanup] Error:', e.message); }
|
|
22
23
|
}, 6 * 60 * 60 * 1000);
|
|
23
24
|
|
|
24
|
-
|
|
25
|
-
console.log('[JSONL] Watcher skipped (AGENTGUI_SKIP_AUTO_IMPORT=1)');
|
|
26
|
-
} else {
|
|
27
|
-
try {
|
|
28
|
-
jsonlWatcher = new JsonlWatcher({ broadcastSync, queries });
|
|
29
|
-
jsonlWatcher.start();
|
|
30
|
-
if (setWatcher) setWatcher(jsonlWatcher);
|
|
31
|
-
console.log('[JSONL] Watcher started');
|
|
32
|
-
} catch (err) { console.error('[JSONL] Watcher failed to start:', err.message); }
|
|
33
|
-
}
|
|
25
|
+
// JsonlWatcher removed; ccsniff handles JSONL history via its own watcher.
|
|
34
26
|
|
|
35
27
|
resumeInterruptedStreams().catch(err => console.error('[RESUME] Startup error:', err.message));
|
|
36
28
|
|
package/lib/ws-setup.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import { WebSocketServer } from 'ws';
|
|
4
|
-
|
|
4
|
+
// Legacy WS handlers removed; no-op shim kept for callsite compatibility.
|
|
5
|
+
const registerLegacyHandler = () => {};
|
|
5
6
|
|
|
6
7
|
export function createWsSetup(server, { BASE_URL, watch, staticDir, _assetCache, htmlState, sendWs, wsRouter, debugLog, subscriptionIndex, syncClients, wsOptimizer, legacyDeps }) {
|
|
7
8
|
const hotReloadClients = [];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentgui",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.932",
|
|
4
4
|
"description": "Multi-agent ACP client with real-time communication",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "electron/main.js",
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
"better-sqlite3": "^12.9.0",
|
|
32
32
|
"busboy": "^1.6.0",
|
|
33
33
|
"ccfollow": "^1.0.7",
|
|
34
|
+
"ccsniff": "github:AnEntrypoint/ccsniff#main",
|
|
34
35
|
"execa": "^9.6.1",
|
|
35
36
|
"express": "^5.2.1",
|
|
36
37
|
"form-data": "^4.0.5",
|
|
@@ -48,7 +49,6 @@
|
|
|
48
49
|
},
|
|
49
50
|
"devDependencies": {
|
|
50
51
|
"electron": "^35.0.0",
|
|
51
|
-
"playwright": "^1.59.1"
|
|
52
|
-
"rippleui": "^1.12.1"
|
|
52
|
+
"playwright": "^1.59.1"
|
|
53
53
|
}
|
|
54
54
|
}
|
package/server.js
CHANGED
|
@@ -5,6 +5,7 @@ import { fileURLToPath } from 'url';
|
|
|
5
5
|
import { LRUCache } from 'lru-cache';
|
|
6
6
|
const PKG_VERSION = JSON.parse(fs.readFileSync(new URL('./package.json', import.meta.url), 'utf8')).version;
|
|
7
7
|
import { createExpressApp } from './lib/routes-upload.js';
|
|
8
|
+
import { createHistoryRouter } from 'ccsniff';
|
|
8
9
|
import { queries } from './database.js';
|
|
9
10
|
import { runClaudeWithStreaming } from './lib/claude-runner-run.js';
|
|
10
11
|
import { initializeDescriptors, getAgentDescriptor } from './lib/agent-descriptors.js';
|
|
@@ -64,10 +65,15 @@ const STARTUP_CWD = (() => {
|
|
|
64
65
|
const cwd = process.env.STARTUP_CWD || process.cwd();
|
|
65
66
|
try { fs.accessSync(cwd, fs.constants.R_OK); return cwd; } catch { console.warn(`[server] STARTUP_CWD "${cwd}" not accessible, falling back to ${process.cwd()}`); return process.cwd(); }
|
|
66
67
|
})();
|
|
67
|
-
const staticDir = path.join(rootDir, '
|
|
68
|
+
const staticDir = path.join(rootDir, 'site', 'app');
|
|
68
69
|
if (!fs.existsSync(staticDir)) fs.mkdirSync(staticDir, { recursive: true });
|
|
69
70
|
|
|
70
71
|
const expressApp = createExpressApp({ queries, BASE_URL });
|
|
72
|
+
try {
|
|
73
|
+
const historyRouter = await createHistoryRouter({ projectsDir: process.env.CLAUDE_PROJECTS_DIR });
|
|
74
|
+
expressApp.use('/', historyRouter);
|
|
75
|
+
console.log('[ccsniff] /v1/history/* mounted');
|
|
76
|
+
} catch (e) { console.error('[ccsniff] mount failed:', e.message); }
|
|
71
77
|
|
|
72
78
|
let discoveredAgents = [];
|
|
73
79
|
initializeDescriptors(discoveredAgents);
|
package/site/app/js/app.js
CHANGED
|
@@ -3,7 +3,7 @@ import * as B from './backend.js';
|
|
|
3
3
|
|
|
4
4
|
installStyles().catch(() => {});
|
|
5
5
|
|
|
6
|
-
const { AppShell, Topbar, Crumb, Side, Status, Chat, ChatComposer, Row, Panel } = C;
|
|
6
|
+
const { AppShell, Topbar, Crumb, Side, Status, Chat, ChatComposer, Row, Panel, PageHeader, SearchInput, TextField, EventList } = C;
|
|
7
7
|
|
|
8
8
|
const state = {
|
|
9
9
|
backend: B.getBackend(),
|
|
@@ -235,33 +235,29 @@ async function sendChat() {
|
|
|
235
235
|
|
|
236
236
|
// ── history ────────────────────────────────────────────────────────────────
|
|
237
237
|
function historyMain() {
|
|
238
|
-
const head =
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
state.selectedSid
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
),
|
|
245
|
-
);
|
|
238
|
+
const head = PageHeader({
|
|
239
|
+
title: '§ history',
|
|
240
|
+
lede: state.selectedSid
|
|
241
|
+
? 'session ' + state.selectedSid
|
|
242
|
+
: 'pick a session from the sidebar — events stream from ccsniff /v1/history.',
|
|
243
|
+
});
|
|
246
244
|
|
|
247
245
|
if (!state.selectedSid) return [head];
|
|
248
246
|
if (state.events.length === 0) return [head, Panel({ title: 'events', children: h('p', { class: 'lede' }, '◌ loading…') })];
|
|
249
247
|
|
|
250
|
-
const rows = state.events.map((e, i) =>
|
|
251
|
-
Row({
|
|
252
|
-
key: 'ev' + i,
|
|
253
|
-
rank: String(i + 1).padStart(3, '0'),
|
|
254
|
-
title: (e.text || '').slice(0, 200) || '(empty)',
|
|
255
|
-
sub: new Date(e.ts).toLocaleString() + ' · ' + (e.role || '?') + ' · ' + (e.type || '?') + (e.tool ? ' · ⌘ ' + e.tool : ''),
|
|
256
|
-
rail: e.role === 'error' ? 'flame' : (e.role === 'user' ? 'green' : 'purple'),
|
|
257
|
-
})
|
|
258
|
-
);
|
|
259
|
-
|
|
260
248
|
return [
|
|
261
249
|
head,
|
|
262
250
|
Panel({
|
|
263
251
|
title: state.events.length + ' events',
|
|
264
|
-
children:
|
|
252
|
+
children: EventList({
|
|
253
|
+
events: state.events.map((e, i) => ({
|
|
254
|
+
key: 'ev' + i,
|
|
255
|
+
rank: String(i + 1).padStart(3, '0'),
|
|
256
|
+
title: (e.text || '').slice(0, 200) || '(empty)',
|
|
257
|
+
sub: new Date(e.ts).toLocaleString() + ' · ' + (e.role || '?') + ' · ' + (e.type || '?') + (e.tool ? ' · ⌘ ' + e.tool : ''),
|
|
258
|
+
rail: e.role === 'error' ? 'flame' : (e.role === 'user' ? 'green' : 'purple'),
|
|
259
|
+
})),
|
|
260
|
+
}),
|
|
265
261
|
}),
|
|
266
262
|
];
|
|
267
263
|
}
|
|
@@ -306,15 +302,15 @@ function historySide() {
|
|
|
306
302
|
}),
|
|
307
303
|
Panel({
|
|
308
304
|
title: searching ? 'matches' : 'sessions',
|
|
309
|
-
children:
|
|
310
|
-
|
|
311
|
-
|
|
305
|
+
children: [
|
|
306
|
+
SearchInput({
|
|
307
|
+
key: 'searchInput',
|
|
312
308
|
placeholder: 'search sessions…',
|
|
313
309
|
value: state.searchQ,
|
|
314
|
-
|
|
310
|
+
onInput: (v) => { state.searchQ = v; runSearch(); },
|
|
315
311
|
}),
|
|
316
|
-
rows.length ? h('div', {}, ...rows) : h('p', { class: 'lede' }, 'no sessions yet'),
|
|
317
|
-
|
|
312
|
+
rows.length ? h('div', { key: 'rows' }, ...rows) : h('p', { key: 'empty', class: 'lede' }, 'no sessions yet'),
|
|
313
|
+
],
|
|
318
314
|
}),
|
|
319
315
|
];
|
|
320
316
|
}
|
|
@@ -323,48 +319,48 @@ function historySide() {
|
|
|
323
319
|
function settingsMain() {
|
|
324
320
|
const ok = state.health.status === 'ok';
|
|
325
321
|
return [
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
))
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
),
|
|
322
|
+
PageHeader({
|
|
323
|
+
title: '⌘ settings',
|
|
324
|
+
lede: 'point agentgui at any backend. blank = same-origin (ccsniff in-process). ?backend=… or the field below persists via localStorage.',
|
|
325
|
+
}),
|
|
326
|
+
Panel({
|
|
327
|
+
title: 'backend',
|
|
328
|
+
children: [
|
|
329
|
+
TextField({
|
|
330
|
+
key: 'backendField',
|
|
331
|
+
label: 'backend url',
|
|
332
|
+
value: state.backendDraft,
|
|
333
|
+
placeholder: '(blank = same origin)',
|
|
334
|
+
onInput: (v) => { state.backendDraft = v; render(); },
|
|
335
|
+
}),
|
|
336
|
+
h('p', { key: 'hp', class: 'lede' }, (ok ? '● ' : '○ ') + JSON.stringify(state.health)),
|
|
337
|
+
h('button', {
|
|
338
|
+
key: 'savebtn',
|
|
339
|
+
onclick: () => {
|
|
340
|
+
B.setBackend(state.backendDraft);
|
|
341
|
+
state.backend = state.backendDraft;
|
|
342
|
+
state.health = { status: 'unknown' };
|
|
343
|
+
render();
|
|
344
|
+
init();
|
|
345
|
+
},
|
|
346
|
+
}, 'save + reconnect'),
|
|
347
|
+
],
|
|
348
|
+
}),
|
|
349
|
+
Panel({
|
|
350
|
+
title: 'models',
|
|
351
|
+
children: state.models.length
|
|
352
|
+
? state.models.slice(0, 40).map((m, i) =>
|
|
353
|
+
Row({
|
|
354
|
+
key: 'm' + i,
|
|
355
|
+
rank: String(i + 1).padStart(3, '0'),
|
|
356
|
+
title: m.id,
|
|
357
|
+
sub: m.owned_by || m.object || 'model',
|
|
358
|
+
rail: m.id === state.selectedModel ? 'green' : 'purple',
|
|
359
|
+
onClick: () => { state.selectedModel = m.id; render(); },
|
|
360
|
+
})
|
|
361
|
+
)
|
|
362
|
+
: h('p', { key: 'none', class: 'lede' }, 'no models loaded'),
|
|
363
|
+
}),
|
|
368
364
|
];
|
|
369
365
|
}
|
|
370
366
|
|
package/site/app/js/backend.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// acptoapi backend client. Resolves base URL from ?backend= or localStorage or default.
|
|
2
2
|
const KEY = 'agentgui.backend';
|
|
3
|
-
const DEFAULT_BACKEND = '
|
|
3
|
+
const DEFAULT_BACKEND = '';
|
|
4
4
|
|
|
5
5
|
export function getBackend() {
|
|
6
6
|
const u = new URL(location.href);
|