mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-04 08:34:06 +00:00
Extract shared normalization/coercion helpers into private @openclaw/normalization-core workspace package while preserving existing plugin SDK helper subpaths.\n\nAlso keeps direct normalization-core imports internal, wires UI/build/loader resolution, and replaces the slow PR network CodeQL lane with a fast added-line boundary scan while retaining full CodeQL for scheduled/manual runs.\n\nVerification: local moved tests, plugin SDK boundary tests, extension loader tests, agents-support shard, UI build/test, build artifacts, lint, workflow guards, autoreview, and GitHub CI passed on PR head 963d893715.
63 lines
2.0 KiB
TypeScript
63 lines
2.0 KiB
TypeScript
import { asPositiveSafeInteger } from "@openclaw/normalization-core/number-coercion";
|
|
import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce";
|
|
|
|
export type SessionTranscriptUpdate = {
|
|
sessionFile: string;
|
|
sessionKey?: string;
|
|
agentId?: string;
|
|
message?: unknown;
|
|
messageId?: string;
|
|
messageSeq?: number;
|
|
};
|
|
|
|
type SessionTranscriptListener = (update: SessionTranscriptUpdate) => void;
|
|
|
|
const SESSION_TRANSCRIPT_LISTENERS = new Set<SessionTranscriptListener>();
|
|
|
|
export function onSessionTranscriptUpdate(listener: SessionTranscriptListener): () => void {
|
|
SESSION_TRANSCRIPT_LISTENERS.add(listener);
|
|
return () => {
|
|
SESSION_TRANSCRIPT_LISTENERS.delete(listener);
|
|
};
|
|
}
|
|
|
|
export function emitSessionTranscriptUpdate(update: string | SessionTranscriptUpdate): void {
|
|
const normalized =
|
|
typeof update === "string"
|
|
? { sessionFile: update }
|
|
: {
|
|
sessionFile: update.sessionFile,
|
|
sessionKey: update.sessionKey,
|
|
agentId: update.agentId,
|
|
message: update.message,
|
|
messageId: update.messageId,
|
|
messageSeq: update.messageSeq,
|
|
};
|
|
const trimmed = normalizeOptionalString(normalized.sessionFile);
|
|
if (!trimmed) {
|
|
return;
|
|
}
|
|
const messageSeq = asPositiveSafeInteger(normalized.messageSeq);
|
|
const nextUpdate: SessionTranscriptUpdate = {
|
|
sessionFile: trimmed,
|
|
...(normalizeOptionalString(normalized.sessionKey)
|
|
? { sessionKey: normalizeOptionalString(normalized.sessionKey) }
|
|
: {}),
|
|
...(normalizeOptionalString(normalized.agentId)
|
|
? { agentId: normalizeOptionalString(normalized.agentId) }
|
|
: {}),
|
|
...(normalized.message !== undefined ? { message: normalized.message } : {}),
|
|
...(normalizeOptionalString(normalized.messageId)
|
|
? { messageId: normalizeOptionalString(normalized.messageId) }
|
|
: {}),
|
|
...(messageSeq !== undefined ? { messageSeq } : {}),
|
|
};
|
|
for (const listener of SESSION_TRANSCRIPT_LISTENERS) {
|
|
try {
|
|
listener(nextUpdate);
|
|
} catch {
|
|
/* ignore */
|
|
}
|
|
}
|
|
}
|