Feat : Log recorder
Some checks failed
release / build (push) Successful in 29s
release / verify-windows (push) Failing after 1m0s

This commit is contained in:
jeanotx32
2026-08-11 22:34:45 +02:00
parent 03b1963150
commit 1dd3959f29
16 changed files with 631 additions and 53 deletions

View File

@@ -3,6 +3,7 @@ import os from 'node:os';
import { WebSocket } from 'ws';
import type {
AgentAction,
AgentEvent,
AgentStatus,
AgentToServer,
LogLevel,
@@ -80,14 +81,23 @@ function send(message: AgentToServer): void {
}
}
function report(level: LogLevel, message: string): void {
/**
* Journalise localement et vers le serveur. `event` classe l'entrée dans
* l'historique de la VM ; l'omettre reste correct pour ce qui n'est que du
* bavardage de progression.
*/
function report(level: LogLevel, message: string, event?: AgentEvent): void {
const prefix = level === 'error' ? '✖' : level === 'warn' ? '!' : '·';
console.log(`${prefix} ${message}`);
send({ type: 'log', level, message, ts: Date.now() });
send({ type: 'log', level, message, ts: Date.now(), event });
}
obs.on('log', (level: LogLevel, message: string) => report(level, message));
watcher.on('log', (level: LogLevel, message: string) => report(level, message));
obs.on('log', (level: LogLevel, message: string, event?: AgentEvent) =>
report(level, message, event),
);
watcher.on('log', (level: LogLevel, message: string, event?: AgentEvent) =>
report(level, message, event),
);
function connect(): void {
if (shuttingDown) return;
@@ -194,7 +204,7 @@ async function handleServerMessage(message: ServerToAgent): Promise<void> {
} catch (err) {
const text = err instanceof Error ? err.message : String(err);
send({ type: 'result', requestId: message.requestId, ok: false, error: text });
report('error', `Échec de « ${message.action} » : ${text}`);
report('error', `Échec de « ${message.action} » : ${text}`, 'command.failed');
}
break;
}
@@ -238,13 +248,13 @@ async function startCapture(params: Record<string, unknown>): Promise<unknown> {
key: fullscreen.key,
windowMatch: fullscreen.windowMatch,
}).catch((err: Error) => {
report('warn', `Plein écran impossible : ${err.message}`);
report('warn', `Plein écran impossible : ${err.message}`, 'fullscreen.failed');
return `échec : ${err.message}`;
});
}
await obs.execute('record.start');
report('info', `Capture démarrée pour ${url}`);
report('info', `Capture démarrée pour ${url}`, 'capture.started');
return { opened, fullscreen: fullscreenResult, recording: true };
}
@@ -256,12 +266,13 @@ async function stopCapture(): Promise<unknown> {
if (browserSettings.enabled && browserSettings.closeOnStop) {
closed = await closeWindow(watcher.snapshotSettings.fullscreen.windowMatch, report).catch(
(err: Error) => {
report('warn', `Fermeture de la fenêtre impossible : ${err.message}`);
report('warn', `Fermeture de la fenêtre impossible : ${err.message}`, 'command.failed');
return `échec : ${err.message}`;
},
);
}
report('info', 'Capture arrêtée', 'capture.stopped');
return { ...(result as object), window: closed };
}
@@ -290,7 +301,7 @@ async function runAction(action: AgentAction, params: Record<string, unknown>):
typeof params.url === 'string' && params.url ? params.url : config.packageUrl,
{
recordState: () => obs.recordState(),
log: (level, message) => report(level, message),
log: (level, message, event) => report(level, message, event),
},
);
default:
@@ -338,9 +349,17 @@ async function drainPresetApply(): Promise<void> {
presetPending = false;
try {
report('info', describePreset(await obs.applyRecordingPreset(recordingSettings)));
report(
'info',
describePreset(await obs.applyRecordingPreset(recordingSettings)),
'preset.applied',
);
} catch (err) {
report('warn', `Preset non appliqué : ${err instanceof Error ? err.message : String(err)}`);
report(
'warn',
`Preset non appliqué : ${err instanceof Error ? err.message : String(err)}`,
'preset.failed',
);
}
}
@@ -355,7 +374,7 @@ async function applyPresetNow(params: Record<string, unknown>): Promise<PresetAp
encoder: isRecordingEncoder(params.encoder) ? params.encoder : recordingSettings.encoder,
});
presetPending = false;
report('info', describePreset(result));
report('info', describePreset(result), 'preset.applied');
return result;
}