fix: reduce global react doctor warnings (#214)
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,19 +116,23 @@ export function suspendTask(taskId: string, suspendedUntil: string): void {
|
|||||||
/**
|
/**
|
||||||
* Format the suspension notification for Discord.
|
* Format the suspension notification for Discord.
|
||||||
*/
|
*/
|
||||||
export function formatSuspensionNotice(
|
const SUSPENSION_RESUME_FORMATTER = new Intl.DateTimeFormat('ko-KR', {
|
||||||
task: ScheduledTask,
|
|
||||||
suspendedUntil: string,
|
|
||||||
reason: string,
|
|
||||||
): string {
|
|
||||||
const resumeLabel = new Intl.DateTimeFormat('ko-KR', {
|
|
||||||
month: 'numeric',
|
month: 'numeric',
|
||||||
day: 'numeric',
|
day: 'numeric',
|
||||||
hour: '2-digit',
|
hour: '2-digit',
|
||||||
minute: '2-digit',
|
minute: '2-digit',
|
||||||
hour12: false,
|
hour12: false,
|
||||||
timeZone: TIMEZONE,
|
timeZone: TIMEZONE,
|
||||||
}).format(new Date(suspendedUntil));
|
});
|
||||||
|
|
||||||
|
export function formatSuspensionNotice(
|
||||||
|
task: ScheduledTask,
|
||||||
|
suspendedUntil: string,
|
||||||
|
reason: string,
|
||||||
|
): string {
|
||||||
|
const resumeLabel = SUSPENSION_RESUME_FORMATTER.format(
|
||||||
|
new Date(suspendedUntil),
|
||||||
|
);
|
||||||
|
|
||||||
const lines = [
|
const lines = [
|
||||||
`⏸ 태스크 일시 중단`,
|
`⏸ 태스크 일시 중단`,
|
||||||
|
|||||||
@@ -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초');
|
||||||
|
|||||||
Reference in New Issue
Block a user