mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-11-14 02:29:33 +01:00
fix(discord): post the rendered screen, not the raw stream, as the alert tail
A full-screen UI repaints in place, so the raw output stream read as garbage. Read capture-pane instead and drop rules, blanks and escape codes.
This commit is contained in:
1 parent
1c4338e8b5
commit
dcf51b1715
3 files changed
+69
-11
No files matched your search
@@ -184,6 +184,24 @@ export function getDiscordStartupHint(): string | undefined {
|
||||
return activeStartupHint;
|
||||
}
|
||||
|
||||
/**
|
||||
* The last lines of a rendered screen for a post: colour and charset codes removed, blank lines and
|
||||
* pure rule lines (box drawing, dashes) dropped, the last 14 lines, at most 900 characters, cut on a line.
|
||||
*/
|
||||
export function screenTail(screen: string, maxLines = 14, maxChars = 900): string {
|
||||
const lines = screen
|
||||
// eslint-disable-next-line no-control-regex
|
||||
.replace(/\u001b\[[0-9;?]*[ -/]*[@-~]|\u001b[()][A-Za-z0-9]|\u001b[@-Z\\-_]/g, '')
|
||||
// eslint-disable-next-line no-control-regex
|
||||
.replace(/[\u0000-\u0008\u000b-\u001f\u007f-\u009f]/g, '')
|
||||
.split(/\r?\n/)
|
||||
.map((l) => l.trimEnd())
|
||||
.filter((l) => l.trim() !== '' && !/^[\s\-_=\u2500-\u257f]+$/.test(l));
|
||||
let out = lines.slice(-maxLines);
|
||||
while (out.length > 1 && out.join('\n').length > maxChars) out = out.slice(1);
|
||||
return out.join('\n').slice(-maxChars);
|
||||
}
|
||||
|
||||
/** Final path segment only, `[A-Za-z0-9._-]`, no leading dot, at most 80 characters. */
|
||||
export function safeAttachmentName(name: string): string {
|
||||
const base = (name.split(/[\\/]/).pop() ?? '').replace(/[^A-Za-z0-9._-]+/g, '_').replace(/^[._]+/, '');
|
||||
|
||||
+10
-11
@@ -45,8 +45,7 @@ import { looksLikeHostReboot, newestPersistedActivity, planRebootRestore } from
|
||||
import { rebootRestoreRegistry } from './reboot-restore-registry.js';
|
||||
import { dataPath, getDataDir, CODEMAN_INSTANCE } from '../config/instance.js';
|
||||
import { WebhookNotifier, readWebhookConfig } from '../webhook-notify.js';
|
||||
import { DiscordBridge } from '../discord-bridge.js';
|
||||
import { stripAnsi } from '../utils/regex-patterns.js';
|
||||
import { DiscordBridge, screenTail } from '../discord-bridge.js';
|
||||
import { stopHostSensors } from '../host-sensors.js';
|
||||
import type { WebhookUrgency } from '../types/push.js';
|
||||
import { webviewFetch } from './webview-egress.js';
|
||||
@@ -3010,7 +3009,7 @@ export class WebServer extends EventEmitter {
|
||||
urgency: template.urgency as WebhookUrgency,
|
||||
sessionId: sessionId || undefined,
|
||||
sessionName: sessionName || undefined,
|
||||
tail: dcSession ? WebServer.outputTail(dcSession) : undefined,
|
||||
tail: dcSession ? this.discordTail(dcSession) : undefined,
|
||||
host: this.windowTitle,
|
||||
})
|
||||
.catch(() => undefined);
|
||||
@@ -3096,14 +3095,14 @@ export class WebServer extends EventEmitter {
|
||||
}
|
||||
}
|
||||
|
||||
/** The last few lines the CLI printed, with colour codes removed, for a Discord alert. */
|
||||
private static outputTail(session: { textOutput: string; terminalBuffer: string }): string {
|
||||
const raw = session.textOutput || session.terminalBuffer.slice(-4000);
|
||||
const lines = stripAnsi(raw)
|
||||
.split(/\r?\n/)
|
||||
.map((l) => l.trimEnd())
|
||||
.filter((l) => l.trim() !== '');
|
||||
return lines.slice(-12).join('\n').slice(-900);
|
||||
/**
|
||||
* What the person would see on the tab right now, for a Discord alert: the rendered tmux screen
|
||||
* (`capture-pane -p`), never the raw output stream, which a full-screen UI repaints in place and
|
||||
* reads as garbage. A session with no pane falls back to its plain text output, else nothing.
|
||||
*/
|
||||
private discordTail(session: { muxName?: string | null; textOutput: string }): string {
|
||||
const pane = session.muxName ? (this.mux.capturePaneText?.(session.muxName) ?? null) : null;
|
||||
return screenTail(pane ?? session.textOutput ?? '');
|
||||
}
|
||||
|
||||
/** The notification body for an event (shared by Web Push and the webhook channel). */
|
||||
|
||||
Reference in new issue
Block a user