fix: load project .env vars and cleanup stale sessions

- Load project's .env file when spawning Claude so API credentials work
- Check isClaudeRunning() before routing messages to sessions
- Auto-cleanup stale sessions when Claude has exited
- Fixes ESO Logs API access from spawned Claude instances

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
RichardDillman
2025-11-25 18:22:46 -05:00
parent 0d277e4ae2
commit 0ce65d7120
2 changed files with 49 additions and 1 deletions

View File

@@ -3,6 +3,42 @@
import { spawn, ChildProcess } from 'child_process';
import { findProject, touchProject } from './project-registry.js';
import { readFileSync, existsSync } from 'fs';
import { join } from 'path';
// Load .env file from a directory and return as object
function loadEnvFile(dirPath: string): Record<string, string> {
const envPath = join(dirPath, '.env');
const envVars: Record<string, string> = {};
if (existsSync(envPath)) {
try {
const content = readFileSync(envPath, 'utf-8');
for (const line of content.split('\n')) {
const trimmed = line.trim();
// Skip comments and empty lines
if (!trimmed || trimmed.startsWith('#')) continue;
const eqIndex = trimmed.indexOf('=');
if (eqIndex > 0) {
const key = trimmed.substring(0, eqIndex).trim();
let value = trimmed.substring(eqIndex + 1).trim();
// Remove quotes if present
if ((value.startsWith('"') && value.endsWith('"')) ||
(value.startsWith("'") && value.endsWith("'"))) {
value = value.slice(1, -1);
}
envVars[key] = value;
}
}
console.log(`[SPAWN] Loaded ${Object.keys(envVars).length} env vars from ${envPath}`);
} catch (error) {
console.error(`[SPAWN] Failed to load .env from ${envPath}:`, error);
}
}
return envVars;
}
interface SpawnedProcess {
projectName: string;
@@ -38,6 +74,9 @@ export async function spawnClaude(
}
try {
// Load project's .env file to pass to Claude
const projectEnv = loadEnvFile(project.path);
// Spawn Claude Code
const claudeProcess = spawn('claude', initialPrompt ? [initialPrompt] : [], {
cwd: project.path,
@@ -45,6 +84,7 @@ export async function spawnClaude(
detached: true,
env: {
...process.env,
...projectEnv, // Include project's .env variables
INNERVOICE_SPAWNED: '1' // Mark as spawned by InnerVoice
}
});

View File

@@ -419,7 +419,10 @@ bot.on('text', async (ctx) => {
const activeSession = Array.from(activeSessions.values())
.find(s => s.projectName.toLowerCase() === targetProject.toLowerCase());
if (activeSession) {
// Check if Claude is actually running (not just session registered)
const claudeActuallyRunning = isClaudeRunning(targetProject);
if (activeSession && claudeActuallyRunning) {
// Add to message queue with session ID
messageQueue.push({
from,
@@ -430,6 +433,11 @@ bot.on('text', async (ctx) => {
});
await ctx.reply(`💬 Message sent to active session: *${activeSession.projectName}*`, { parse_mode: 'Markdown' });
} else {
// Clean up stale session if Claude exited
if (activeSession && !claudeActuallyRunning) {
console.log(`[CLEANUP] Removing stale session for ${activeSession.projectName} (Claude not running)`);
activeSessions.delete(activeSession.id);
}
// No active session - check if project is registered and should auto-spawn
try {
const project = await findProject(targetProject);