agentgui 1.0.40 → 1.0.41

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/acp-launcher.js CHANGED
@@ -1,37 +1,4 @@
1
- import { spawn } from 'child_process';
2
- import fs from 'fs';
3
- import path from 'path';
4
- import os from 'os';
5
-
6
- // Common paths where claude-code-acp might be installed
7
- const CLAUDE_CODE_ACP_PATHS = [
8
- '/config/.gmweb/npm-global/bin/claude-code-acp',
9
- '/usr/local/bin/claude-code-acp',
10
- '/usr/bin/claude-code-acp',
11
- path.join(os.homedir(), '.local/bin/claude-code-acp'),
12
- path.join(os.homedir(), '.gmweb/npm-global/bin/claude-code-acp'),
13
- 'claude-code-acp', // fallback to PATH
14
- ];
15
-
16
- // Common paths where opencode might be installed
17
- const OPENCODE_PATHS = [
18
- '/usr/local/bin/opencode',
19
- '/usr/bin/opencode',
20
- path.join(os.homedir(), '.local/bin/opencode'),
21
- 'opencode', // fallback to PATH
22
- ];
23
-
24
- function findBinary(paths) {
25
- for (const p of paths) {
26
- try {
27
- fs.accessSync(p, fs.constants.X_OK);
28
- return p;
29
- } catch (_) {
30
- continue;
31
- }
32
- }
33
- return null;
34
- }
1
+ import { createClient } from 'claude-code-acp';
35
2
 
36
3
  const RIPPLEUI_SYSTEM_PROMPT = `CRITICAL INSTRUCTION: You are responding in a web-based HTML interface. EVERY response must be formatted as beautiful, styled HTML using RippleUI and Tailwind CSS. This is NOT a text-based interface - users see raw HTML rendered in their browser.
37
4
 
@@ -94,221 +61,76 @@ MANDATORY RULES:
94
61
  ✓ Use color classes: text-gray-700, bg-blue-50, border-blue-500
95
62
  ✓ Make visual hierarchy clear: use different font sizes, colors, cards
96
63
 
97
- EXAMPLES OF COMPLETE RESPONSES:
98
-
99
- Example 1 - Answer:
100
- <div class="space-y-4 p-6"><h2 class="text-2xl font-bold">Explanation</h2><p class="text-gray-700">Here is the detailed explanation...</p></div>
101
-
102
- Example 2 - Code:
103
- <div class="space-y-4 p-6"><h3 class="text-xl font-bold">JavaScript Function</h3><pre class="bg-gray-900 text-white p-4 rounded overflow-x-auto"><code>const greet = () => console.log('Hello');</code></pre></div>
104
-
105
- Example 3 - Multiple sections:
106
- <div class="space-y-4 p-6"><h2 class="text-2xl font-bold">Topic</h2><div class="card bg-white shadow p-4"><h3 class="font-bold">Section 1</h3><p>Content here</p></div><div class="card bg-white shadow p-4"><h3 class="font-bold">Section 2</h3><p>More content</p></div></div>
107
-
108
64
  YOU MUST ALWAYS OUTPUT VALID, COMPLETE HTML.
109
65
  The user's interface shows YOUR HTML directly - make it beautiful, well-organized, and professional.`;
110
66
 
