@townco/core 0.0.3 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -0
- package/dist/logger.d.ts +59 -0
- package/dist/logger.js +191 -0
- package/package.json +5 -2
- package/src/logger.ts +0 -253
- package/tsconfig.json +0 -6
- /package/{src/index.ts → dist/index.d.ts} +0 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./logger.js";
|
package/dist/logger.d.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser-compatible logger
|
|
3
|
+
* Outputs structured JSON logs to console with color-coding
|
|
4
|
+
* Also captures logs to a global store for in-app viewing
|
|
5
|
+
* In Node.js environment with logsDir option, also writes to .logs/ directory
|
|
6
|
+
*/
|
|
7
|
+
export type LogLevel = "trace" | "debug" | "info" | "warn" | "error" | "fatal";
|
|
8
|
+
export interface LogEntry {
|
|
9
|
+
id: string;
|
|
10
|
+
timestamp: string;
|
|
11
|
+
level: LogLevel;
|
|
12
|
+
service: string;
|
|
13
|
+
message: string;
|
|
14
|
+
metadata?: Record<string, unknown>;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Get all captured logs
|
|
18
|
+
*/
|
|
19
|
+
export declare function getCapturedLogs(): LogEntry[];
|
|
20
|
+
/**
|
|
21
|
+
* Clear all captured logs
|
|
22
|
+
*/
|
|
23
|
+
export declare function clearCapturedLogs(): void;
|
|
24
|
+
/**
|
|
25
|
+
* Subscribe to log updates
|
|
26
|
+
*/
|
|
27
|
+
type LogSubscriber = (entry: LogEntry) => void;
|
|
28
|
+
export declare function subscribeToLogs(callback: LogSubscriber): () => void;
|
|
29
|
+
/**
|
|
30
|
+
* Configure global logs directory for file writing
|
|
31
|
+
* Must be called before creating any loggers (typically at TUI startup)
|
|
32
|
+
*/
|
|
33
|
+
export declare function configureLogsDir(logsDir: string): void;
|
|
34
|
+
export declare class Logger {
|
|
35
|
+
private service;
|
|
36
|
+
private minLevel;
|
|
37
|
+
private logFilePath?;
|
|
38
|
+
private logsDir?;
|
|
39
|
+
private writeQueue;
|
|
40
|
+
private isWriting;
|
|
41
|
+
constructor(service: string, minLevel?: LogLevel);
|
|
42
|
+
private setupFileLogging;
|
|
43
|
+
private writeToFile;
|
|
44
|
+
private shouldLog;
|
|
45
|
+
private log;
|
|
46
|
+
trace(message: string, metadata?: Record<string, unknown>): void;
|
|
47
|
+
debug(message: string, metadata?: Record<string, unknown>): void;
|
|
48
|
+
info(message: string, metadata?: Record<string, unknown>): void;
|
|
49
|
+
warn(message: string, metadata?: Record<string, unknown>): void;
|
|
50
|
+
error(message: string, metadata?: Record<string, unknown>): void;
|
|
51
|
+
fatal(message: string, metadata?: Record<string, unknown>): void;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Create a logger instance for a service
|
|
55
|
+
* @param service - Service name (e.g., "gui", "http-agent", "tui")
|
|
56
|
+
* @param minLevel - Minimum log level to display (default: "debug")
|
|
57
|
+
*/
|
|
58
|
+
export declare function createLogger(service: string, minLevel?: LogLevel): Logger;
|
|
59
|
+
export {};
|
package/dist/logger.js
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser-compatible logger
|
|
3
|
+
* Outputs structured JSON logs to console with color-coding
|
|
4
|
+
* Also captures logs to a global store for in-app viewing
|
|
5
|
+
* In Node.js environment with logsDir option, also writes to .logs/ directory
|
|
6
|
+
*/
|
|
7
|
+
// Check if running in Node.js
|
|
8
|
+
const isNode = typeof process !== "undefined" && process.versions?.node;
|
|
9
|
+
// Global logs directory configuration (set once at app startup for TUI)
|
|
10
|
+
let globalLogsDir;
|
|
11
|
+
// Global log store
|
|
12
|
+
const globalLogStore = [];
|
|
13
|
+
let logIdCounter = 0;
|
|
14
|
+
/**
|
|
15
|
+
* Get all captured logs
|
|
16
|
+
*/
|
|
17
|
+
export function getCapturedLogs() {
|
|
18
|
+
return [...globalLogStore];
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Clear all captured logs
|
|
22
|
+
*/
|
|
23
|
+
export function clearCapturedLogs() {
|
|
24
|
+
globalLogStore.length = 0;
|
|
25
|
+
}
|
|
26
|
+
const logSubscribers = new Set();
|
|
27
|
+
export function subscribeToLogs(callback) {
|
|
28
|
+
logSubscribers.add(callback);
|
|
29
|
+
return () => logSubscribers.delete(callback);
|
|
30
|
+
}
|
|
31
|
+
function notifyLogSubscribers(entry) {
|
|
32
|
+
for (const callback of logSubscribers) {
|
|
33
|
+
callback(entry);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Configure global logs directory for file writing
|
|
38
|
+
* Must be called before creating any loggers (typically at TUI startup)
|
|
39
|
+
*/
|
|
40
|
+
export function configureLogsDir(logsDir) {
|
|
41
|
+
globalLogsDir = logsDir;
|
|
42
|
+
}
|
|
43
|
+
const LOG_LEVELS = {
|
|
44
|
+
trace: 0,
|
|
45
|
+
debug: 1,
|
|
46
|
+
info: 2,
|
|
47
|
+
warn: 3,
|
|
48
|
+
error: 4,
|
|
49
|
+
fatal: 5,
|
|
50
|
+
};
|
|
51
|
+
const _LOG_COLORS = {
|
|
52
|
+
trace: "#6B7280", // gray
|
|
53
|
+
debug: "#3B82F6", // blue
|
|
54
|
+
info: "#10B981", // green
|
|
55
|
+
warn: "#F59E0B", // orange
|
|
56
|
+
error: "#EF4444", // red
|
|
57
|
+
fatal: "#DC2626", // dark red
|
|
58
|
+
};
|
|
59
|
+
const _LOG_STYLES = {
|
|
60
|
+
trace: "color: #6B7280",
|
|
61
|
+
debug: "color: #3B82F6; font-weight: bold",
|
|
62
|
+
info: "color: #10B981; font-weight: bold",
|
|
63
|
+
warn: "color: #F59E0B; font-weight: bold",
|
|
64
|
+
error: "color: #EF4444; font-weight: bold",
|
|
65
|
+
fatal: "color: #DC2626; font-weight: bold; background: #FEE2E2",
|
|
66
|
+
};
|
|
67
|
+
export class Logger {
|
|
68
|
+
service;
|
|
69
|
+
minLevel;
|
|
70
|
+
logFilePath;
|
|
71
|
+
logsDir;
|
|
72
|
+
writeQueue = [];
|
|
73
|
+
isWriting = false;
|
|
74
|
+
constructor(service, minLevel = "debug") {
|
|
75
|
+
this.service = service;
|
|
76
|
+
this.minLevel = minLevel;
|
|
77
|
+
// In production, suppress trace and debug logs
|
|
78
|
+
if (typeof process !== "undefined" &&
|
|
79
|
+
process.env?.NODE_ENV === "production") {
|
|
80
|
+
this.minLevel = "info";
|
|
81
|
+
}
|
|
82
|
+
// Note: File logging setup is done lazily in log() method
|
|
83
|
+
// This allows loggers created before configureLogsDir() to still write to files
|
|
84
|
+
}
|
|
85
|
+
setupFileLogging() {
|
|
86
|
+
if (!isNode || !globalLogsDir)
|
|
87
|
+
return;
|
|
88
|
+
try {
|
|
89
|
+
// Dynamic import for Node.js modules
|
|
90
|
+
const path = require("node:path");
|
|
91
|
+
const fs = require("node:fs");
|
|
92
|
+
this.logsDir = globalLogsDir;
|
|
93
|
+
this.logFilePath = path.join(this.logsDir, `${this.service}.log`);
|
|
94
|
+
// Create logs directory if it doesn't exist
|
|
95
|
+
if (!fs.existsSync(this.logsDir)) {
|
|
96
|
+
fs.mkdirSync(this.logsDir, { recursive: true });
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
catch (_error) {
|
|
100
|
+
// Silently fail if we can't set up file logging
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
async writeToFile(content) {
|
|
104
|
+
if (!this.logFilePath || !isNode)
|
|
105
|
+
return;
|
|
106
|
+
this.writeQueue.push(content);
|
|
107
|
+
if (this.isWriting) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
this.isWriting = true;
|
|
111
|
+
while (this.writeQueue.length > 0) {
|
|
112
|
+
const batch = this.writeQueue.splice(0, this.writeQueue.length);
|
|
113
|
+
const data = `${batch.join("\n")}\n`;
|
|
114
|
+
try {
|
|
115
|
+
// Dynamic import for Node.js modules
|
|
116
|
+
const fs = require("node:fs");
|
|
117
|
+
await fs.promises.appendFile(this.logFilePath, data, "utf-8");
|
|
118
|
+
}
|
|
119
|
+
catch (_error) {
|
|
120
|
+
// Silently fail
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
this.isWriting = false;
|
|
124
|
+
}
|
|
125
|
+
shouldLog(level) {
|
|
126
|
+
return LOG_LEVELS[level] >= LOG_LEVELS[this.minLevel];
|
|
127
|
+
}
|
|
128
|
+
log(level, message, metadata) {
|
|
129
|
+
if (!this.shouldLog(level)) {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
const entry = {
|
|
133
|
+
id: `log_${++logIdCounter}`,
|
|
134
|
+
timestamp: new Date().toISOString(),
|
|
135
|
+
level,
|
|
136
|
+
service: this.service,
|
|
137
|
+
message,
|
|
138
|
+
...(metadata && { metadata }),
|
|
139
|
+
};
|
|
140
|
+
// Store in global log store
|
|
141
|
+
globalLogStore.push(entry);
|
|
142
|
+
// Notify subscribers
|
|
143
|
+
notifyLogSubscribers(entry);
|
|
144
|
+
// Write to file in Node.js (for logs tab to read)
|
|
145
|
+
// Lazily set up file logging if globalLogsDir was configured after this logger was created
|
|
146
|
+
if (isNode && !this.logFilePath && globalLogsDir) {
|
|
147
|
+
this.setupFileLogging();
|
|
148
|
+
}
|
|
149
|
+
if (isNode && this.logFilePath) {
|
|
150
|
+
// Write as JSON without the id field (to match expected format)
|
|
151
|
+
const fileEntry = {
|
|
152
|
+
timestamp: entry.timestamp,
|
|
153
|
+
level: entry.level,
|
|
154
|
+
service: entry.service,
|
|
155
|
+
message: entry.message,
|
|
156
|
+
...(entry.metadata && { metadata: entry.metadata }),
|
|
157
|
+
};
|
|
158
|
+
this.writeToFile(JSON.stringify(fileEntry)).catch(() => {
|
|
159
|
+
// Silently fail
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
// No console output - logs are only captured and displayed in UI
|
|
163
|
+
// This prevents logs from polluting stdout/stderr in TUI mode
|
|
164
|
+
}
|
|
165
|
+
trace(message, metadata) {
|
|
166
|
+
this.log("trace", message, metadata);
|
|
167
|
+
}
|
|
168
|
+
debug(message, metadata) {
|
|
169
|
+
this.log("debug", message, metadata);
|
|
170
|
+
}
|
|
171
|
+
info(message, metadata) {
|
|
172
|
+
this.log("info", message, metadata);
|
|
173
|
+
}
|
|
174
|
+
warn(message, metadata) {
|
|
175
|
+
this.log("warn", message, metadata);
|
|
176
|
+
}
|
|
177
|
+
error(message, metadata) {
|
|
178
|
+
this.log("error", message, metadata);
|
|
179
|
+
}
|
|
180
|
+
fatal(message, metadata) {
|
|
181
|
+
this.log("fatal", message, metadata);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Create a logger instance for a service
|
|
186
|
+
* @param service - Service name (e.g., "gui", "http-agent", "tui")
|
|
187
|
+
* @param minLevel - Minimum log level to display (default: "debug")
|
|
188
|
+
*/
|
|
189
|
+
export function createLogger(service, minLevel = "debug") {
|
|
190
|
+
return new Logger(service, minLevel);
|
|
191
|
+
}
|
package/package.json
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@townco/core",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.5",
|
|
5
5
|
"description": "core",
|
|
6
6
|
"license": "UNLICENSED",
|
|
7
7
|
"main": "./dist/index.js",
|
|
8
8
|
"types": "./dist/index.d.ts",
|
|
9
9
|
"repository": "github:townco/town",
|
|
10
|
+
"files": [
|
|
11
|
+
"dist"
|
|
12
|
+
],
|
|
10
13
|
"exports": {
|
|
11
14
|
".": {
|
|
12
15
|
"import": "./dist/index.js",
|
|
@@ -15,7 +18,7 @@
|
|
|
15
18
|
},
|
|
16
19
|
"devDependencies": {
|
|
17
20
|
"typescript": "^5.9.3",
|
|
18
|
-
"@townco/tsconfig": "0.1.
|
|
21
|
+
"@townco/tsconfig": "0.1.24"
|
|
19
22
|
},
|
|
20
23
|
"scripts": {
|
|
21
24
|
"build": "tsc",
|
package/src/logger.ts
DELETED
|
@@ -1,253 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Browser-compatible logger
|
|
3
|
-
* Outputs structured JSON logs to console with color-coding
|
|
4
|
-
* Also captures logs to a global store for in-app viewing
|
|
5
|
-
* In Node.js environment with logsDir option, also writes to .logs/ directory
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
export type LogLevel = "trace" | "debug" | "info" | "warn" | "error" | "fatal";
|
|
9
|
-
|
|
10
|
-
// Check if running in Node.js
|
|
11
|
-
const isNode = typeof process !== "undefined" && process.versions?.node;
|
|
12
|
-
|
|
13
|
-
// Global logs directory configuration (set once at app startup for TUI)
|
|
14
|
-
let globalLogsDir: string | undefined;
|
|
15
|
-
|
|
16
|
-
export interface LogEntry {
|
|
17
|
-
id: string;
|
|
18
|
-
timestamp: string;
|
|
19
|
-
level: LogLevel;
|
|
20
|
-
service: string;
|
|
21
|
-
message: string;
|
|
22
|
-
metadata?: Record<string, unknown>;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// Global log store
|
|
26
|
-
const globalLogStore: LogEntry[] = [];
|
|
27
|
-
let logIdCounter = 0;
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Get all captured logs
|
|
31
|
-
*/
|
|
32
|
-
export function getCapturedLogs(): LogEntry[] {
|
|
33
|
-
return [...globalLogStore];
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Clear all captured logs
|
|
38
|
-
*/
|
|
39
|
-
export function clearCapturedLogs(): void {
|
|
40
|
-
globalLogStore.length = 0;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Subscribe to log updates
|
|
45
|
-
*/
|
|
46
|
-
type LogSubscriber = (entry: LogEntry) => void;
|
|
47
|
-
const logSubscribers: Set<LogSubscriber> = new Set();
|
|
48
|
-
|
|
49
|
-
export function subscribeToLogs(callback: LogSubscriber): () => void {
|
|
50
|
-
logSubscribers.add(callback);
|
|
51
|
-
return () => logSubscribers.delete(callback);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
function notifyLogSubscribers(entry: LogEntry): void {
|
|
55
|
-
for (const callback of logSubscribers) {
|
|
56
|
-
callback(entry);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Configure global logs directory for file writing
|
|
62
|
-
* Must be called before creating any loggers (typically at TUI startup)
|
|
63
|
-
*/
|
|
64
|
-
export function configureLogsDir(logsDir: string): void {
|
|
65
|
-
globalLogsDir = logsDir;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const LOG_LEVELS: Record<LogLevel, number> = {
|
|
69
|
-
trace: 0,
|
|
70
|
-
debug: 1,
|
|
71
|
-
info: 2,
|
|
72
|
-
warn: 3,
|
|
73
|
-
error: 4,
|
|
74
|
-
fatal: 5,
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
const _LOG_COLORS: Record<LogLevel, string> = {
|
|
78
|
-
trace: "#6B7280", // gray
|
|
79
|
-
debug: "#3B82F6", // blue
|
|
80
|
-
info: "#10B981", // green
|
|
81
|
-
warn: "#F59E0B", // orange
|
|
82
|
-
error: "#EF4444", // red
|
|
83
|
-
fatal: "#DC2626", // dark red
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
const _LOG_STYLES: Record<LogLevel, string> = {
|
|
87
|
-
trace: "color: #6B7280",
|
|
88
|
-
debug: "color: #3B82F6; font-weight: bold",
|
|
89
|
-
info: "color: #10B981; font-weight: bold",
|
|
90
|
-
warn: "color: #F59E0B; font-weight: bold",
|
|
91
|
-
error: "color: #EF4444; font-weight: bold",
|
|
92
|
-
fatal: "color: #DC2626; font-weight: bold; background: #FEE2E2",
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
export class Logger {
|
|
96
|
-
private service: string;
|
|
97
|
-
private minLevel: LogLevel;
|
|
98
|
-
private logFilePath?: string;
|
|
99
|
-
private logsDir?: string;
|
|
100
|
-
private writeQueue: string[] = [];
|
|
101
|
-
private isWriting = false;
|
|
102
|
-
|
|
103
|
-
constructor(service: string, minLevel: LogLevel = "debug") {
|
|
104
|
-
this.service = service;
|
|
105
|
-
this.minLevel = minLevel;
|
|
106
|
-
|
|
107
|
-
// In production, suppress trace and debug logs
|
|
108
|
-
if (
|
|
109
|
-
typeof process !== "undefined" &&
|
|
110
|
-
process.env?.NODE_ENV === "production"
|
|
111
|
-
) {
|
|
112
|
-
this.minLevel = "info";
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
// Note: File logging setup is done lazily in log() method
|
|
116
|
-
// This allows loggers created before configureLogsDir() to still write to files
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
private setupFileLogging(): void {
|
|
120
|
-
if (!isNode || !globalLogsDir) return;
|
|
121
|
-
|
|
122
|
-
try {
|
|
123
|
-
// Dynamic import for Node.js modules
|
|
124
|
-
const path = require("node:path");
|
|
125
|
-
const fs = require("node:fs");
|
|
126
|
-
|
|
127
|
-
this.logsDir = globalLogsDir;
|
|
128
|
-
this.logFilePath = path.join(this.logsDir, `${this.service}.log`);
|
|
129
|
-
|
|
130
|
-
// Create logs directory if it doesn't exist
|
|
131
|
-
if (!fs.existsSync(this.logsDir)) {
|
|
132
|
-
fs.mkdirSync(this.logsDir, { recursive: true });
|
|
133
|
-
}
|
|
134
|
-
} catch (_error) {
|
|
135
|
-
// Silently fail if we can't set up file logging
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
private async writeToFile(content: string): Promise<void> {
|
|
140
|
-
if (!this.logFilePath || !isNode) return;
|
|
141
|
-
|
|
142
|
-
this.writeQueue.push(content);
|
|
143
|
-
|
|
144
|
-
if (this.isWriting) {
|
|
145
|
-
return;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
this.isWriting = true;
|
|
149
|
-
|
|
150
|
-
while (this.writeQueue.length > 0) {
|
|
151
|
-
const batch = this.writeQueue.splice(0, this.writeQueue.length);
|
|
152
|
-
const data = `${batch.join("\n")}\n`;
|
|
153
|
-
|
|
154
|
-
try {
|
|
155
|
-
// Dynamic import for Node.js modules
|
|
156
|
-
const fs = require("node:fs");
|
|
157
|
-
await fs.promises.appendFile(this.logFilePath, data, "utf-8");
|
|
158
|
-
} catch (_error) {
|
|
159
|
-
// Silently fail
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
this.isWriting = false;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
private shouldLog(level: LogLevel): boolean {
|
|
167
|
-
return LOG_LEVELS[level] >= LOG_LEVELS[this.minLevel];
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
private log(
|
|
171
|
-
level: LogLevel,
|
|
172
|
-
message: string,
|
|
173
|
-
metadata?: Record<string, unknown>,
|
|
174
|
-
): void {
|
|
175
|
-
if (!this.shouldLog(level)) {
|
|
176
|
-
return;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
const entry: LogEntry = {
|
|
180
|
-
id: `log_${++logIdCounter}`,
|
|
181
|
-
timestamp: new Date().toISOString(),
|
|
182
|
-
level,
|
|
183
|
-
service: this.service,
|
|
184
|
-
message,
|
|
185
|
-
...(metadata && { metadata }),
|
|
186
|
-
};
|
|
187
|
-
|
|
188
|
-
// Store in global log store
|
|
189
|
-
globalLogStore.push(entry);
|
|
190
|
-
|
|
191
|
-
// Notify subscribers
|
|
192
|
-
notifyLogSubscribers(entry);
|
|
193
|
-
|
|
194
|
-
// Write to file in Node.js (for logs tab to read)
|
|
195
|
-
// Lazily set up file logging if globalLogsDir was configured after this logger was created
|
|
196
|
-
if (isNode && !this.logFilePath && globalLogsDir) {
|
|
197
|
-
this.setupFileLogging();
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
if (isNode && this.logFilePath) {
|
|
201
|
-
// Write as JSON without the id field (to match expected format)
|
|
202
|
-
const fileEntry = {
|
|
203
|
-
timestamp: entry.timestamp,
|
|
204
|
-
level: entry.level,
|
|
205
|
-
service: entry.service,
|
|
206
|
-
message: entry.message,
|
|
207
|
-
...(entry.metadata && { metadata: entry.metadata }),
|
|
208
|
-
};
|
|
209
|
-
this.writeToFile(JSON.stringify(fileEntry)).catch(() => {
|
|
210
|
-
// Silently fail
|
|
211
|
-
});
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// No console output - logs are only captured and displayed in UI
|
|
215
|
-
// This prevents logs from polluting stdout/stderr in TUI mode
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
trace(message: string, metadata?: Record<string, unknown>): void {
|
|
219
|
-
this.log("trace", message, metadata);
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
debug(message: string, metadata?: Record<string, unknown>): void {
|
|
223
|
-
this.log("debug", message, metadata);
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
info(message: string, metadata?: Record<string, unknown>): void {
|
|
227
|
-
this.log("info", message, metadata);
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
warn(message: string, metadata?: Record<string, unknown>): void {
|
|
231
|
-
this.log("warn", message, metadata);
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
error(message: string, metadata?: Record<string, unknown>): void {
|
|
235
|
-
this.log("error", message, metadata);
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
fatal(message: string, metadata?: Record<string, unknown>): void {
|
|
239
|
-
this.log("fatal", message, metadata);
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
/**
|
|
244
|
-
* Create a logger instance for a service
|
|
245
|
-
* @param service - Service name (e.g., "gui", "http-agent", "tui")
|
|
246
|
-
* @param minLevel - Minimum log level to display (default: "debug")
|
|
247
|
-
*/
|
|
248
|
-
export function createLogger(
|
|
249
|
-
service: string,
|
|
250
|
-
minLevel: LogLevel = "debug",
|
|
251
|
-
): Logger {
|
|
252
|
-
return new Logger(service, minLevel);
|
|
253
|
-
}
|
package/tsconfig.json
DELETED
|
File without changes
|