Files
EJClaw/src/config.ts
Eyejoker b710d4a33d chore: update claude-agent-sdk to 0.2.76, read dashboard config from .env
- Bump @anthropic-ai/claude-agent-sdk 0.2.68 → 0.2.76
- Read STATUS_CHANNEL_ID and USAGE_DASHBOARD from .env file
2026-03-16 05:54:17 +09:00

98 lines
3.1 KiB
TypeScript

import os from 'os';
import path from 'path';
import { readEnvFile } from './env.js';
const envConfig = readEnvFile([
'ASSISTANT_NAME',
'ASSISTANT_HAS_OWN_NUMBER',
'SESSION_COMMAND_USER_IDS',
'STATUS_CHANNEL_ID',
'USAGE_DASHBOARD',
]);
export const ASSISTANT_NAME =
process.env.ASSISTANT_NAME || envConfig.ASSISTANT_NAME || 'Andy';
// Service identity for DB partitioning (shared DB, two services)
export const SERVICE_ID =
ASSISTANT_NAME.toLowerCase() === 'codex' ? 'codex' : 'claude';
export const SERVICE_AGENT_TYPE: 'claude-code' | 'codex' =
ASSISTANT_NAME.toLowerCase() === 'codex' ? 'codex' : 'claude-code';
export const ASSISTANT_HAS_OWN_NUMBER =
(process.env.ASSISTANT_HAS_OWN_NUMBER ||
envConfig.ASSISTANT_HAS_OWN_NUMBER) === 'true';
export const SESSION_COMMAND_USER_IDS = new Set(
(
process.env.SESSION_COMMAND_USER_IDS ||
envConfig.SESSION_COMMAND_USER_IDS ||
''
)
.split(',')
.map((id) => id.trim())
.filter(Boolean),
);
export const POLL_INTERVAL = 2000;
export const SCHEDULER_POLL_INTERVAL = 60000;
const PROJECT_ROOT = process.cwd();
const HOME_DIR = process.env.HOME || os.homedir();
export const SENDER_ALLOWLIST_PATH = path.join(
HOME_DIR,
'.config',
'nanoclaw',
'sender-allowlist.json',
);
export const STORE_DIR = path.resolve(
process.env.NANOCLAW_STORE_DIR || path.join(PROJECT_ROOT, 'store'),
);
export const GROUPS_DIR = path.resolve(
process.env.NANOCLAW_GROUPS_DIR || path.join(PROJECT_ROOT, 'groups'),
);
export const DATA_DIR = path.resolve(
process.env.NANOCLAW_DATA_DIR || path.join(PROJECT_ROOT, 'data'),
);
// Shared cache directory (same across both services for dedup)
export const CACHE_DIR = path.join(PROJECT_ROOT, 'cache');
export const AGENT_TIMEOUT = parseInt(
process.env.AGENT_TIMEOUT || '1800000',
10,
);
export const AGENT_MAX_OUTPUT_SIZE = parseInt(
process.env.AGENT_MAX_OUTPUT_SIZE || '10485760',
10,
); // 10MB default
export const IPC_POLL_INTERVAL = 1000;
export const IDLE_TIMEOUT = parseInt(process.env.IDLE_TIMEOUT || '1800000', 10); // 30min default — how long to keep agent alive after last result
export const MAX_CONCURRENT_AGENTS = Math.max(
1,
parseInt(process.env.MAX_CONCURRENT_AGENTS || '5', 10) || 5,
);
function escapeRegex(str: string): string {
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
export const TRIGGER_PATTERN = new RegExp(
`^@${escapeRegex(ASSISTANT_NAME)}\\b`,
'i',
);
// Status dashboard: Discord channel ID for live agent status updates
export const STATUS_CHANNEL_ID =
process.env.STATUS_CHANNEL_ID || envConfig.STATUS_CHANNEL_ID || '';
export const STATUS_UPDATE_INTERVAL = 10000; // 10s
export const USAGE_UPDATE_INTERVAL = 300000; // 5 minutes
export const USAGE_DASHBOARD_ENABLED =
(process.env.USAGE_DASHBOARD || envConfig.USAGE_DASHBOARD || '') === 'true';
// Timezone for scheduled tasks (cron expressions, etc.)
// Uses system timezone by default
export const TIMEZONE =
process.env.TZ || Intl.DateTimeFormat().resolvedOptions().timeZone;
export function isSessionCommandSenderAllowed(senderId: string): boolean {
return SESSION_COMMAND_USER_IDS.has(senderId);
}