Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 13 additions & 12 deletions packages/apprentice/src/daemon/adapters/discord.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
ChannelType,
Partials,
} from 'discord.js';
import { createLogger } from '../../utils/logger.js';
import {
type PlatformAdapter,
type PlatformConfig,
Expand All @@ -20,6 +21,8 @@ import {
type DiscordConfig,
} from '../types.js';

const log = createLogger({ namespace: 'Discord' });

export class DiscordAdapter implements PlatformAdapter {
public readonly platform = 'discord' as const;

Expand Down Expand Up @@ -51,7 +54,7 @@ export class DiscordAdapter implements PlatformAdapter {
return new Promise((resolve, reject) => {
this.client.once(Events.ClientReady, () => {
this.ready = true;
console.log(`Discord connected as ${this.client.user?.tag}`);
log.info('Connected', { tag: this.client.user?.tag });
resolve();
});

Expand Down Expand Up @@ -102,7 +105,7 @@ export class DiscordAdapter implements PlatformAdapter {
try {
await this.onMessage(incomingMsg);
} catch (error) {
console.error('Error handling Discord message:', error);
log.error('Error handling message', { error });
}
});

Expand All @@ -126,7 +129,7 @@ export class DiscordAdapter implements PlatformAdapter {
added: true,
});
} catch (error) {
console.error('Error handling Discord reaction:', error);
log.error('Error handling reaction', { error });
}
});

Expand All @@ -146,7 +149,7 @@ export class DiscordAdapter implements PlatformAdapter {
added: false,
});
} catch (error) {
console.error('Error handling Discord reaction remove:', error);
log.error('Error handling reaction remove', { error });
}
});
}
Expand Down Expand Up @@ -259,13 +262,11 @@ export class DiscordAdapter implements PlatformAdapter {
messageRef: MessageRef,
content: MessageContent,
): Promise<void> {
console.log(
`[Discord] Editing message ${messageRef.messageId} in channel ${messageRef.channelId}`,
);
log.debug('Editing message', { messageId: messageRef.messageId, channelId: messageRef.channelId });
const channel = await this.resolveChannel(messageRef);
console.log(`[Discord] Resolved channel, fetching message...`);
log.debug('Resolved channel, fetching message');
const message = await channel.messages.fetch(messageRef.messageId);
console.log(`[Discord] Message fetched successfully`);
log.debug('Message fetched successfully');

const editOptions: any = {};

Expand All @@ -274,7 +275,7 @@ export class DiscordAdapter implements PlatformAdapter {
}

if (content.image) {
console.log(`[Discord] Attaching image (${content.image.length} bytes)`);
log.debug('Attaching image', { size: content.image.length });
const attachment = new AttachmentBuilder(content.image, {
name: 'progress.png',
});
Expand All @@ -299,9 +300,9 @@ export class DiscordAdapter implements PlatformAdapter {
];
}

console.log(`[Discord] Applying message edit...`);
log.debug('Applying message edit');
await message.edit(editOptions);
console.log(`[Discord] Message edit complete`);
log.debug('Message edit complete');
}

