Skip to content

Commit 22110fa

Browse files
committed
forward logs to main and renderer
1 parent ba9668d commit 22110fa

File tree

8 files changed

+75
-26
lines changed

8 files changed

+75
-26
lines changed

apps/array/src/main/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
type MenuItemConstructorOptions,
1111
shell,
1212
} from "electron";
13+
import "./lib/logger";
1314
import { ANALYTICS_EVENTS } from "../types/analytics.js";
1415
import { registerAgentIpc, type TaskController } from "./services/agent.js";
1516
import { registerFoldersIpc } from "./services/folders.js";

apps/array/src/main/lib/logger.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import log from "electron-log/main";
22

3+
// Initialize IPC transport to forward main process logs to renderer dev tools
4+
log.initialize();
5+
36
log.transports.file.level = "info";
4-
log.transports.console.level = "debug";
7+
log.transports.console.level = "info";
58

69
export const logger = {
710
info: (message: string, ...args: unknown[]) => log.info(message, ...args),

apps/array/src/main/services/agent.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { randomUUID } from "node:crypto";
22
import { mkdirSync, rmSync, symlinkSync } from "node:fs";
33
import { tmpdir } from "node:os";
44
import { join } from "node:path";
5-
import { Agent, PermissionMode } from "@posthog/agent";
5+
import { Agent, type OnLogCallback, PermissionMode } from "@posthog/agent";
66
import {
77
app,
88
type BrowserWindow,
@@ -13,6 +13,15 @@ import { logger } from "../lib/logger";
1313

1414
const log = logger.scope("agent");
1515

16+
const onAgentLog: OnLogCallback = (level, scope, message, data) => {
17+
const scopedLog = logger.scope(scope);
18+
if (data !== undefined) {
19+
scopedLog[level](message, data);
20+
} else {
21+
scopedLog[level](message);
22+
}
23+
};
24+
1625
interface AgentStartParams {
1726
taskId: string;
1827
repoPath: string;
@@ -146,6 +155,7 @@ export function registerAgentIpc(
146155
posthogApiUrl: apiHost,
147156
posthogProjectId: projectId,
148157
debug: true,
158+
onLog: onAgentLog,
149159
});
150160

151161
const controllerEntry: TaskController = {

apps/array/src/renderer/lib/logger.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import log from "electron-log/renderer";
22

3+
// Ensure logs appear in dev tools console
4+
log.transports.console.level = "debug";
5+
36
export const logger = {
47
info: (message: string, ...args: unknown[]) => log.info(message, ...args),
58
warn: (message: string, ...args: unknown[]) => log.warn(message, ...args),

packages/agent/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ export type {
3333
AgentConfig,
3434
AgentEvent,
3535
ExecutionResult,
36+
LogLevel as LogLevelType,
3637
McpServerConfig,
38+
OnLogCallback,
3739
ResearchEvaluation,
3840
SupportingFile,
3941
Task,

packages/agent/src/agent.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,11 @@ export class Agent {
6565
...defaultMcpServers,
6666
...config.mcpServers,
6767
};
68-
this.logger = new Logger({ debug: this.debug, prefix: "[PostHog Agent]" });
68+
this.logger = new Logger({
69+
debug: this.debug,
70+
prefix: "[PostHog Agent]",
71+
onLog: config.onLog,
72+
});
6973
this.taskManager = new TaskManager();
7074
// Hardcode Claude adapter for now - extensible for other providers later
7175
this.adapter = new ClaudeAdapter();

packages/agent/src/types.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,15 @@ export type McpServerConfig =
337337
instance?: any;
338338
};
339339

340+
export type LogLevel = "debug" | "info" | "warn" | "error";
341+
342+
export type OnLogCallback = (
343+
level: LogLevel,
344+
scope: string,
345+
message: string,
346+
data?: unknown,
347+
) => void;
348+
340349
export interface AgentConfig {
341350
workingDirectory?: string;
342351
onEvent?: (event: AgentEvent) => void;
@@ -356,6 +365,7 @@ export interface AgentConfig {
356365

357366
// Logging configuration
358367
debug?: boolean;
368+
onLog?: OnLogCallback;
359369

360370
// Fine-grained permission control for direct run() calls
361371
// See: https://docs.claude.com/en/api/agent-sdk/permissions

packages/agent/src/utils/logger.ts

Lines changed: 39 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
import type { LogLevel as LogLevelType, OnLogCallback } from "../types.js";
2+
13
/**
2-
* Simple logger utility with configurable debug mode
4+
* Simple logger utility with configurable debug mode and external log forwarding
35
*/
46
export enum LogLevel {
57
ERROR = 0,
@@ -11,28 +13,38 @@ export enum LogLevel {
1113
export interface LoggerConfig {
1214
debug?: boolean;
1315
prefix?: string;
16+
scope?: string;
17+
onLog?: OnLogCallback;
1418
}
1519

1620
export class Logger {
1721
private debugEnabled: boolean;
1822
private prefix: string;
23+
private scope: string;
24+
private onLog?: OnLogCallback;
1925

2026
constructor(config: LoggerConfig = {}) {
2127
this.debugEnabled = config.debug ?? false;
2228
this.prefix = config.prefix ?? "[PostHog Agent]";
29+
this.scope = config.scope ?? "agent";
30+
this.onLog = config.onLog;
2331
}
2432

2533
setDebug(enabled: boolean) {
2634
this.debugEnabled = enabled;
2735
}
2836

37+
setOnLog(onLog: OnLogCallback | undefined) {
38+
this.onLog = onLog;
39+
}
40+
2941
private formatMessage(
3042
level: string,
3143
message: string,
3244
data?: unknown,
3345
): string {
3446
const timestamp = new Date().toISOString();
35-
const base = `${timestamp} ${this.prefix} ${level} ${message}`;
47+
const base = `${timestamp} ${this.prefix} [${level}] ${message}`;
3648

3749
if (data !== undefined) {
3850
return `${base} ${JSON.stringify(data, null, 2)}`;
@@ -41,45 +53,49 @@ export class Logger {
4153
return base;
4254
}
4355

44-
error(message: string, error?: Error | unknown) {
45-
// Always log errors
46-
if (error instanceof Error) {
47-
console.error(
48-
this.formatMessage("[ERROR]", message, {
49-
message: error.message,
50-
stack: error.stack,
51-
}),
52-
);
53-
} else {
54-
console.error(this.formatMessage("[ERROR]", message, error));
56+
private emitLog(level: LogLevelType, message: string, data?: unknown) {
57+
if (this.onLog) {
58+
this.onLog(level, this.scope, message, data);
59+
return;
60+
}
61+
62+
const shouldLog = this.debugEnabled || level === "error";
63+
64+
if (shouldLog) {
65+
console[level](this.formatMessage(level.toLowerCase(), message, data));
5566
}
5667
}
5768

69+
error(message: string, error?: Error | unknown) {
70+
const data =
71+
error instanceof Error
72+
? { message: error.message, stack: error.stack }
73+
: error;
74+
75+
this.emitLog("error", message, data);
76+
}
77+
5878
warn(message: string, data?: unknown) {
59-
if (this.debugEnabled) {
60-
console.warn(this.formatMessage("[WARN]", message, data));
61-
}
79+
this.emitLog("warn", message, data);
6280
}
6381

6482
info(message: string, data?: unknown) {
65-
if (this.debugEnabled) {
66-
console.log(this.formatMessage("[INFO]", message, data));
67-
}
83+
this.emitLog("info", message, data);
6884
}
6985

7086
debug(message: string, data?: unknown) {
71-
if (this.debugEnabled) {
72-
console.log(this.formatMessage("[DEBUG]", message, data));
73-
}
87+
this.emitLog("debug", message, data);
7488
}
7589

7690
/**
77-
* Create a child logger with additional prefix
91+
* Create a child logger with additional prefix and scope
7892
*/
7993
child(childPrefix: string): Logger {
8094
return new Logger({
8195
debug: this.debugEnabled,
8296
prefix: `${this.prefix} [${childPrefix}]`,
97+
scope: `${this.scope}:${childPrefix}`,
98+
onLog: this.onLog,
8399
});
84100
}
85101
}

0 commit comments

Comments
 (0)