Skip to content

Commit 7a9b852

Browse files
committed
2 parents 56a5cf5 + 0274d82 commit 7a9b852

File tree

14 files changed

+200
-84
lines changed

14 files changed

+200
-84
lines changed

.env.example

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,18 @@ HTTP_MCP_PORT=9100
1616
AGENT_PORT=9200
1717
EXTENSION_PORT=9300
1818

19+
# Optional directories
20+
# RESOURCES_DIR=./resources
21+
# EXECUTION_DIR=./out/
22+
1923
# Agent Configuration
2024
MAX_SESSIONS=5
2125
SESSION_IDLE_TIMEOUT_MS=90000
2226
EVENT_GAP_TIMEOUT_MS=60000
2327

2428
BROWSEROS_BINARY=/Applications/BrowserOS.app/Contents/MacOS/BrowserOS
2529

26-
# PostHog
30+
# PostHog
2731
POSTHOG_API_KEY=
2832
POSTHOG_ENDPOINT=
2933

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "browseros-server",
3-
"version": "0.0.11",
3+
"version": "0.0.12",
44
"description": "Unified BrowserOS server with MCP and Agent support",
55
"private": true,
66
"type": "module",

packages/agent/src/agent/ClaudeSDKAgent.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -245,9 +245,7 @@ export class ClaudeSDKAgent extends BaseAgent {
245245
this.startExecution();
246246
this.abortController = new AbortController();
247247

248-
logger.info('🤖 ClaudeSDKAgent executing', {
249-
message: message.substring(0, 100),
250-
});
248+
logger.info('🤖 ClaudeSDKAgent executing', {message});
251249

252250
try {
253251
const options: any = {
@@ -329,11 +327,7 @@ export class ClaudeSDKAgent extends BaseAgent {
329327
subtype: (event as any).subtype,
330328
is_error: (event as any).is_error,
331329
num_turns: numTurns,
332-
result: (event as any).result
333-
? typeof (event as any).result === 'string'
334-
? (event as any).result.substring(0, 200)
335-
: JSON.stringify((event as any).result).substring(0, 200)
336-
: 'N/A',
330+
result: (event as any).result ?? 'N/A',
337331
});
338332
}
339333

packages/agent/src/agent/CodexSDKAgent.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ export class CodexSDKAgent extends BaseAgent {
320320
this.abortController = new AbortController();
321321

322322
logger.info('🤖 CodexSDKAgent executing', {
323-
message: message.substring(0, 100),
323+
message,
324324
});
325325

326326
try {
@@ -415,12 +415,11 @@ export class CodexSDKAgent extends BaseAgent {
415415

416416
const event = result.value;
417417

418-
// Log Codex events for debugging
419-
const eventData = JSON.stringify(event).substring(0, 100);
418+
// Log Codex events for debugging (console view truncates automatically)
420419
if (event.type === 'error' || event.type === 'turn.failed') {
421-
logger.error('Codex event', {type: event.type, data: eventData});
420+
logger.error('Codex event', event);
422421
} else {
423-
logger.debug('Codex event', {type: event.type, data: eventData});
422+
logger.debug('Codex event', event);
424423
}
425424

426425
// Update event time

packages/common/src/logger.ts

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import fs from 'node:fs';
66
import path from 'node:path';
77

88
type LogLevel = 'debug' | 'info' | 'warn' | 'error';
9+
type FormatOptions = {useColor?: boolean; truncateStrings?: boolean};
910

1011
const COLORS = {
1112
debug: '\x1b[36m',
@@ -15,6 +16,7 @@ const COLORS = {
1516
};
1617

1718
const RESET = '\x1b[0m';
19+
const CONSOLE_META_CHAR_LIMIT = 100;
1820

1921
class Logger {
2022
private level: LogLevel;
@@ -28,21 +30,45 @@ class Logger {
2830
this.logFilePath = path.join(logDir, 'browseros-server.log');
2931
}
3032

31-
private format(level: LogLevel, message: string, meta?: object): string {
33+
private format(
34+
level: LogLevel,
35+
message: string,
36+
meta?: object,
37+
{useColor = true, truncateStrings = false}: FormatOptions = {},
38+
): string {
3239
const timestamp = new Date().toISOString();
33-
const color = COLORS[level];
34-
const metaStr = meta ? `\n${JSON.stringify(meta, null, 2)}` : '';
35-
return `${color}[${timestamp}] [${level.toUpperCase()}]${RESET} ${message}${metaStr}`;
40+
const prefix = useColor
41+
? `${COLORS[level]}[${timestamp}] [${level.toUpperCase()}]${RESET}`
42+
: `[${timestamp}] [${level.toUpperCase()}]`;
43+
const metaStr = meta
44+
? `\n${this.stringifyMeta(meta, truncateStrings)}`
45+
: '';
46+
return `${prefix} ${message}${metaStr}`;
3647
}
3748

38-
private formatPlain(level: LogLevel, message: string, meta?: object): string {
39-
const timestamp = new Date().toISOString();
40-
const metaStr = meta ? `\n${JSON.stringify(meta, null, 2)}` : '';
41-
return `[${timestamp}] [${level.toUpperCase()}] ${message}${metaStr}`;
49+
private stringifyMeta(meta: object, truncateStrings: boolean): string {
50+
return JSON.stringify(
51+
meta,
52+
(key, value) => {
53+
if (
54+
truncateStrings &&
55+
typeof value === 'string' &&
56+
value.length > CONSOLE_META_CHAR_LIMIT
57+
) {
58+
const extra = value.length - CONSOLE_META_CHAR_LIMIT;
59+
return `${value.slice(0, CONSOLE_META_CHAR_LIMIT)}... (+${extra} chars)`;
60+
}
61+
return value;
62+
},
63+
2,
64+
);
4265
}
4366

4467
private log(level: LogLevel, message: string, meta?: object) {
45-
const formatted = this.format(level, message, meta);
68+
const formatted = this.format(level, message, meta, {
69+
useColor: true,
70+
truncateStrings: true,
71+
});
4672

4773
switch (level) {
4874
case 'error':
@@ -56,7 +82,10 @@ class Logger {
5682
}
5783

5884
if (this.logFilePath) {
59-
const plainFormatted = this.formatPlain(level, message, meta);
85+
const plainFormatted = this.format(level, message, meta, {
86+
useColor: false,
87+
truncateStrings: false,
88+
});
6089
try {
6190
fs.appendFileSync(this.logFilePath, plainFormatted + '\n');
6291
} catch (error) {

packages/controller-ext/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"manifest_version": 3,
33
"name": "BrowserOS Controller",
4-
"version": "1.0.0.5",
4+
"version": "1.0.0.8",
55
"description": "BrowserOS API bridge for BrowserOS Server",
66
"key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhlh9i/c2A3f0PL86hXhGPzguLIOQ+sPf3/Y8RD11gmdvoU6XqnUqv7GgBvm7SW7316uPnS58AYZY13jGtF4rFrscdda5H2CjZrtOyOycmKp2KzibJLwibXNm/JwKhZ3QEfgsW/orh1SMY2kNj62JemkWLcLyn3E1T+KTcTVyFOxiJS3hyQ+Y0/Jp1HOqGh5lYS58YYzwhId5rrJjfL7wFYtALgt2dEA2r7p4qpe+SW0QLA+ayjRAjS+yt+qitR0eWg+XgqcIk1f1KblN8/yDISssSD4LWiPofe5CmJPnqlHIuI0CpgvAFv9dvgR/w8OFkXxK5h06i6saum1xExj+IwIDAQAB",
77
"permissions": [

packages/controller-ext/src/background/BrowserOSController.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,18 @@ export class BrowserOSController {
111111
return this.wsClient.isConnected();
112112
}
113113

114+
notifyWindowFocused(windowId?: number): void {
115+
try {
116+
this.wsClient.send({type: 'focused', windowId});
117+
logger.debug('Sent focused event', {windowId});
118+
} catch (error) {
119+
logger.warn('Failed to send focused event', {
120+
windowId,
121+
error: error instanceof Error ? error.message : String(error),
122+
});
123+
}
124+
}
125+
114126
private registerActions(): void {
115127
logger.info('Registering actions...');
116128

packages/controller-ext/src/background/index.ts

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ async function getOrCreateController(): Promise<BrowserOSController> {
100100
}
101101

102102
async function shutdownController(reason: string): Promise<void> {
103-
logger.info(`[BrowserOS Controller] Shutdown requested: ${reason}`);
103+
logger.info('Controller shutdown requested', {reason});
104104

105105
if (controllerState.initPromise) {
106106
try {
@@ -138,27 +138,42 @@ function ensureControllerRunning(trigger: string): void {
138138
getOrCreateController().catch(error => {
139139
const message =
140140
error instanceof Error ? error.message : JSON.stringify(error);
141-
logger.error(
142-
`[BrowserOS Controller] Failed to start (trigger=${trigger}): ${message}`,
143-
);
141+
logger.error('Controller failed to start', {trigger, error: message});
144142
});
145143
}
146144

147-
logger.info('[BrowserOS Controller] Extension loaded');
145+
logger.info('Extension loaded');
148146

149147
chrome.runtime.onInstalled.addListener(() => {
150-
logger.info('[BrowserOS Controller] Extension installed');
148+
logger.info('Extension installed');
151149
});
152150

153151
chrome.runtime.onStartup.addListener(() => {
154-
logger.info('[BrowserOS Controller] Browser startup event');
152+
logger.info('Browser startup event');
155153
ensureControllerRunning('runtime.onStartup');
156154
});
157155

158156
// Immediately attempt to start the controller when the service worker initializes
159157
ensureControllerRunning('service-worker-init');
160158

159+
chrome.windows.onFocusChanged.addListener(windowId => {
160+
if (windowId === chrome.windows.WINDOW_ID_NONE) {
161+
return;
162+
}
163+
164+
notifyWindowFocused(windowId).catch(error => {
165+
const message =
166+
error instanceof Error ? error.message : JSON.stringify(error);
167+
logger.warn('Failed to notify focus change', {windowId, error: message});
168+
});
169+
});
170+
161171
chrome.runtime.onSuspend?.addListener(() => {
162-
logger.info('[BrowserOS Controller] Extension suspending');
172+
logger.info('Extension suspending');
163173
void shutdownController('runtime.onSuspend');
164174
});
175+
176+
async function notifyWindowFocused(windowId: number): Promise<void> {
177+
const controller = await getOrCreateController();
178+
controller.notifyWindowFocused(windowId);
179+
}

packages/controller-ext/src/config/constants.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,5 +53,5 @@ export const CONCURRENCY_CONFIG: ConcurrencyConfig = {
5353
export const LOGGING_CONFIG: LoggingConfig = {
5454
enabled: true,
5555
level: 'info',
56-
prefix: '[BrowserOS Controller]',
56+
prefix: '',
5757
};

packages/controller-ext/src/utils/Logger.ts

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,44 +14,45 @@ export class Logger {
1414
this.prefix = prefix;
1515
}
1616

17-
log(message: string, level: LogLevel = 'info'): void {
17+
log(message: string, level: LogLevel = 'info', data?: object): void {
1818
if (!LOGGING_CONFIG.enabled) return;
1919

2020
const timestamp = new Date().toISOString();
2121
const logMessage = `${this.prefix} [${timestamp}] ${message}`;
22+
const formattedData = data ? `\n${JSON.stringify(data, null, 2)}` : '';
2223

2324
switch (level) {
2425
case 'debug':
25-
if (LOGGING_CONFIG.level === 'debug') console.log(logMessage);
26+
if (LOGGING_CONFIG.level === 'debug') console.log(logMessage + formattedData);
2627
break;
2728
case 'info':
2829
if (['debug', 'info'].includes(LOGGING_CONFIG.level))
29-
console.info(logMessage);
30+
console.info(logMessage + formattedData);
3031
break;
3132
case 'warn':
3233
if (['debug', 'info', 'warn'].includes(LOGGING_CONFIG.level))
33-
console.warn(logMessage);
34+
console.warn(logMessage + formattedData);
3435
break;
3536
case 'error':
36-
console.error(logMessage);
37+
console.error(logMessage + formattedData);
3738
break;
3839
}
3940
}
4041

41-
debug(message: string): void {
42-
this.log(message, 'debug');
42+
debug(message: string, data?: object): void {
43+
this.log(message, 'debug', data);
4344
}
4445

45-
info(message: string): void {
46-
this.log(message, 'info');
46+
info(message: string, data?: object): void {
47+
this.log(message, 'info', data);
4748
}
4849

49-
warn(message: string): void {
50-
this.log(message, 'warn');
50+
warn(message: string, data?: object): void {
51+
this.log(message, 'warn', data);
5152
}
5253

53-
error(message: string): void {
54-
this.log(message, 'error');
54+
error(message: string, data?: object): void {
55+
this.log(message, 'error', data);
5556
}
5657
}
5758

0 commit comments

Comments
 (0)