public async deleteMessage(messageRef: MessageRef): Promise<void> {
Expand Down
44 changes: 21 additions & 23 deletions packages/apprentice/src/daemon/agent-runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,15 @@ import { EventEmitter } from 'events';
import { writeFileSync } from 'fs';
import { join, dirname } from 'path';
import { promisify } from 'util';
import { createLogger } from '../utils/logger.js';
import { ProgressFileWriter, getProgressFilePath } from './progress-file.js';
import { type AgentConfig, type ProgressConfig } from './types.js';

const execAsync = promisify(exec);

const log = createLogger({ namespace: 'AgentRunner' });
const agentLog = createLogger({ namespace: 'Agent' });

export interface AgentProcess extends EventEmitter {
readonly id: string;
readonly pid: number | undefined;
Expand Down Expand Up @@ -73,7 +77,7 @@ export class AgentRunner {

// Start asynchronously but catch any errors
process.start().catch((err) => {
console.error(`[AgentRunner] Failed to start process:`, err);
log.error('Failed to start process', { error: err });
});
return process;
}
Expand Down Expand Up @@ -150,46 +154,42 @@ class AgentProcessImpl extends EventEmitter implements AgentProcess {

this.process = this.spawnAgent();

console.log(
`[AgentRunner] Process spawned with PID: ${this.process.pid}`,
);
log.info('Process spawned', { pid: this.process.pid });
await this.progressWriter.addLogEntry(
`Process spawned (PID: ${this.process.pid})`,
);

// Debug lifecycle events
this.process.on('spawn', () => {
console.log(`[AgentRunner] Process spawn event fired`);
log.debug('Process spawn event fired');
});
this.process.on('disconnect', () => {
console.log(`[AgentRunner] Process disconnected`);
log.debug('Process disconnected');
});
this.process.on('exit', (code, signal) => {
console.log(
`[AgentRunner] Process exit: code=${code}, signal=${signal}`,
);
log.debug('Process exit', { code, signal });
});

this.process.stdout?.on('data', (data) => {
const text = data.toString();
console.log(`[Agent] stdout: ${text.trim()}`);
agentLog.debug('stdout', { data: text.trim() });
this.handleOutput(text);
});
this.process.stdout?.on('end', () => {
console.log(`[AgentRunner] stdout stream ended`);
log.debug('stdout stream ended');
});
this.process.stderr?.on('data', (data) => {
const text = data.toString();
console.log(`[Agent] stderr: ${text.trim()}`);
agentLog.debug('stderr', { data: text.trim() });
this.handleOutput(text);
});

this.process.on('close', (code) => {
console.log(`[AgentRunner] Process closed with code: ${code}`);
log.info('Process closed', { code });
this.handleClose(code);
});
this.process.on('error', (err) => {
console.error(`[AgentRunner] Process error:`, err);
log.error('Process error', { error: err });
this.handleError(err);
});

Expand Down Expand Up @@ -220,7 +220,7 @@ class AgentProcessImpl extends EventEmitter implements AgentProcess {
);
const promptContent = this.buildProgressInstructions(progressFilePath);
writeFileSync(promptFilePath, promptContent);
console.log(`[AgentRunner] Wrote prompt file: ${promptFilePath}`);
log.info('Wrote prompt file', { path: promptFilePath });

// Reference the prompt file at the start, then the task
const fullTask = `First, read ${promptFilePath} for important instructions.\n\n${this.options.task}`;
Expand All @@ -231,9 +231,9 @@ class AgentProcessImpl extends EventEmitter implements AgentProcess {
const workspaceArg = workspace ? `--workspace '${workspace}'` : '';
const command = `cursor agent -p --approve-mcps --output-format stream-json ${workspaceArg} '${escapedTask}'`;

console.log(`[AgentRunner] Spawning command: ${command.slice(0, 200)}...`);
console.log(`[AgentRunner] Working directory: ${workspace}`);
console.log(`[AgentRunner] Progress file: ${progressFilePath}`);
log.info('Spawning command', { command: command.slice(0, 200) });
log.info('Working directory', { cwd: workspace });
log.info('Progress file', { path: progressFilePath });

// Use stdio: "inherit" so output goes directly to terminal for debugging
// Progress updates come from the file monitor, not stdout parsing
Expand Down Expand Up @@ -312,7 +312,7 @@ Rules:
cwd: this.options.workingDirectory || process.cwd(),
});
} catch (error) {
console.error(`Failed to remove worktree: ${error}`);
log.error('Failed to remove worktree', { error });
}
}

Expand All @@ -335,7 +335,7 @@ Rules:
try {
const event = JSON.parse(line);
// Log full event for debugging
console.log(`[Agent] JSON event:`, JSON.stringify(event, null, 2));
agentLog.debug('JSON event', { event });
this.handleEvent(event);
return;
} catch {
Expand All @@ -348,9 +348,7 @@ Rules:
}

private handleEvent(event: any): void {
console.log(
`[Agent] Event type: ${event.type}, subtype: ${event.subtype || 'none'}`,
);
agentLog.debug('Event', { type: event.type, subtype: event.subtype || 'none' });

// Only handle result events - the spawned agent handles progress updates
if (event.type === 'result') {
Expand Down
Loading