fix: reduce global react doctor warnings (#214)

This commit is contained in:
Eyejoker
2026-06-03 08:30:24 +08:00
committed by GitHub
parent 22602da1ec
commit 2dab27f443
5 changed files with 41 additions and 45 deletions

View File

@@ -415,12 +415,7 @@ export class DiscordChannel implements Channel {
.trim(); .trim();
// Convert @username mentions to Discord mention format // Convert @username mentions to Discord mention format
const mentionMap: Record<string, string> = { cleaned = cleaned.replaceAll('@눈쟁이', '<@216851709744513024>');
: '216851709744513024',
};
for (const [name, id] of Object.entries(mentionMap)) {
cleaned = cleaned.replace(new RegExp(`@${name}`, 'g'), `<@${id}>`);
}
cleaned = formatOutbound(cleaned); cleaned = formatOutbound(cleaned);
// Discord has a 2000 character limit per message and 10 attachments per message // Discord has a 2000 character limit per message and 10 attachments per message

View File

@@ -16,6 +16,7 @@ export function readCodexFeatureFromContent(
feature: CodexConfigFeature, feature: CodexConfigFeature,
): boolean { ): boolean {
const lines = content.split('\n'); const lines = content.split('\n');
const featureLinePattern = new RegExp(`^${feature}\\s*=\\s*(true|false)$`);
let inFeatures = false; let inFeatures = false;
for (const line of lines) { for (const line of lines) {
@@ -28,9 +29,7 @@ export function readCodexFeatureFromContent(
break; break;
} }
if (!inFeatures) continue; if (!inFeatures) continue;
const match = trimmed.match( const match = trimmed.match(featureLinePattern);
new RegExp(`^${feature}\\s*=\\s*(true|false)$`),
);
if (match) return match[1] === 'true'; if (match) return match[1] === 'true';
} }

View File

@@ -227,13 +227,7 @@ export function listClaudeAccounts(): ClaudeAccountSummary[] {
if (def) out.push(def); if (def) out.push(def);
const dir = path.join(settingsHomeDir(), '.claude-accounts'); const dir = path.join(settingsHomeDir(), '.claude-accounts');
if (fs.existsSync(dir)) { if (fs.existsSync(dir)) {
const entries = fs.readdirSync(dir); for (const i of readAccountIndices(dir)) {
const indices = entries
.filter((e) => /^\d+$/.test(e))
.map((e) => Number.parseInt(e, 10))
.filter((n) => Number.isFinite(n) && n >= 1)
.sort((a, b) => a - b);
for (const i of indices) {
const acc = readClaudeAccount(i); const acc = readClaudeAccount(i);
if (acc) out.push(acc); if (acc) out.push(acc);
} }
@@ -247,13 +241,7 @@ export function listCodexAccounts(): CodexAccountSummary[] {
if (def) out.push(def); if (def) out.push(def);
const dir = path.join(settingsHomeDir(), '.codex-accounts'); const dir = path.join(settingsHomeDir(), '.codex-accounts');
if (fs.existsSync(dir)) { if (fs.existsSync(dir)) {
const entries = fs.readdirSync(dir); for (const i of readAccountIndices(dir)) {
const indices = entries
.filter((e) => /^\d+$/.test(e))
.map((e) => Number.parseInt(e, 10))
.filter((n) => Number.isFinite(n) && n >= 1)
.sort((a, b) => a - b);
for (const i of indices) {
const acc = readCodexAccount(i); const acc = readCodexAccount(i);
if (acc) out.push(acc); if (acc) out.push(acc);
} }
@@ -261,6 +249,16 @@ export function listCodexAccounts(): CodexAccountSummary[] {
return out; return out;
} }
function readAccountIndices(dir: string): number[] {
const indices: number[] = [];
for (const entry of fs.readdirSync(dir)) {
if (!/^\d+$/.test(entry)) continue;
const index = Number.parseInt(entry, 10);
if (Number.isFinite(index) && index >= 1) indices.push(index);
}
return indices.sort((a, b) => a - b);
}
function pickEnvValue(content: string, key: string): string | undefined { function pickEnvValue(content: string, key: string): string | undefined {
const re = new RegExp(`^${key}=(.*)$`, 'm'); const re = new RegExp(`^${key}=(.*)$`, 'm');
const match = content.match(re); const match = content.match(re);
@@ -526,13 +524,7 @@ export function getActiveCodexSettingsIndex(): number | null {
} }
const dir = path.join(settingsHomeDir(), '.codex-accounts'); const dir = path.join(settingsHomeDir(), '.codex-accounts');
if (fs.existsSync(dir)) { if (fs.existsSync(dir)) {
const indices = fs for (const i of readAccountIndices(dir)) {
.readdirSync(dir)
.filter((e) => /^\d+$/.test(e))
.map((e) => Number.parseInt(e, 10))
.filter((n) => Number.isFinite(n) && n >= 1)
.sort((a, b) => a - b);
for (const i of indices) {
if (codexAuthPath(i) === activePath) return i; if (codexAuthPath(i) === activePath) return i;
} }
} }

View File

@@ -116,19 +116,23 @@ export function suspendTask(taskId: string, suspendedUntil: string): void {
/** /**
* Format the suspension notification for Discord. * Format the suspension notification for Discord.
*/ */
const SUSPENSION_RESUME_FORMATTER = new Intl.DateTimeFormat('ko-KR', {
month: 'numeric',
day: 'numeric',
hour: '2-digit',
minute: '2-digit',
hour12: false,
timeZone: TIMEZONE,
});
export function formatSuspensionNotice( export function formatSuspensionNotice(
task: ScheduledTask, task: ScheduledTask,
suspendedUntil: string, suspendedUntil: string,
reason: string, reason: string,
): string { ): string {
const resumeLabel = new Intl.DateTimeFormat('ko-KR', { const resumeLabel = SUSPENSION_RESUME_FORMATTER.format(
month: 'numeric', new Date(suspendedUntil),
day: 'numeric', );
hour: '2-digit',
minute: '2-digit',
hour12: false,
timeZone: TIMEZONE,
}).format(new Date(suspendedUntil));
const lines = [ const lines = [
`⏸ 태스크 일시 중단`, `⏸ 태스크 일시 중단`,

View File

@@ -13,6 +13,18 @@ export type WatcherStatusPhase =
export const WATCH_CI_PREFIX = WATCH_CI_PROMPT_PREFIX; export const WATCH_CI_PREFIX = WATCH_CI_PROMPT_PREFIX;
export const TASK_STATUS_MESSAGE_PREFIX = '\u2063\u2063\u2063'; export const TASK_STATUS_MESSAGE_PREFIX = '\u2063\u2063\u2063';
export const DEFAULT_WATCH_CI_MAX_DURATION_MS = 24 * 60 * 60 * 1000; export const DEFAULT_WATCH_CI_MAX_DURATION_MS = 24 * 60 * 60 * 1000;
let watchTimeFormatter: Intl.DateTimeFormat | null = null;
function getWatchTimeFormatter(): Intl.DateTimeFormat {
watchTimeFormatter ??= new Intl.DateTimeFormat('ko-KR', {
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false,
timeZone: TIMEZONE,
});
return watchTimeFormatter;
}
export function isWatchCiTask(task: Pick<ScheduledTask, 'prompt'>): boolean { export function isWatchCiTask(task: Pick<ScheduledTask, 'prompt'>): boolean {
return task.prompt.startsWith(WATCH_CI_PREFIX); return task.prompt.startsWith(WATCH_CI_PREFIX);
@@ -36,13 +48,7 @@ export function extractWatchCiTarget(prompt: string): string | null {
} }
function formatTimeLabel(timestampIso: string): string { function formatTimeLabel(timestampIso: string): string {
return new Intl.DateTimeFormat('ko-KR', { return getWatchTimeFormatter()
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false,
timeZone: TIMEZONE,
})
.format(new Date(timestampIso)) .format(new Date(timestampIso))
.replace(/:/g, '시 ') .replace(/:/g, '시 ')
.replace(/시 (\d{2})$/, '분 $1초'); .replace(/시 (\d{2})$/, '분 $1초');