feat: expand live chat and work server tools

This commit is contained in:
2026-04-30 11:40:02 +09:00
parent 42ae640470
commit 2df0ba30cb
112 changed files with 15241 additions and 996 deletions

View File

@@ -21,6 +21,7 @@ import {
claimNextPlanForMerge,
claimNextPlanForMainMerge,
formatPlanNotificationLabel,
getPlanItemById,
isPlanLockedByWorker,
mapPlanRow,
markPlanAsCompleted,
@@ -50,9 +51,11 @@ const REPEATED_PROGRESS_NOTIFICATION_MS = 180_000;
const STARTED_REQUEST_SUMMARY_LIMIT = 72;
const ERROR_SUMMARY_MAX_LENGTH = 500;
const ERROR_SUMMARY_LINE_PATTERN =
/(ERROR:|failed|failure|capacity|Read-only file system|permission|not permitted|sandbox|os error|ENOENT|EACCES|ECONN|SyntaxError|TypeError|ReferenceError)/i;
/(ERROR:|\bfailed\b|\bfailure\b|capacity|Read-only file system|permission|not permitted|sandbox|os error|ENOENT|EACCES|ECONN|SyntaxError|TypeError|ReferenceError)/i;
const ERROR_SUMMARY_NOISE_PATTERN =
/^(exec|codex|tokens used|succeeded in \d+ms:?|[><=]{3,}|[A-Za-z]:\\|\/bin\/bash\b|\d+\s*[:|])/i;
/^(exec|codex|tokens used|succeeded in \d+ms:?|```|[><=]{3,}|[A-Za-z]:\\|\/bin\/bash\b|\d+\s*[:|])/i;
const ERROR_SUMMARY_STRUCTURED_NOISE_PATTERN =
/^(?:(?:[+\-]\s*)?(?:"(?:failed|failedCount|iosFailed|webFailed)"|'(?:failed|failedCount|iosFailed|webFailed)'|(?:failed|failedCount|iosFailed|webFailed))\s*(?::|=)\s*(?:\[\s*\]|0)\s*[,;]?|[+\-]\s*(?:"(?:failed|failedCount|iosFailed|webFailed)"|'(?:failed|failedCount|iosFailed|webFailed)'|(?:failed|failedCount|iosFailed|webFailed))\s*(?::|=).+|return\s+Promise\.resolve\(\{\s*ok:\s*true,\s*skipped:\s*(?:true|false),[\s\S]*failedCount:\s*0[\s\S]*\}\);?)$/i;
const PLAN_CODEX_RUNNER_MAX_ATTEMPTS = 2;
const PLAN_CODEX_RUNNER_RETRY_DELAY_MS = 5000;
const PLAN_CODEX_RUNNER_TRANSIENT_FAILURE_PATTERN =
@@ -133,12 +136,13 @@ function normalizeErrorSummaryLine(line: string) {
.trim();
}
function summarizeFailureOutput(output: string, fallback: string) {
export function summarizeFailureOutput(output: string, fallback: string) {
const normalizedLines = output
.split('\n')
.map((line) => normalizeErrorSummaryLine(line))
.filter(Boolean)
.filter((line) => !ERROR_SUMMARY_NOISE_PATTERN.test(line));
.filter((line) => !ERROR_SUMMARY_NOISE_PATTERN.test(line))
.filter((line) => !ERROR_SUMMARY_STRUCTURED_NOISE_PATTERN.test(line));
const bestLine =
normalizedLines.filter((line) => ERROR_SUMMARY_LINE_PATTERN.test(line)).at(-1) ??
@@ -288,11 +292,16 @@ export class PlanWorker {
return;
}
const item = await getPlanItemById(planId);
const disableWebPush = Boolean(item?.suppressWebPush);
const result = await sendNotifications({
title,
body,
threadId: `plan-${planId}`,
data: buildPlanNotificationData(planId, workId, eventType),
}, {
disableWebPush,
});
this.logger.info(
@@ -300,6 +309,7 @@ export class PlanWorker {
planId,
workId,
eventType,
disableWebPush,
ios: {
skipped: result.ios.skipped,
sentCount: result.ios.sentCount,