mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-07 16:09:43 +02:00
fix(remote): stop the wake handlers shadowing each other; enforce the input cap
Two findings from a final review pass over the wake-on-LAN feature. `_onRemoteHostWaking` / `_onRemoteHostWakeFailed` were defined in BOTH `panels-ui.js` (toasts) and `host-wake-ui.js` (banner). Both files mix into `CodemanApp.prototype` and `host-wake-ui.js` loads later, so the panels-ui copies were silently shadowed: the toast never fired, and a wake started for a BACKGROUND session (input on a non-active tab) produced no notification at all, since the banner handler only acts on the active session. The handlers now live only in `host-wake-ui.js`, show the toast unconditionally, and update the banner when the woken session is the active one. `appendBoundedPending` dropped only WHOLE chunks, so a single input value over the cap (one large paste is one `input` value, up to the 100 KB input schema) was kept in full: "bounded at 4 KB" held per chunk, not per session, and nothing was logged. The surviving chunk's head is now trimmed too, code-point aware so a multi-byte character is never split into a replacement char. Adds the guard that would have caught the first one: every SSE dispatch handler must be defined in exactly ONE frontend module. The existing test only asserts a handler EXISTS somewhere, which two modules both satisfy while one is shadowed.
This commit is contained in:
@@ -99,6 +99,11 @@ export function decideRemoteInputAction(args: {
|
||||
/**
|
||||
* Append `data` to the pending buffer, dropping the OLDEST bytes when the cap is
|
||||
* exceeded. Returns the resulting buffer. Pure.
|
||||
*
|
||||
* A single chunk can itself exceed the cap (one large paste is one `input` value),
|
||||
* so after whole chunks are dropped the surviving chunk's HEAD is trimmed too —
|
||||
* otherwise "bounded at 4 KB" would hold only per chunk, not per session. The trim
|
||||
* is code-point aware, so it never emits a broken multi-byte character.
|
||||
*/
|
||||
export function appendBoundedPending(
|
||||
pending: string[],
|
||||
@@ -111,9 +116,25 @@ export function appendBoundedPending(
|
||||
total -= Buffer.byteLength(next[0]);
|
||||
next.shift();
|
||||
}
|
||||
if (next.length === 1) next[0] = tailWithinBytes(next[0], maxBytes);
|
||||
return next;
|
||||
}
|
||||
|
||||
/** Keep only the trailing part of `value` that fits in `maxBytes` UTF-8 bytes. Pure. */
|
||||
function tailWithinBytes(value: string, maxBytes: number): string {
|
||||
if (Buffer.byteLength(value) <= maxBytes) return value;
|
||||
const chars = [...value];
|
||||
let total = 0;
|
||||
let start = chars.length;
|
||||
while (start > 0) {
|
||||
const size = Buffer.byteLength(chars[start - 1]);
|
||||
if (total + size > maxBytes) break;
|
||||
total += size;
|
||||
start--;
|
||||
}
|
||||
return chars.slice(start).join('');
|
||||
}
|
||||
|
||||
/** The remote fields the wake flow needs. Structurally satisfied by `SessionRemote`. */
|
||||
export interface WakeableRemote {
|
||||
wakeCommand?: string;
|
||||
|
||||
Reference in New Issue
Block a user