Files
memind/help-page-delivery-remediation.mjs
T
john 8f91c52c67 feat(help): add cursor help escalation worker and chat bridge
Introduce help escalation persistence, cursor help worker processing,
optional OpenAI-compatible chat bridge, and page delivery remediation.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-27 09:33:49 +08:00

83 lines
2.5 KiB
JavaScript

import path from 'node:path';
import { spawn } from 'node:child_process';
import { fileURLToPath } from 'node:url';
import {
extractHelpEscalationPagePath,
extractHelpEscalationSessionId,
} from './help-escalation.mjs';
const repoRoot = path.join(path.dirname(fileURLToPath(import.meta.url)));
function envFlag(value, fallback = true) {
const raw = String(value ?? '').trim().toLowerCase();
if (!raw) return fallback;
return ['1', 'true', 'yes', 'on'].includes(raw);
}
export function shouldAutoRemediateHelpViaGoose(escalation, env = process.env) {
if (!envFlag(env.MEMIND_CURSOR_HELP_AUTO_GOOSE_REMEDIATE, true)) return false;
const pagePath = extractHelpEscalationPagePath(escalation?.userText, escalation?.context ?? {});
return Boolean(pagePath && escalation?.userId);
}
export function runHelpPageDeliveryRemediationScript({
escalation,
env = process.env,
logger = console,
viaGoose = true,
} = {}) {
const userId = escalation?.userId;
const sessionId = extractHelpEscalationSessionId(escalation);
const pagePath = extractHelpEscalationPagePath(escalation?.userText, escalation?.context ?? {});
if (!userId || !pagePath) {
return Promise.resolve(null);
}
const scriptPath = path.join(repoRoot, 'scripts/help-remediate-page-delivery.mjs');
const args = [
scriptPath,
`--user-id=${userId}`,
`--page=${pagePath}`,
`--port=${Number(env.H5_PORT ?? 8081)}`,
];
if (sessionId) args.push(`--session-id=${sessionId}`);
if (viaGoose && sessionId) args.push('--via-goose');
logger.info?.('[cursor-help] auto goose remediation', {
userId,
sessionId,
pagePath,
viaGoose: Boolean(viaGoose && sessionId),
});
return new Promise((resolve, reject) => {
const child = spawn(process.execPath, args, {
cwd: repoRoot,
stdio: ['ignore', 'pipe', 'pipe'],
env,
});
let stdout = '';
let stderr = '';
child.stdout.on('data', (chunk) => {
stdout += String(chunk);
});
child.stderr.on('data', (chunk) => {
stderr += String(chunk);
});
child.on('error', reject);
child.on('close', (code) => {
if (code !== 0) {
reject(new Error(stderr.trim() || stdout.trim() || `remediation exited ${code}`));
return;
}
try {
const jsonLine = stdout.trim().split('\n').reverse().find((line) => line.startsWith('{'));
resolve(jsonLine ? JSON.parse(jsonLine) : { stdout });
} catch {
resolve({ stdout });
}
});
});
}