Final sweep: Crucible fixes, Path Tracer polish, forge progress, tests green.
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled

Align dashboard subtitle default and UpsertAgent tests with fleet label behavior; WebSocket coalesce and PathForge hardening; Crucible expanded ops and visual DV fixes; Vitest 610/610 and full test-suite pass; trim PROBLEMS.md to open items only.
This commit is contained in:
AetherForge
2026-06-06 18:07:47 -07:00
parent e65753ce49
commit 6372b07e6c
40 changed files with 1495 additions and 794 deletions

View File

@@ -172,6 +172,45 @@ describe('WebSocketProvider', () => {
expect(result.current.agentLogs.a1).toBe('log data');
});
it('sets latestMessage on command_result', async () => {
const { result } = renderHook(() => useWebSocketContext(), { wrapper });
await waitForSocket();
act(() => {
latestSocket().emitOpen();
latestSocket().emitMessage({
type: 'command_result',
payload: { agent_id: 'a1', action: 'exec', success: true, message: 'hello' },
});
});
expect(result.current.latestMessage?.type).toBe('command_result');
expect(result.current.commandResults).toHaveLength(1);
expect(result.current.commandResults[0].message).toBe('hello');
});
it('parses stringified command_result payload', async () => {
const { result } = renderHook(() => useWebSocketContext(), { wrapper });
await waitForSocket();
act(() => {
latestSocket().emitOpen();
latestSocket().emitMessage({
type: 'command_result',
payload: JSON.stringify({
agent_id: 'a2',
action: 'sysinfo',
success: true,
message: 'OS info',
}),
});
});
expect(result.current.commandResults).toHaveLength(1);
expect(result.current.commandResults[0].agent_id).toBe('a2');
expect(result.current.commandResults[0].message).toBe('OS info');
});
it('schedules reconnect after close', async () => {
MockWebSocket.instances = [];
renderHook(() => useWebSocketContext(), { wrapper });

View File

@@ -261,7 +261,16 @@ export function WebSocketProvider({ children }: { children: React.ReactNode }) {
break;
}
case 'command_result': {
const p = msg.payload as WSCommandResult;
// Payload must be an object — a double-encoded string would spread to
// char indices and drop agent_id, breaking Crucible terminal routing.
let p = msg.payload as WSCommandResult | string;
if (typeof p === 'string') {
try {
p = JSON.parse(p) as WSCommandResult;
} catch {
break;
}
}
const seq = ++cmdSeqRef.current;
// Cap at 2000; command results are rare (operator-triggered) so this is plenty.
// Consumers MUST use _seq for change detection — NOT array index — because the