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
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:
@@ -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 });
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user