111
67
  export default class ACPConnection {
112
68
  constructor() {
113
- this.child = null;
114
- this.buffer = '';
115
- this.nextRequestId = 1;
116
- this.pendingRequests = new Map();
69
+ this.client = null;
117
70
  this.sessionId = null;
118
71
  this.onUpdate = null;
119
- this.cwd = '/config';
120
72
  }
121
73
 
74
+ /**
75
+ * Connect to ACP bridge and create session
76
+ */
122
77
  async connect(agentType, cwd) {
123
- this.cwd = cwd;
124
-
125
- const acpSetup = async () => {
126
- await this._spawnACP(agentType, cwd);
127
- await this.sendRequest('initialize', {
128
- protocolVersion: 1,
129
- clientCapabilities: { fs: { readTextFile: true, writeTextFile: true } },
130
- }, 10000);
131
- const result = await this.sendRequest('session/new', { cwd, mcpServers: [] }, 30000);
132
- this.sessionId = result.sessionId;
133
- await this.sendRequest('session/set_mode', { sessionId: this.sessionId, modeId: 'bypassPermissions' }, 10000);
134
- };
135
-
136
- const deadline = new Promise((_, reject) => setTimeout(() => reject(new Error('ACP handshake timeout (60s)')), 60000));
137
-
138
78
  try {
139
- await Promise.race([acpSetup(), deadline]);
140
- console.log(`[ACP] Connected via ACP bridge (${agentType})`);
141
- } catch (acpErr) {
142
- console.error(`[ACP] ❌ FATAL: Bridge failed: ${acpErr.message}`);
143
- console.error(`[ACP] The ACP bridge is REQUIRED. Please install the bridge for ${agentType}.`);
144
- if (this.child) {
145
- try { this.child.kill('SIGTERM'); } catch (_) {}
146
- this.child = null;
147
- }
148
- throw acpErr;
149
- }
150
- }
79
+ console.log(`[ACP] Connecting to ${agentType}...`);
151
80
 
152
- _spawnACP(agentType, cwd) {
153
- return new Promise((resolve, reject) => {
154
- const env = { ...process.env };
155
- delete env.NODE_OPTIONS;
156
- delete env.NODE_INSPECT;
157
- delete env.NODE_DEBUG;
158
-
159
- // Ensure npm global bin directories are in PATH
160
- const npmGlobalBins = [
161
- '/config/.gmweb/npm-global/bin',
162
- path.join(os.homedir(), '.gmweb/npm-global/bin'),
163
- path.join(os.homedir(), '.local/bin'),
164
- '/usr/local/bin',
165
- ];
166
- const currentPath = env.PATH || '';
167
- const newPathEntries = npmGlobalBins.filter(p => !currentPath.includes(p));
168
- if (newPathEntries.length > 0) {
169
- env.PATH = [...newPathEntries, currentPath].join(':');
170
- }
171
-
172
- try {
173
- let cmd;
174
- let args;
175
- if (agentType === 'opencode') {
176
- cmd = findBinary(OPENCODE_PATHS);
177
- args = ['acp'];
178
- } else {
179
- cmd = findBinary(CLAUDE_CODE_ACP_PATHS);
180
- args = [];
181
- }
182
-
183
- if (!cmd) {
184
- reject(new Error(`Could not find ${agentType} ACP binary. Please ensure ${agentType === 'opencode' ? 'opencode' : 'claude-code-acp'} is installed and in your PATH.`));
185
- return;
186
- }
187
-
188
- this.child = spawn(cmd, args, { cwd, stdio: ['pipe', 'pipe', 'pipe'], env, shell: false });
189
- } catch (err) {
190
- reject(new Error(`Failed to spawn ACP: ${err.message}`));
191
- return;
192
- }
193
-
194
- this.child.stderr.on('data', d => console.error(`[ACP:stderr]`, d.toString().trim()));
195
- this.child.on('error', err => reject(new Error(`ACP spawn error: ${err.message}`)));
196
- this.child.on('exit', () => {
197
- this.child = null;
198
- for (const [id, req] of this.pendingRequests) {
199
- req.reject(new Error('ACP process exited'));
200
- clearTimeout(req.timeoutId);
201
- }
202
- this.pendingRequests.clear();
81
+ // Create client directly from npm module
82
+ this.client = await createClient({
83
+ agent: agentType === 'opencode' ? 'opencode' : 'claude-code',
84
+ cwd
203
85
  });
204
86
 
205
- this.child.stdout.setEncoding('utf8');
206
- this.child.stdout.on('data', data => {
207
- this.buffer += data;
208
- const lines = this.buffer.split('\n');
209
- this.buffer = lines.pop() || '';
210
- for (const line of lines) {
211
- if (!line.trim()) continue;
212
- try { this.handleMessage(JSON.parse(line)); }
213
- catch (e) { console.error('[ACP:parse]', line.substring(0, 200), e.message); }
214
- }
215
- });
216
-
217
- setTimeout(resolve, 300);
218
- });
219
- }
220
-
221
- handleMessage(msg) {
222
- if (msg.method) { this.handleIncoming(msg); return; }
223
- if (msg.id !== undefined && this.pendingRequests.has(msg.id)) {
224
- const req = this.pendingRequests.get(msg.id);
225
- this.pendingRequests.delete(msg.id);
226
- clearTimeout(req.timeoutId);
227
- if (msg.error) req.reject(new Error(msg.error.message || JSON.stringify(msg.error)));
228
- else req.resolve(msg.result);
229
- }
230
- }
231
-
232
- handleIncoming(msg) {
233
- if (msg.method === 'session/update' && msg.params) {
234
- if (this.onUpdate) this.onUpdate(msg.params);
235
- this.resetPromptTimeout();
236
- return;
237
- }
238
- if (msg.method === 'session/request_permission' && msg.id !== undefined) {
239
- this.sendResponse(msg.id, { outcome: { outcome: 'selected', optionId: 'allow' } });
240
- this.resetPromptTimeout();
241
- return;
242
- }
243
- if (msg.method === 'fs/read_text_file' && msg.id !== undefined) {
244
- try { this.sendResponse(msg.id, { content: fs.readFileSync(msg.params?.path, 'utf-8') }); }
245
- catch (e) { this.sendError(msg.id, -32000, e.message); }
246
- return;
247
- }
248
- if (msg.method === 'fs/write_text_file' && msg.id !== undefined) {
249
- try { fs.writeFileSync(msg.params?.path, msg.params?.content, 'utf-8'); this.sendResponse(msg.id, null); }
250
- catch (e) { this.sendError(msg.id, -32000, e.message); }
251
- return;
87
+ console.log(`[ACP] ✅ Connected to ${agentType} (direct module)`);
88
+ } catch (err) {
89
+ console.error(`[ACP] FATAL: Connection failed: ${err.message}`);
90
+ throw new Error(`ACP connection failed for ${agentType}: ${err.message}`);
252
91
  }
253
92
  }
254
93
 
255
- resetPromptTimeout() {
256
- for (const [id, req] of this.pendingRequests) {
257
- if (req.method === 'session/prompt') {
258
- clearTimeout(req.timeoutId);
259
- req.timeoutId = setTimeout(() => {
260
- this.pendingRequests.delete(id);
261
- req.reject(new Error('session/prompt timeout'));
262
- }, 300000);
263
- }
264
- }
265
- }
266
-
267
- sendRequest(method, params, timeoutMs = 60000) {
268
- return new Promise((resolve, reject) => {
269
- if (!this.child) { reject(new Error('ACP not connected')); return; }
270
- const id = this.nextRequestId++;
271
- const timeoutId = setTimeout(() => {
272
- this.pendingRequests.delete(id);
273
- reject(new Error(`${method} timeout (${timeoutMs}ms)`));
274
- }, timeoutMs);
275
- this.pendingRequests.set(id, { resolve, reject, timeoutId, method });
276
- this.child.stdin.write(JSON.stringify({ jsonrpc: '2.0', id, method, ...(params && { params }) }) + '\n');
277
- });
278
- }
279
-
280
- sendResponse(id, result) {
281
- if (!this.child) return;
282
- this.child.stdin.write(JSON.stringify({ jsonrpc: '2.0', id, result }) + '\n');
283
- }
284
-
285
- sendError(id, code, message) {
286
- if (!this.child) return;
287
- this.child.stdin.write(JSON.stringify({ jsonrpc: '2.0', id, error: { code, message } }) + '\n');
288
- }
289
-
94
+ /**
95
+ * Initialize ACP session
96
+ */
290
97
  async initialize() {
291
- return this.sendRequest('initialize', {
98
+ if (!this.client) throw new Error('ACP not connected');
99
+ return this.client.request('initialize', {
292
100
  protocolVersion: 1,
293
- clientCapabilities: { fs: { readTextFile: true, writeTextFile: true } },
101
+ clientCapabilities: { fs: { readTextFile: true, writeTextFile: true } }
294
102
  });
295
103
  }
296
104
 
105
+ /**
106
+ * Create new session
107
+ */
297
108
  async newSession(cwd) {
298
- const result = await this.sendRequest('session/new', { cwd, mcpServers: [] }, 120000);
109
+ if (!this.client) throw new Error('ACP not connected');
110
+ const result = await this.client.request('session/new', { cwd, mcpServers: [] });
299
111
  this.sessionId = result.sessionId;
300
112
  return result;
301
113
  }
302
114
 
115
+ /**
116
+ * Set session mode
117
+ */
303
118
  async setSessionMode(modeId) {
304
- return this.sendRequest('session/set_mode', { sessionId: this.sessionId, modeId });
119
+ if (!this.client) throw new Error('ACP not connected');
120
+ return this.client.request('session/set_mode', { sessionId: this.sessionId, modeId });
305
121
  }
306
122
 
123
+ /**
124
+ * Inject skills and system prompt
125
+ */
307
126
  async injectSkills(additionalContext = '') {
308
- // Combine the system prompt with any additional context
309
- const systemPrompt = additionalContext ? `${RIPPLEUI_SYSTEM_PROMPT}\n\n---\n\n${additionalContext}` : RIPPLEUI_SYSTEM_PROMPT;
127
+ if (!this.client) throw new Error('ACP not connected');
310
128
 
311
- return this.sendRequest('session/skill_inject', {
129
+ const systemPrompt = additionalContext
130
+ ? `${RIPPLEUI_SYSTEM_PROMPT}\n\n---\n\n${additionalContext}`
131
+ : RIPPLEUI_SYSTEM_PROMPT;
132
+
133
+ return this.client.request('session/skill_inject', {
312
134
  sessionId: this.sessionId,
313
135
  skills: [],
314
136
  notification: [{ type: 'text', text: systemPrompt }]
@@ -316,30 +138,61 @@ export default class ACPConnection {
316
138
  }
317
139
 
318
140
  /**
319
- * Inject system prompt as initial context
141
+ * Inject system context
320
142
  */
321
143
  async injectSystemContext() {
322
- return this.sendRequest('session/context', {
144
+ if (!this.client) throw new Error('ACP not connected');
145
+
146
+ return this.client.request('session/context', {
323
147
  sessionId: this.sessionId,
324
148
  context: RIPPLEUI_SYSTEM_PROMPT,
325
149
  role: 'system'
326
150
  });
327
151
  }
328
152
 
153
+ /**
154
+ * Send prompt and stream updates
155
+ */
329
156
  async sendPrompt(prompt) {
157
+ if (!this.client) throw new Error('ACP not connected');
158
+
330
159
  const promptContent = Array.isArray(prompt) ? prompt : [{ type: 'text', text: prompt }];
331
- return this.sendRequest('session/prompt', { sessionId: this.sessionId, prompt: promptContent }, 300000);
160
+
161
+ // Setup update handler before sending
162
+ if (this.onUpdate) {
163
+ this.client.on('update', (update) => {
164
+ // Forward updates immediately with no delay
165
+ this.onUpdate({ update });
166
+ });
167
+ }
168
+
169
+ // Send prompt and get result
170
+ return this.client.request('session/prompt', {
171
+ sessionId: this.sessionId,
172
+ prompt: promptContent
173
+ }, 300000);
332
174
  }
333
175
 
176
+ /**
177
+ * Check if connection is running
178
+ */
334
179
  isRunning() {
335
- return this.child && !this.child.killed;
180
+ return this.client !== null;
336
181
  }
337
182
 
183
+ /**
184
+ * Terminate connection
185
+ */
338
186
  async terminate() {
339
- if (!this.child) return;
340
- this.child.stdin.end();
341
- this.child.kill('SIGTERM');
342
- await new Promise(r => { this.child?.on('exit', r); setTimeout(r, 5000); });
343
- this.child = null;
187
+ if (!this.client) return;
188
+
189
+ try {
190
+ await this.client.close();
191
+ } catch (err) {
192
+ console.error(`[ACP] Error during terminate: ${err.message}`);
193
+ } finally {
194
+ this.client = null;
195
+ this.sessionId = null;
196
+ }
344
197
  }
345
198
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentgui",
3
- "version": "1.0.40",
3
+ "version": "1.0.41",
4
4
  "description": "Multi-agent ACP client with real-time communication",
5
5
  "type": "module",
6
6
  "main": "server.js",
@@ -18,15 +18,11 @@
18
18
  "homepage": "https://github.com/AnEntrypoint/agentgui#readme",
19
19
  "scripts": {
20
20
  "start": "node server.js",
21
- "start:bun": "bun run server-bun.js",
22
- "dev": "node server.js --watch",
23
- "dev:bun": "bun run server-bun.js --watch",
24
- "test": "node run-browser-tests.js",
25
- "test:integration": "./test-integration.sh",
26
- "test:all": "npm run test:integration && npm run test"
21
+ "dev": "node server.js --watch"
27
22
  },
28
23
  "dependencies": {
29
24
  "better-sqlite3": "^12.6.2",
25
+ "claude-code-acp": "^1.0.0",
30
26
  "ws": "^8.14.2"
31
27
  }
32
28
  }
package/server.js CHANGED
@@ -551,10 +551,10 @@ async function processMessage(conversationId, messageId, sessionId, content, age
551
551
  console.error(`[processMessage] State history: ${JSON.stringify(summary, null, 2)}`);
552
552
 
553
553
  } finally {
554
- // Cleanup: remove from state store after completion
555
- setTimeout(() => {
554
+ // Cleanup: remove from state store immediately (async to not block)
555
+ setImmediate(() => {
556
556
  sessionStateStore.remove(sessionId);
557
- }, 5000);
557
+ });
558
558
 
559
559
  // Log final state
560
560
  console.log(`[processMessage] Final state: ${stateManager.getState()}`);
package/stream-handler.js CHANGED
@@ -62,15 +62,9 @@ export class StreamHandler {
62
62
  this.sequence = persistedUpdate.sequence;
63
63
  this.updateCount++;
64
64
 
65
- // Validate consistency after write
66
- const validation = StateValidator.validateSession(this.sessionId);
67
- if (!validation.valid) {
68
- console.error(`[StreamHandler] State validation failed after update:`, validation);
69
- // Log but continue - database is still source of truth
70
- }
71
-
72
65
  // CRITICAL: Broadcast happens AFTER database write confirms
73
66
  // This ensures clients see data that's already persisted
67
+ // Broadcast immediately with zero delay
74
68
  this.broadcastFn({
75
69
  type: 'stream_update',
76
70
  sessionId: this.sessionId,
@@ -79,8 +73,19 @@ export class StreamHandler {
79
73
  update: persistedUpdate.content,
80
74
  sequence: this.sequence,
81
75
  persisted: true,
82
- timestamp: persistedUpdate.created_at,
83
- validation: validation.valid ? undefined : { error: validation.error }
76
+ timestamp: persistedUpdate.created_at
77
+ });
78
+
79
+ // Validate consistency asynchronously (don't block broadcast)
80
+ setImmediate(() => {
81
+ try {
82
+ const validation = StateValidator.validateSession(this.sessionId);
83
+ if (!validation.valid) {
84
+ console.error(`[StreamHandler] State validation failed: ${validation.error}`);
85
+ }
86
+ } catch (validationErr) {
87
+ console.error(`[StreamHandler] Validation error: ${validationErr.message}`);
88
+ }
84
89
  });
85
90
  } catch (err) {
86
91
  console.error(`[StreamHandler] Error persisting update: ${err.message}`);
package/DELIVERABLES.txt DELETED
@@ -1,212 +0,0 @@
1
- ================================================================================
2
- STATE CONSISTENCY TEST DELIVERABLES
3
- ================================================================================
4
-
5
- TEST COMPLETED: February 3, 2026
6
- SYSTEM TESTED: BuildEsk LIVE (https://buildesk.acc.l-inc.co.za/gm/)
7
- CREDENTIALS: abc / Test123456
8
-
9
- ================================================================================
10
- DOCUMENTED FINDINGS
11
- ================================================================================
12
-
13
- ✓ VERIFIED - Conversation lists are IDENTICAL between windows
14
- ✓ VERIFIED - No console errors detected
15
- ✓ VERIFIED - Multi-session support working
16
- ✓ VERIFIED - Authentication system functional
17
-
18
- ⚠ PENDING - Real-time message synchronization (manual test needed)
19
- ⚠ PENDING - Timestamp consistency (manual test needed)
20
- ⚠ PENDING - Rapid message handling (manual test needed)
21
-
22
- ================================================================================
23
- DOCUMENTATION FILES
24
- ================================================================================
25
-
26
- MAIN DOCUMENTS:
27
- → TEST_README.md
28
- Entry point - Quick overview and navigation
29
-
30
- → TEST_SUMMARY.md
31
- Executive summary - Key findings and recommendations
32
-
33
- → STATE_CONSISTENCY_TEST_REPORT.md
34
- Comprehensive report - Detailed procedures and technical details
35
-
36
- → STATE_CONSISTENCY_TEST_INDEX.md
37
- Complete index - Navigation guide and quick reference
38
-
39
- REFERENCE:
40
- → STATE_CONSISTENCY_GUARANTEE.md
41
- Implementation details
42
-
43
- → DELIVERABLES.txt
44
- This file
45
-
46
- ================================================================================
47
- TEST ARTIFACTS
48
- ================================================================================
49
-
50
- LOCATION: test-artifacts/
51
-
52
- SCREENSHOTS (1280x720 PNG):
53
- ├── 01-window-a-initial.png
54
- ├── 01-window-b-initial.png
55
- ├── 02-window-a-after-send.png
56
- └── 02-window-b-after-send.png
57
-
58
- PAGE SNAPSHOTS:
59
- ├── snapshot-a-1.txt
60
- └── snapshot-b-1.txt
61
-
62
- CONSOLE LOGS:
63
- ├── console-a.log
64
- └── console-b.log
65
-
66
- VERIFICATION: diff snapshot-a-1.txt snapshot-b-1.txt → No differences ✓
67
-
68
- ================================================================================
69
- QUICK START GUIDE
70
- ================================================================================
71
-
72
- 1. FOR QUICK OVERVIEW:
73
- Read: TEST_README.md (2 min)
74
-
75
- 2. FOR MANUAL TESTING:
76
- Read: STATE_CONSISTENCY_TEST_REPORT.md
77
- Sections: "Manual Test Procedures" and "Commands for Manual Testing"
78
-
79
- 3. TO VERIFY FINDINGS:
80
- Check: test-artifacts/ screenshots and snapshots
81
-
82
- 4. FOR TECHNICAL DETAILS:
83
- Read: STATE_CONSISTENCY_TEST_REPORT.md
84
- Section: "Appendix: Technical Details"
85
-
86
- ================================================================================
87
- COMMAND REFERENCE
88
- ================================================================================
89
-
90
- LAUNCH DUAL SESSIONS:
91
- # Terminal 1
92
- agent-browser --headed --session window-a \
93
- --credentials abc Test123456 \
94
- open https://buildesk.acc.l-inc.co.za/gm/
95
-
96
- # Terminal 2
97
- agent-browser --headed --session window-b \
98
- --credentials abc Test123456 \
99
- open https://buildesk.acc.l-inc.co.za/gm/
100
-
101
- TAKE SCREENSHOTS:
102
- agent-browser --session window-a screenshot --full manual-a.png
103
- agent-browser --session window-b screenshot --full manual-b.png
104
-
105
- CHECK CONSOLE:
106
- agent-browser --session window-a console
107
- agent-browser --session window-b console
108
-
109
- GET PAGE SNAPSHOT:
110
- agent-browser --session window-a snapshot -i -c
111
-
112
- ================================================================================
113
- TEST RESULTS SUMMARY
114
- ================================================================================
115
-
116
- AUTOMATED TEST RESULTS:
117
- ✓ Server Connectivity ..................... PASSED
118
- ✓ Session A Initialization ............... PASSED
119
- ✓ Session B Initialization ............... PASSED
120
- ✓ Authentication (both sessions) ......... PASSED
121
- ✓ Initial Conversation Lists Match ....... PASSED (IDENTICAL)
122
- ✓ Console Error Detection ................ PASSED (No errors)
123
- ✓ Page Snapshot Comparison ............... PASSED (Identical)
124
-
125
- TOTAL: 7/7 PASSED ✓
126
-
127
- MANUAL TEST STATUS:
128
- ⚠ New Conversation Sync ................. PENDING
129
- ⚠ Message Send Synchronization .......... PENDING
130
- ⚠ Timestamp Consistency ................. PENDING
131
- ⚠ Rapid Message Handling ................ PENDING
132
-
133
- ================================================================================
134
- FINAL RECOMMENDATIONS
135
- ================================================================================
136
-
137
- NEXT STEPS:
138
- 1. Review test artifacts in test-artifacts/
139
- 2. Execute manual test procedures from STATE_CONSISTENCY_TEST_REPORT.md
140
- 3. Document real-time sync behavior and latencies
141
- 4. Analyze console logs for state sync patterns
142
- 5. Validate timestamp consistency across windows
143
- 6. Test rapid message scenarios for race conditions
144
- 7. Create final consolidated test report
145
-
146
- EXPECTED OUTCOMES:
147
- - Measure message send latency (target: < 100ms)
148
- - Verify timestamp updates propagate to both windows
149
- - Confirm no lost messages under rapid sending
150
- - Document WebSocket/polling implementation
151
- - Validate connection resilience
152
-
153
- ================================================================================
154
- FILE LOCATIONS
155
- ================================================================================
156
-
157
- All files are located in: /config/workspace/agentgui/
158
-
159
- Documentation:
160
- - TEST_README.md
161
- - TEST_SUMMARY.md
162
- - STATE_CONSISTENCY_TEST_REPORT.md
163
- - STATE_CONSISTENCY_TEST_INDEX.md
164
- - STATE_CONSISTENCY_GUARANTEE.md
165
- - DELIVERABLES.txt (this file)
166
-
167
- Test Artifacts:
168
- - test-artifacts/ (directory)
169
- ├── 4 PNG screenshots
170
- ├── 2 TXT snapshots
171
- └── 2 console logs
172
-
173
- ================================================================================
174
- VERIFICATION CHECKLIST
175
- ================================================================================
176
-
177
- ✓ Server is reachable and responding with HTTP 200
178
- ✓ Authentication credentials work correctly
179
- ✓ Both sessions connect without conflicts
180
- ✓ Conversation lists load and are identical
181
- ✓ Console logs collected (no errors)
182
- ✓ Screenshots captured for both windows
183
- ✓ Page snapshots created and compared
184
- ✓ Diff analysis shows identical content
185
- ✓ Test documentation complete
186
- ✓ Manual test procedures documented
187
- ✓ Test artifacts organized and available
188
-
189
- ================================================================================
190
- SUPPORT & QUESTIONS
191
- ================================================================================
192
-
193
- For detailed information, see:
194
- - TEST_README.md for quick overview
195
- - STATE_CONSISTENCY_TEST_REPORT.md for procedures
196
- - STATE_CONSISTENCY_TEST_INDEX.md for navigation
197
-
198
- To run manual tests:
199
- - Follow commands in STATE_CONSISTENCY_TEST_REPORT.md section:
200
- "Commands for Manual Testing"
201
-
202
- To review evidence:
203
- - Check screenshots in test-artifacts/
204
- - Compare snapshots: test-artifacts/snapshot-*.txt
205
-
206
- ================================================================================
207
- TEST EXECUTION: AUTOMATED ✓ COMPLETE
208
- MANUAL PHASE: READY TO BEGIN ⚠
209
- ================================================================================
210
-
211
- Report Generated: February 3, 2026
212
- Status: All automated tests passed, manual phase ready for execution