@vybestack/llxprt-code-core 0.1.22 → 0.1.23
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/src/config/config.d.ts +14 -1
- package/dist/src/config/config.js +23 -3
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/core/client.js +2 -2
- package/dist/src/core/client.js.map +1 -1
- package/dist/src/core/coreToolScheduler.d.ts +2 -1
- package/dist/src/core/coreToolScheduler.js +19 -0
- package/dist/src/core/coreToolScheduler.js.map +1 -1
- package/dist/src/core/geminiChat.js +28 -13
- package/dist/src/core/geminiChat.js.map +1 -1
- package/dist/src/core/loggingContentGenerator.d.ts +1 -5
- package/dist/src/core/loggingContentGenerator.js +4 -6
- package/dist/src/core/loggingContentGenerator.js.map +1 -1
- package/dist/src/core/nonInteractiveToolExecutor.d.ts +2 -2
- package/dist/src/core/nonInteractiveToolExecutor.js +13 -9
- package/dist/src/core/nonInteractiveToolExecutor.js.map +1 -1
- package/dist/src/core/subagent.js +5 -5
- package/dist/src/core/subagent.js.map +1 -1
- package/dist/src/debug/ConfigurationManager.d.ts +28 -0
- package/dist/src/debug/ConfigurationManager.js +211 -0
- package/dist/src/debug/ConfigurationManager.js.map +1 -0
- package/dist/src/debug/DebugLogger.d.ts +26 -0
- package/dist/src/debug/DebugLogger.js +230 -0
- package/dist/src/debug/DebugLogger.js.map +1 -0
- package/dist/src/debug/FileOutput.d.ts +23 -0
- package/dist/src/debug/FileOutput.js +144 -0
- package/dist/src/debug/FileOutput.js.map +1 -0
- package/dist/src/debug/MockConfigurationManager.d.ts +28 -0
- package/dist/src/debug/MockConfigurationManager.js +45 -0
- package/dist/src/debug/MockConfigurationManager.js.map +1 -0
- package/dist/src/debug/MockFileOutput.d.ts +20 -0
- package/dist/src/debug/MockFileOutput.js +25 -0
- package/dist/src/debug/MockFileOutput.js.map +1 -0
- package/dist/src/debug/index.d.ts +8 -0
- package/dist/src/debug/index.js +9 -0
- package/dist/src/debug/index.js.map +1 -0
- package/dist/src/debug/types.d.ts +23 -0
- package/dist/src/debug/types.js +2 -0
- package/dist/src/debug/types.js.map +1 -0
- package/dist/src/ide/ide-client.d.ts +4 -0
- package/dist/src/ide/ide-client.js +41 -2
- package/dist/src/ide/ide-client.js.map +1 -1
- package/dist/src/ide/ide-installer.js +17 -4
- package/dist/src/ide/ide-installer.js.map +1 -1
- package/dist/src/ide/process-utils.d.ts +10 -5
- package/dist/src/ide/process-utils.js +113 -30
- package/dist/src/ide/process-utils.js.map +1 -1
- package/dist/src/index.d.ts +5 -0
- package/dist/src/index.js +4 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/prompt-config/defaults/core.md +34 -230
- package/dist/src/prompt-config/defaults/tools/read-file.md +1 -1
- package/dist/src/providers/BaseProvider.js +13 -2
- package/dist/src/providers/BaseProvider.js.map +1 -1
- package/dist/src/providers/anthropic/AnthropicProvider.d.ts +1 -0
- package/dist/src/providers/anthropic/AnthropicProvider.js +20 -31
- package/dist/src/providers/anthropic/AnthropicProvider.js.map +1 -1
- package/dist/src/providers/gemini/GeminiProvider.d.ts +1 -0
- package/dist/src/providers/gemini/GeminiProvider.js +23 -50
- package/dist/src/providers/gemini/GeminiProvider.js.map +1 -1
- package/dist/src/providers/openai/OpenAIProvider.d.ts +9 -0
- package/dist/src/providers/openai/OpenAIProvider.js +502 -129
- package/dist/src/providers/openai/OpenAIProvider.js.map +1 -1
- package/dist/src/providers/openai/buildResponsesRequest.js +9 -6
- package/dist/src/providers/openai/buildResponsesRequest.js.map +1 -1
- package/dist/src/providers/openai/getOpenAIProviderInfo.js +8 -3
- package/dist/src/providers/openai/getOpenAIProviderInfo.js.map +1 -1
- package/dist/src/providers/openai/parseResponsesStream.js +13 -4
- package/dist/src/providers/openai/parseResponsesStream.js.map +1 -1
- package/dist/src/providers/openai/syntheticToolResponses.d.ts +0 -9
- package/dist/src/providers/openai/syntheticToolResponses.js +87 -16
- package/dist/src/providers/openai/syntheticToolResponses.js.map +1 -1
- package/dist/src/services/fileSystemService.d.ts +31 -0
- package/dist/src/services/fileSystemService.js +18 -0
- package/dist/src/services/fileSystemService.js.map +1 -0
- package/dist/src/services/loopDetectionService.d.ts +5 -0
- package/dist/src/services/loopDetectionService.js +89 -1
- package/dist/src/services/loopDetectionService.js.map +1 -1
- package/dist/src/services/shellExecutionService.d.ts +8 -6
- package/dist/src/services/shellExecutionService.js +297 -133
- package/dist/src/services/shellExecutionService.js.map +1 -1
- package/dist/src/telemetry/loggers.js +1 -1
- package/dist/src/telemetry/loggers.js.map +1 -1
- package/dist/src/telemetry/metrics.d.ts +1 -1
- package/dist/src/telemetry/metrics.js +2 -1
- package/dist/src/telemetry/metrics.js.map +1 -1
- package/dist/src/telemetry/sdk.js +3 -3
- package/dist/src/telemetry/sdk.js.map +1 -1
- package/dist/src/telemetry/types.d.ts +1 -0
- package/dist/src/telemetry/types.js +20 -0
- package/dist/src/telemetry/types.js.map +1 -1
- package/dist/src/telemetry/uiTelemetry.d.ts +4 -0
- package/dist/src/telemetry/uiTelemetry.js +16 -1
- package/dist/src/telemetry/uiTelemetry.js.map +1 -1
- package/dist/src/test-utils/tools.d.ts +8 -2
- package/dist/src/test-utils/tools.js +2 -3
- package/dist/src/test-utils/tools.js.map +1 -1
- package/dist/src/tools/ToolFormatter.d.ts +1 -0
- package/dist/src/tools/ToolFormatter.js +90 -9
- package/dist/src/tools/ToolFormatter.js.map +1 -1
- package/dist/src/tools/edit.d.ts +1 -1
- package/dist/src/tools/edit.js +15 -9
- package/dist/src/tools/edit.js.map +1 -1
- package/dist/src/tools/glob.d.ts +1 -1
- package/dist/src/tools/glob.js +8 -8
- package/dist/src/tools/glob.js.map +1 -1
- package/dist/src/tools/grep.d.ts +1 -1
- package/dist/src/tools/grep.js +1 -6
- package/dist/src/tools/grep.js.map +1 -1
- package/dist/src/tools/ls.d.ts +1 -1
- package/dist/src/tools/ls.js +1 -6
- package/dist/src/tools/ls.js.map +1 -1
- package/dist/src/tools/mcp-client-manager.d.ts +38 -0
- package/dist/src/tools/mcp-client-manager.js +74 -0
- package/dist/src/tools/mcp-client-manager.js.map +1 -0
- package/dist/src/tools/mcp-client.d.ts +43 -0
- package/dist/src/tools/mcp-client.js +117 -1
- package/dist/src/tools/mcp-client.js.map +1 -1
- package/dist/src/tools/memoryTool.d.ts +1 -1
- package/dist/src/tools/memoryTool.js +1 -6
- package/dist/src/tools/memoryTool.js.map +1 -1
- package/dist/src/tools/read-file.d.ts +1 -1
- package/dist/src/tools/read-file.js +5 -7
- package/dist/src/tools/read-file.js.map +1 -1
- package/dist/src/tools/read-many-files.d.ts +0 -1
- package/dist/src/tools/read-many-files.js +16 -11
- package/dist/src/tools/read-many-files.js.map +1 -1
- package/dist/src/tools/shell.d.ts +1 -1
- package/dist/src/tools/shell.js +32 -28
- package/dist/src/tools/shell.js.map +1 -1
- package/dist/src/tools/tool-registry.d.ts +5 -0
- package/dist/src/tools/tool-registry.js +13 -4
- package/dist/src/tools/tool-registry.js.map +1 -1
- package/dist/src/tools/tools.d.ts +3 -1
- package/dist/src/tools/tools.js +12 -0
- package/dist/src/tools/tools.js.map +1 -1
- package/dist/src/tools/web-fetch.d.ts +1 -1
- package/dist/src/tools/web-fetch.js +1 -6
- package/dist/src/tools/web-fetch.js.map +1 -1
- package/dist/src/tools/web-search.d.ts +6 -1
- package/dist/src/tools/web-search.js +6 -6
- package/dist/src/tools/web-search.js.map +1 -1
- package/dist/src/tools/write-file.d.ts +1 -1
- package/dist/src/tools/write-file.js +7 -8
- package/dist/src/tools/write-file.js.map +1 -1
- package/dist/src/utils/environmentContext.js +2 -2
- package/dist/src/utils/environmentContext.js.map +1 -1
- package/dist/src/utils/errorReporting.js +1 -1
- package/dist/src/utils/fileUtils.d.ts +2 -1
- package/dist/src/utils/fileUtils.js +3 -3
- package/dist/src/utils/fileUtils.js.map +1 -1
- package/dist/src/utils/getPty.d.ts +19 -0
- package/dist/src/utils/getPty.js +23 -0
- package/dist/src/utils/getPty.js.map +1 -0
- package/dist/src/utils/user_account.js +58 -53
- package/dist/src/utils/user_account.js.map +1 -1
- package/package.json +22 -7
@@ -0,0 +1,211 @@
|
|
1
|
+
/**
|
2
|
+
* @plan:PLAN-20250120-DEBUGLOGGING.P08
|
3
|
+
* @requirement REQ-003,REQ-007
|
4
|
+
*/
|
5
|
+
import * as fs from 'fs';
|
6
|
+
import * as path from 'path';
|
7
|
+
import * as os from 'os';
|
8
|
+
import { LLXPRT_DIR } from '../utils/paths.js';
|
9
|
+
export class ConfigurationManager {
|
10
|
+
// Line 11: PRIVATE static instance: ConfigurationManager
|
11
|
+
static instance;
|
12
|
+
// Line 12-18: Private configuration properties
|
13
|
+
defaultConfig;
|
14
|
+
projectConfig = null;
|
15
|
+
userConfig = null;
|
16
|
+
envConfig = null;
|
17
|
+
cliConfig = null;
|
18
|
+
ephemeralConfig = null;
|
19
|
+
mergedConfig;
|
20
|
+
listeners = new Set();
|
21
|
+
// Line 21-26: Singleton getInstance()
|
22
|
+
static getInstance() {
|
23
|
+
if (!ConfigurationManager.instance) {
|
24
|
+
ConfigurationManager.instance = new ConfigurationManager();
|
25
|
+
}
|
26
|
+
return ConfigurationManager.instance;
|
27
|
+
}
|
28
|
+
// Line 28-40: Constructor with default config
|
29
|
+
constructor() {
|
30
|
+
this.defaultConfig = {
|
31
|
+
enabled: false,
|
32
|
+
namespaces: [],
|
33
|
+
level: 'info',
|
34
|
+
output: { target: 'file', directory: `~/${LLXPRT_DIR}/debug` },
|
35
|
+
lazyEvaluation: true,
|
36
|
+
redactPatterns: ['apiKey', 'token', 'password'],
|
37
|
+
};
|
38
|
+
this.listeners = new Set();
|
39
|
+
this.loadConfigurations();
|
40
|
+
this.mergeConfigurations();
|
41
|
+
}
|
42
|
+
// Line 42-46: Load all configurations
|
43
|
+
loadConfigurations() {
|
44
|
+
this.loadEnvironmentConfig();
|
45
|
+
this.loadUserConfig();
|
46
|
+
this.loadProjectConfig();
|
47
|
+
}
|
48
|
+
// Line 47-64: Load environment config (support DEBUG and LLXPRT_DEBUG)
|
49
|
+
loadEnvironmentConfig() {
|
50
|
+
if (process.env.DEBUG) {
|
51
|
+
const namespaces = this.parseDebugEnv(process.env.DEBUG);
|
52
|
+
// Only enable if DEBUG contains llxprt namespaces
|
53
|
+
const llxprtNamespaces = namespaces.filter((ns) => ns.startsWith('llxprt') || ns === '*');
|
54
|
+
if (llxprtNamespaces.length > 0) {
|
55
|
+
this.envConfig = {
|
56
|
+
enabled: true,
|
57
|
+
namespaces: llxprtNamespaces,
|
58
|
+
};
|
59
|
+
}
|
60
|
+
}
|
61
|
+
if (process.env.LLXPRT_DEBUG) {
|
62
|
+
const namespaces = this.parseDebugEnv(process.env.LLXPRT_DEBUG);
|
63
|
+
this.envConfig = {
|
64
|
+
enabled: true,
|
65
|
+
namespaces,
|
66
|
+
};
|
67
|
+
}
|
68
|
+
// Support other LLXPRT environment variables
|
69
|
+
if (process.env.DEBUG_ENABLED) {
|
70
|
+
this.envConfig = {
|
71
|
+
...this.envConfig,
|
72
|
+
enabled: process.env.DEBUG_ENABLED === 'true',
|
73
|
+
};
|
74
|
+
}
|
75
|
+
if (process.env.DEBUG_LEVEL) {
|
76
|
+
this.envConfig = { ...this.envConfig, level: process.env.DEBUG_LEVEL };
|
77
|
+
}
|
78
|
+
}
|
79
|
+
// Line 66-79: Load user config from ~/.llxprt/settings.json
|
80
|
+
loadUserConfig() {
|
81
|
+
try {
|
82
|
+
const homeDir = os.homedir();
|
83
|
+
if (!homeDir) {
|
84
|
+
// In test environments, os.homedir() might not be available
|
85
|
+
return;
|
86
|
+
}
|
87
|
+
const configPath = path.join(homeDir, LLXPRT_DIR, 'settings.json');
|
88
|
+
if (fs.existsSync(configPath)) {
|
89
|
+
try {
|
90
|
+
const content = fs.readFileSync(configPath, 'utf8');
|
91
|
+
const parsed = JSON.parse(content);
|
92
|
+
if (parsed.debug) {
|
93
|
+
this.userConfig = parsed.debug;
|
94
|
+
}
|
95
|
+
}
|
96
|
+
catch (error) {
|
97
|
+
console.warn('Failed to load user config:', error);
|
98
|
+
}
|
99
|
+
}
|
100
|
+
}
|
101
|
+
catch (_error) {
|
102
|
+
// Silently skip if we can't determine home directory (e.g., in tests)
|
103
|
+
// This allows the debug system to work with default config
|
104
|
+
}
|
105
|
+
}
|
106
|
+
// Line 81-94: Load project config from .llxprt/config.json
|
107
|
+
loadProjectConfig() {
|
108
|
+
try {
|
109
|
+
const cwd = process.cwd();
|
110
|
+
if (!cwd) {
|
111
|
+
return;
|
112
|
+
}
|
113
|
+
const configPath = path.join(cwd, LLXPRT_DIR, 'config.json');
|
114
|
+
if (fs.existsSync(configPath)) {
|
115
|
+
try {
|
116
|
+
const content = fs.readFileSync(configPath, 'utf8');
|
117
|
+
const parsed = JSON.parse(content);
|
118
|
+
if (parsed.debug) {
|
119
|
+
this.projectConfig = parsed.debug;
|
120
|
+
}
|
121
|
+
}
|
122
|
+
catch (error) {
|
123
|
+
console.warn('Failed to load project config:', error);
|
124
|
+
}
|
125
|
+
}
|
126
|
+
}
|
127
|
+
catch (_error) {
|
128
|
+
// Silently skip if we can't determine working directory (e.g., in tests)
|
129
|
+
}
|
130
|
+
}
|
131
|
+
// Line 96-111: Merge configurations in priority order
|
132
|
+
mergeConfigurations() {
|
133
|
+
const configs = [
|
134
|
+
this.defaultConfig,
|
135
|
+
this.projectConfig,
|
136
|
+
this.userConfig,
|
137
|
+
this.envConfig,
|
138
|
+
this.cliConfig,
|
139
|
+
this.ephemeralConfig,
|
140
|
+
].filter(Boolean);
|
141
|
+
this.mergedConfig = configs.reduce((merged, config) => Object.assign({}, merged, config), {});
|
142
|
+
// Notify all listeners of configuration change
|
143
|
+
this.listeners.forEach((listener) => listener());
|
144
|
+
}
|
145
|
+
// Line 113-121: Set CLI and ephemeral configs
|
146
|
+
setCliConfig(config) {
|
147
|
+
this.cliConfig = config;
|
148
|
+
this.mergeConfigurations();
|
149
|
+
}
|
150
|
+
setEphemeralConfig(config) {
|
151
|
+
this.ephemeralConfig = {
|
152
|
+
...this.ephemeralConfig,
|
153
|
+
...config,
|
154
|
+
};
|
155
|
+
this.mergeConfigurations();
|
156
|
+
}
|
157
|
+
// Line 123-150: Persist ephemeral to user config
|
158
|
+
persistEphemeralConfig() {
|
159
|
+
if (!this.ephemeralConfig) {
|
160
|
+
return;
|
161
|
+
}
|
162
|
+
const userConfigPath = path.join(os.homedir(), LLXPRT_DIR, 'settings.json');
|
163
|
+
let existing = {};
|
164
|
+
if (fs.existsSync(userConfigPath)) {
|
165
|
+
try {
|
166
|
+
existing = JSON.parse(fs.readFileSync(userConfigPath, 'utf8'));
|
167
|
+
}
|
168
|
+
catch {
|
169
|
+
existing = {};
|
170
|
+
}
|
171
|
+
}
|
172
|
+
existing.debug = Object.assign({}, existing.debug, this.ephemeralConfig);
|
173
|
+
try {
|
174
|
+
fs.mkdirSync(path.dirname(userConfigPath), { recursive: true });
|
175
|
+
fs.writeFileSync(userConfigPath, JSON.stringify(existing, null, 2));
|
176
|
+
this.userConfig = existing.debug;
|
177
|
+
this.ephemeralConfig = null;
|
178
|
+
this.mergeConfigurations();
|
179
|
+
}
|
180
|
+
catch (_error) {
|
181
|
+
throw new Error('Failed to persist configuration');
|
182
|
+
}
|
183
|
+
}
|
184
|
+
// Line 152-174: Getters and subscription management
|
185
|
+
getEffectiveConfig() {
|
186
|
+
return this.mergedConfig;
|
187
|
+
}
|
188
|
+
getOutputTarget() {
|
189
|
+
const output = this.mergedConfig.output;
|
190
|
+
if (typeof output === 'string') {
|
191
|
+
return output;
|
192
|
+
}
|
193
|
+
return output.target;
|
194
|
+
}
|
195
|
+
getRedactPatterns() {
|
196
|
+
return this.mergedConfig.redactPatterns;
|
197
|
+
}
|
198
|
+
subscribe(listener) {
|
199
|
+
this.listeners.add(listener);
|
200
|
+
}
|
201
|
+
unsubscribe(listener) {
|
202
|
+
this.listeners.delete(listener);
|
203
|
+
}
|
204
|
+
parseDebugEnv(value) {
|
205
|
+
return value
|
206
|
+
.split(',')
|
207
|
+
.map((s) => s.trim())
|
208
|
+
.filter(Boolean);
|
209
|
+
}
|
210
|
+
}
|
211
|
+
//# sourceMappingURL=ConfigurationManager.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"ConfigurationManager.js","sourceRoot":"","sources":["../../../src/debug/ConfigurationManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAG/C,MAAM,OAAO,oBAAoB;IAC/B,yDAAyD;IACjD,MAAM,CAAC,QAAQ,CAAmC;IAE1D,+CAA+C;IACvC,aAAa,CAAgB;IAC7B,aAAa,GAAkC,IAAI,CAAC;IACpD,UAAU,GAAkC,IAAI,CAAC;IACjD,SAAS,GAAkC,IAAI,CAAC;IAChD,SAAS,GAAkC,IAAI,CAAC;IAChD,eAAe,GAAkC,IAAI,CAAC;IACtD,YAAY,CAAiB;IAC7B,SAAS,GAAoB,IAAI,GAAG,EAAE,CAAC;IAE/C,sCAAsC;IACtC,MAAM,CAAC,WAAW;QAChB,IAAI,CAAC,oBAAoB,CAAC,QAAQ,EAAE,CAAC;YACnC,oBAAoB,CAAC,QAAQ,GAAG,IAAI,oBAAoB,EAAE,CAAC;QAC7D,CAAC;QACD,OAAO,oBAAoB,CAAC,QAAQ,CAAC;IACvC,CAAC;IAED,8CAA8C;IAC9C;QACE,IAAI,CAAC,aAAa,GAAG;YACnB,OAAO,EAAE,KAAK;YACd,UAAU,EAAE,EAAE;YACd,KAAK,EAAE,MAAM;YACb,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,UAAU,QAAQ,EAAE;YAC9D,cAAc,EAAE,IAAI;YACpB,cAAc,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,UAAU,CAAC;SAChD,CAAC;QACF,IAAI,CAAC,SAAS,GAAG,IAAI,GAAG,EAAE,CAAC;QAC3B,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,IAAI,CAAC,mBAAmB,EAAE,CAAC;IAC7B,CAAC;IAED,sCAAsC;IACtC,kBAAkB;QAChB,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC7B,IAAI,CAAC,cAAc,EAAE,CAAC;QACtB,IAAI,CAAC,iBAAiB,EAAE,CAAC;IAC3B,CAAC;IAED,uEAAuE;IAC/D,qBAAqB;QAC3B,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;YACtB,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACzD,kDAAkD;YAClD,MAAM,gBAAgB,GAAG,UAAU,CAAC,MAAM,CACxC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,GAAG,CAC9C,CAAC;YACF,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAChC,IAAI,CAAC,SAAS,GAAG;oBACf,OAAO,EAAE,IAAI;oBACb,UAAU,EAAE,gBAAgB;iBAC7B,CAAC;YACJ,CAAC;QACH,CAAC;QAED,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;YAC7B,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;YAChE,IAAI,CAAC,SAAS,GAAG;gBACf,OAAO,EAAE,IAAI;gBACb,UAAU;aACX,CAAC;QACJ,CAAC;QAED,6CAA6C;QAC7C,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;YAC9B,IAAI,CAAC,SAAS,GAAG;gBACf,GAAG,IAAI,CAAC,SAAS;gBACjB,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,KAAK,MAAM;aAC9C,CAAC;QACJ,CAAC;QAED,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;YAC5B,IAAI,CAAC,SAAS,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;QACzE,CAAC;IACH,CAAC;IAED,4DAA4D;IACpD,cAAc;QACpB,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC;YAC7B,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,4DAA4D;gBAC5D,OAAO;YACT,CAAC;YACD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,eAAe,CAAC,CAAC;YACnE,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC9B,IAAI,CAAC;oBACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;oBACpD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;oBACnC,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;wBACjB,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC;oBACjC,CAAC;gBACH,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,OAAO,CAAC,IAAI,CAAC,6BAA6B,EAAE,KAAK,CAAC,CAAC;gBACrD,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,MAAM,EAAE,CAAC;YAChB,sEAAsE;YACtE,2DAA2D;QAC7D,CAAC;IACH,CAAC;IAED,2DAA2D;IACnD,iBAAiB;QACvB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;YAC1B,IAAI,CAAC,GAAG,EAAE,CAAC;gBACT,OAAO;YACT,CAAC;YACD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,EAAE,aAAa,CAAC,CAAC;YAC7D,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC9B,IAAI,CAAC;oBACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;oBACpD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;oBACnC,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;wBACjB,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC,KAAK,CAAC;oBACpC,CAAC;gBACH,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,OAAO,CAAC,IAAI,CAAC,gCAAgC,EAAE,KAAK,CAAC,CAAC;gBACxD,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,MAAM,EAAE,CAAC;YAChB,yEAAyE;QAC3E,CAAC;IACH,CAAC;IAED,sDAAsD;IAC9C,mBAAmB;QACzB,MAAM,OAAO,GAAG;YACd,IAAI,CAAC,aAAa;YAClB,IAAI,CAAC,aAAa;YAClB,IAAI,CAAC,UAAU;YACf,IAAI,CAAC,SAAS;YACd,IAAI,CAAC,SAAS;YACd,IAAI,CAAC,eAAe;SACrB,CAAC,MAAM,CAAC,OAAO,CAAkC,CAAC;QAEnD,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,MAAM,CAChC,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EACrD,EAAE,CACc,CAAC;QAEnB,+CAA+C;QAC/C,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;IACnD,CAAC;IAED,8CAA8C;IAC9C,YAAY,CAAC,MAA8B;QACzC,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC;QACxB,IAAI,CAAC,mBAAmB,EAAE,CAAC;IAC7B,CAAC;IAED,kBAAkB,CAAC,MAA8B;QAC/C,IAAI,CAAC,eAAe,GAAG;YACrB,GAAG,IAAI,CAAC,eAAe;YACvB,GAAG,MAAM;SACV,CAAC;QACF,IAAI,CAAC,mBAAmB,EAAE,CAAC;IAC7B,CAAC;IAED,iDAAiD;IACjD,sBAAsB;QACpB,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;YAC1B,OAAO;QACT,CAAC;QAED,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,eAAe,CAAC,CAAC;QAC5E,IAAI,QAAQ,GAA4B,EAAE,CAAC;QAE3C,IAAI,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;YAClC,IAAI,CAAC;gBACH,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC,CAAC;YACjE,CAAC;YAAC,MAAM,CAAC;gBACP,QAAQ,GAAG,EAAE,CAAC;YAChB,CAAC;QACH,CAAC;QAED,QAAQ,CAAC,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;QAEzE,IAAI,CAAC;YACH,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAChE,EAAE,CAAC,aAAa,CAAC,cAAc,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YACpE,IAAI,CAAC,UAAU,GAAG,QAAQ,CAAC,KAA+B,CAAC;YAC3D,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;YAC5B,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC7B,CAAC;QAAC,OAAO,MAAM,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IAED,oDAAoD;IACpD,kBAAkB;QAChB,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAED,eAAe;QACb,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC;QACxC,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC/B,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,OAAO,MAAM,CAAC,MAAM,CAAC;IACvB,CAAC;IAED,iBAAiB;QACf,OAAO,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC;IAC1C,CAAC;IAED,SAAS,CAAC,QAAoB;QAC5B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC/B,CAAC;IAED,WAAW,CAAC,QAAoB;QAC9B,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAClC,CAAC;IAEO,aAAa,CAAC,KAAa;QACjC,OAAO,KAAK;aACT,KAAK,CAAC,GAAG,CAAC;aACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;aACpB,MAAM,CAAC,OAAO,CAAC,CAAC;IACrB,CAAC;CACF"}
|
@@ -0,0 +1,26 @@
|
|
1
|
+
import { ConfigurationManager } from './ConfigurationManager.js';
|
2
|
+
import { FileOutput } from './FileOutput.js';
|
3
|
+
export declare class DebugLogger {
|
4
|
+
private debugInstance;
|
5
|
+
private _namespace;
|
6
|
+
private _configManager;
|
7
|
+
private _fileOutput;
|
8
|
+
private _enabled;
|
9
|
+
private _level;
|
10
|
+
constructor(namespace: string);
|
11
|
+
get namespace(): string;
|
12
|
+
get enabled(): boolean;
|
13
|
+
set enabled(value: boolean);
|
14
|
+
get level(): string;
|
15
|
+
set level(value: string);
|
16
|
+
get configManager(): ConfigurationManager;
|
17
|
+
get fileOutput(): FileOutput;
|
18
|
+
log(messageOrFn: string | (() => string), ...args: unknown[]): void;
|
19
|
+
debug(messageOrFn: string | (() => string), ...args: unknown[]): void;
|
20
|
+
error(messageOrFn: string | (() => string), ...args: unknown[]): void;
|
21
|
+
checkEnabled(): boolean;
|
22
|
+
private matchesPattern;
|
23
|
+
private redactSensitive;
|
24
|
+
private onConfigChange;
|
25
|
+
dispose(): Promise<void>;
|
26
|
+
}
|
@@ -0,0 +1,230 @@
|
|
1
|
+
/**
|
2
|
+
* @plan PLAN-20250120-DEBUGLOGGING.P05
|
3
|
+
* @requirement REQ-001,REQ-002,REQ-006
|
4
|
+
* @pseudocode lines 10-121
|
5
|
+
*/
|
6
|
+
import createDebug from 'debug';
|
7
|
+
import { ConfigurationManager } from './ConfigurationManager.js';
|
8
|
+
import { FileOutput } from './FileOutput.js';
|
9
|
+
// Configure debug to use console.log instead of stderr for React UI compatibility
|
10
|
+
// This ensures debug output goes to the Ctrl+O debug console in the UI
|
11
|
+
if (typeof window === 'undefined') {
|
12
|
+
// Disable colors to respect theme settings
|
13
|
+
createDebug.useColors = () => false;
|
14
|
+
// Use a wrapper function that calls the CURRENT console.log
|
15
|
+
// This works even if console.log is patched later by the UI
|
16
|
+
createDebug.log = (...args) => {
|
17
|
+
// Call whatever console.log is at the time of logging
|
18
|
+
// This allows the UI's ConsolePatcher to intercept it
|
19
|
+
console.log(...args);
|
20
|
+
};
|
21
|
+
}
|
22
|
+
export class DebugLogger {
|
23
|
+
debugInstance; // Line 11
|
24
|
+
_namespace; // Line 12
|
25
|
+
_configManager; // Line 13
|
26
|
+
_fileOutput; // Line 14
|
27
|
+
_enabled; // Line 15
|
28
|
+
_level = 'debug';
|
29
|
+
constructor(namespace) {
|
30
|
+
// Lines 17-24: Initialize logger
|
31
|
+
this._namespace = namespace; // Line 18
|
32
|
+
this.debugInstance = createDebug(namespace); // Line 19
|
33
|
+
this._configManager = ConfigurationManager.getInstance(); // Line 20
|
34
|
+
this._fileOutput = FileOutput.getInstance(); // Line 21
|
35
|
+
this._enabled = this.checkEnabled(); // Line 22
|
36
|
+
this._configManager.subscribe(() => this.onConfigChange()); // Line 23
|
37
|
+
}
|
38
|
+
get namespace() {
|
39
|
+
return this._namespace;
|
40
|
+
}
|
41
|
+
get enabled() {
|
42
|
+
return this._enabled;
|
43
|
+
}
|
44
|
+
set enabled(value) {
|
45
|
+
this._enabled = value;
|
46
|
+
}
|
47
|
+
get level() {
|
48
|
+
return this._level;
|
49
|
+
}
|
50
|
+
set level(value) {
|
51
|
+
this._level = value;
|
52
|
+
}
|
53
|
+
get configManager() {
|
54
|
+
return this._configManager;
|
55
|
+
}
|
56
|
+
get fileOutput() {
|
57
|
+
return this._fileOutput;
|
58
|
+
}
|
59
|
+
log(messageOrFn, ...args) {
|
60
|
+
// Lines 26-60: Main log method
|
61
|
+
if (!this._enabled) {
|
62
|
+
// Line 27-29
|
63
|
+
return; // Zero overhead - no processing when disabled
|
64
|
+
}
|
65
|
+
let message;
|
66
|
+
if (typeof messageOrFn === 'function') {
|
67
|
+
// Line 32
|
68
|
+
try {
|
69
|
+
message = messageOrFn(); // Line 34
|
70
|
+
}
|
71
|
+
catch (_error) {
|
72
|
+
message = '[Error evaluating log function]'; // Line 36
|
73
|
+
}
|
74
|
+
}
|
75
|
+
else {
|
76
|
+
message = messageOrFn; // Line 39
|
77
|
+
}
|
78
|
+
message = this.redactSensitive(message); // Line 42
|
79
|
+
const timestamp = new Date().toISOString(); // Line 43
|
80
|
+
const logEntry = {
|
81
|
+
// Lines 45-51
|
82
|
+
timestamp,
|
83
|
+
namespace: this._namespace,
|
84
|
+
level: 'log',
|
85
|
+
message,
|
86
|
+
args: args.length > 0 ? args : undefined,
|
87
|
+
};
|
88
|
+
const target = this._configManager.getOutputTarget();
|
89
|
+
if (target.includes('file')) {
|
90
|
+
// Line 53-55
|
91
|
+
void this._fileOutput.write(logEntry);
|
92
|
+
}
|
93
|
+
if (target.includes('stderr')) {
|
94
|
+
// Line 57-59
|
95
|
+
this.debugInstance(message, ...args);
|
96
|
+
}
|
97
|
+
}
|
98
|
+
debug(messageOrFn, ...args) {
|
99
|
+
// Lines 62-64
|
100
|
+
if (this._level === 'error') {
|
101
|
+
return; // Don't log debug messages when level is error
|
102
|
+
}
|
103
|
+
// Create modified log entry with debug level
|
104
|
+
if (!this._enabled) {
|
105
|
+
return;
|
106
|
+
}
|
107
|
+
let message;
|
108
|
+
if (typeof messageOrFn === 'function') {
|
109
|
+
try {
|
110
|
+
message = messageOrFn();
|
111
|
+
}
|
112
|
+
catch (_error) {
|
113
|
+
message = '[Error evaluating log function]';
|
114
|
+
}
|
115
|
+
}
|
116
|
+
else {
|
117
|
+
message = messageOrFn;
|
118
|
+
}
|
119
|
+
message = this.redactSensitive(message);
|
120
|
+
const timestamp = new Date().toISOString();
|
121
|
+
const logEntry = {
|
122
|
+
timestamp,
|
123
|
+
namespace: this._namespace,
|
124
|
+
level: 'debug',
|
125
|
+
message,
|
126
|
+
args: args.length > 0 ? args : undefined,
|
127
|
+
};
|
128
|
+
const target = this._configManager.getOutputTarget();
|
129
|
+
if (target.includes('file')) {
|
130
|
+
void this._fileOutput.write(logEntry);
|
131
|
+
}
|
132
|
+
if (target.includes('stderr')) {
|
133
|
+
this.debugInstance(message, ...args);
|
134
|
+
}
|
135
|
+
}
|
136
|
+
error(messageOrFn, ...args) {
|
137
|
+
// Lines 66-70
|
138
|
+
if (!this._enabled) {
|
139
|
+
return;
|
140
|
+
}
|
141
|
+
let message;
|
142
|
+
if (typeof messageOrFn === 'function') {
|
143
|
+
try {
|
144
|
+
message = messageOrFn();
|
145
|
+
}
|
146
|
+
catch (_error) {
|
147
|
+
message = '[Error evaluating log function]';
|
148
|
+
}
|
149
|
+
}
|
150
|
+
else {
|
151
|
+
message = messageOrFn;
|
152
|
+
}
|
153
|
+
message = this.redactSensitive(message);
|
154
|
+
const timestamp = new Date().toISOString();
|
155
|
+
const logEntry = {
|
156
|
+
timestamp,
|
157
|
+
namespace: this._namespace,
|
158
|
+
level: 'error',
|
159
|
+
message,
|
160
|
+
args: args.length > 0 ? args : undefined,
|
161
|
+
};
|
162
|
+
const target = this._configManager.getOutputTarget();
|
163
|
+
if (target.includes('file')) {
|
164
|
+
void this._fileOutput.write(logEntry);
|
165
|
+
}
|
166
|
+
if (target.includes('stderr')) {
|
167
|
+
this.debugInstance(message, ...args);
|
168
|
+
}
|
169
|
+
}
|
170
|
+
checkEnabled() {
|
171
|
+
// Lines 72-85: Check if logger enabled
|
172
|
+
const config = this._configManager.getEffectiveConfig(); // Line 73
|
173
|
+
if (!config.enabled) {
|
174
|
+
// Line 74-76
|
175
|
+
return false;
|
176
|
+
}
|
177
|
+
// Handle namespaces as either array or object
|
178
|
+
const namespaces = Array.isArray(config.namespaces)
|
179
|
+
? config.namespaces
|
180
|
+
: Object.keys(config.namespaces);
|
181
|
+
for (const pattern of namespaces) {
|
182
|
+
// Line 78-82
|
183
|
+
if (this.matchesPattern(this._namespace, pattern)) {
|
184
|
+
return true;
|
185
|
+
}
|
186
|
+
}
|
187
|
+
return false; // Line 84
|
188
|
+
}
|
189
|
+
matchesPattern(namespace, pattern) {
|
190
|
+
// Lines 87-98: Pattern matching
|
191
|
+
if (pattern === namespace) {
|
192
|
+
// Line 88-90
|
193
|
+
return true;
|
194
|
+
}
|
195
|
+
// Support wildcards anywhere in the pattern
|
196
|
+
if (pattern.includes('*')) {
|
197
|
+
// Convert pattern to regex:
|
198
|
+
// - Escape special regex chars except *
|
199
|
+
// - Replace * with .* for regex wildcard matching
|
200
|
+
const regexPattern = pattern
|
201
|
+
.replace(/[.+?^${}()|[\]\\]/g, '\\$&') // Escape special chars
|
202
|
+
.replace(/\*/g, '.*'); // Convert * to regex wildcard
|
203
|
+
const regex = new RegExp(`^${regexPattern}$`);
|
204
|
+
return regex.test(namespace);
|
205
|
+
}
|
206
|
+
return false; // Line 97
|
207
|
+
}
|
208
|
+
redactSensitive(message) {
|
209
|
+
// Lines 100-110: Redact sensitive data
|
210
|
+
const patterns = this._configManager.getRedactPatterns(); // Line 101
|
211
|
+
let result = message; // Line 102
|
212
|
+
for (const pattern of patterns) {
|
213
|
+
// Line 104-107
|
214
|
+
const regex = new RegExp(`${pattern}["']?:\\s*["']?([^"'\\s]+)`, 'gi');
|
215
|
+
result = result.replace(regex, `${pattern}: [REDACTED]`);
|
216
|
+
}
|
217
|
+
return result; // Line 109
|
218
|
+
}
|
219
|
+
onConfigChange() {
|
220
|
+
// Lines 112-114
|
221
|
+
this._enabled = this.checkEnabled();
|
222
|
+
}
|
223
|
+
async dispose() {
|
224
|
+
// Lines 116-119
|
225
|
+
this._configManager.unsubscribe(this.onConfigChange);
|
226
|
+
// Flush pending writes handled by FileOutput
|
227
|
+
await this._fileOutput.dispose();
|
228
|
+
}
|
229
|
+
}
|
230
|
+
//# sourceMappingURL=DebugLogger.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"DebugLogger.js","sourceRoot":"","sources":["../../../src/debug/DebugLogger.ts"],"names":[],"mappings":"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"}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
import type { LogEntry } from './types.js';
|
2
|
+
export declare class FileOutput {
|
3
|
+
private static instance;
|
4
|
+
private debugDir;
|
5
|
+
private currentLogFile;
|
6
|
+
private writeQueue;
|
7
|
+
private isWriting;
|
8
|
+
private disposed;
|
9
|
+
private flushTimeout;
|
10
|
+
private maxFileSize;
|
11
|
+
private maxQueueSize;
|
12
|
+
private batchSize;
|
13
|
+
private flushInterval;
|
14
|
+
private constructor();
|
15
|
+
static getInstance(): FileOutput;
|
16
|
+
write(entry: LogEntry): Promise<void>;
|
17
|
+
dispose(): Promise<void>;
|
18
|
+
private startFlushTimer;
|
19
|
+
private flushQueue;
|
20
|
+
private ensureDirectoryExists;
|
21
|
+
private checkFileRotation;
|
22
|
+
private generateLogFileName;
|
23
|
+
}
|
@@ -0,0 +1,144 @@
|
|
1
|
+
/**
|
2
|
+
* @plan PLAN-20250120-DEBUGLOGGING.P10
|
3
|
+
* @requirement REQ-005
|
4
|
+
*/
|
5
|
+
import { promises as fs } from 'fs';
|
6
|
+
import { join } from 'path';
|
7
|
+
import { homedir } from 'os';
|
8
|
+
import { LLXPRT_DIR } from '../utils/paths.js';
|
9
|
+
export class FileOutput {
|
10
|
+
static instance;
|
11
|
+
debugDir;
|
12
|
+
currentLogFile;
|
13
|
+
writeQueue = [];
|
14
|
+
isWriting = false;
|
15
|
+
disposed = false;
|
16
|
+
flushTimeout = null;
|
17
|
+
maxFileSize = 10 * 1024 * 1024; // 10MB
|
18
|
+
maxQueueSize = 1000;
|
19
|
+
batchSize = 50;
|
20
|
+
flushInterval = 1000; // 1 second
|
21
|
+
constructor() {
|
22
|
+
const home = homedir();
|
23
|
+
// Handle test environments where homedir might not be available
|
24
|
+
this.debugDir = home
|
25
|
+
? join(home, LLXPRT_DIR, 'debug')
|
26
|
+
: join(process.cwd(), LLXPRT_DIR, 'debug');
|
27
|
+
this.currentLogFile = this.generateLogFileName();
|
28
|
+
this.startFlushTimer();
|
29
|
+
}
|
30
|
+
static getInstance() {
|
31
|
+
if (!FileOutput.instance) {
|
32
|
+
FileOutput.instance = new FileOutput();
|
33
|
+
}
|
34
|
+
return FileOutput.instance;
|
35
|
+
}
|
36
|
+
async write(entry) {
|
37
|
+
if (this.disposed) {
|
38
|
+
return;
|
39
|
+
}
|
40
|
+
// Add to queue
|
41
|
+
this.writeQueue.push({
|
42
|
+
entry,
|
43
|
+
timestamp: Date.now(),
|
44
|
+
});
|
45
|
+
// Prevent queue from growing too large
|
46
|
+
if (this.writeQueue.length > this.maxQueueSize) {
|
47
|
+
this.writeQueue = this.writeQueue.slice(-this.maxQueueSize);
|
48
|
+
}
|
49
|
+
// Flush immediately if queue is large or not currently writing
|
50
|
+
if (this.writeQueue.length >= this.batchSize || !this.isWriting) {
|
51
|
+
await this.flushQueue();
|
52
|
+
}
|
53
|
+
}
|
54
|
+
async dispose() {
|
55
|
+
this.disposed = true;
|
56
|
+
if (this.flushTimeout) {
|
57
|
+
clearTimeout(this.flushTimeout);
|
58
|
+
this.flushTimeout = null;
|
59
|
+
}
|
60
|
+
// Flush any remaining entries
|
61
|
+
await this.flushQueue();
|
62
|
+
}
|
63
|
+
startFlushTimer() {
|
64
|
+
if (this.disposed) {
|
65
|
+
return;
|
66
|
+
}
|
67
|
+
this.flushTimeout = setTimeout(async () => {
|
68
|
+
await this.flushQueue();
|
69
|
+
this.startFlushTimer();
|
70
|
+
}, this.flushInterval);
|
71
|
+
}
|
72
|
+
async flushQueue() {
|
73
|
+
if (this.isWriting || this.writeQueue.length === 0 || this.disposed) {
|
74
|
+
return;
|
75
|
+
}
|
76
|
+
this.isWriting = true;
|
77
|
+
let entriesToWrite = [];
|
78
|
+
try {
|
79
|
+
await this.ensureDirectoryExists();
|
80
|
+
await this.checkFileRotation();
|
81
|
+
// Process entries in batches
|
82
|
+
entriesToWrite = this.writeQueue.splice(0, this.batchSize);
|
83
|
+
if (entriesToWrite.length === 0) {
|
84
|
+
return;
|
85
|
+
}
|
86
|
+
// Convert to JSONL format
|
87
|
+
const jsonlData = entriesToWrite.map(({ entry }) => JSON.stringify(entry)).join('\n') +
|
88
|
+
'\n';
|
89
|
+
// Write to file with proper permissions
|
90
|
+
await fs.appendFile(this.currentLogFile, jsonlData, {
|
91
|
+
encoding: 'utf8',
|
92
|
+
mode: 0o600,
|
93
|
+
});
|
94
|
+
}
|
95
|
+
catch (error) {
|
96
|
+
// Gracefully handle errors - don't crash the application
|
97
|
+
console.error('FileOutput: Failed to write log entries:', error);
|
98
|
+
// Put entries back in queue for retry (but limit retries)
|
99
|
+
if (this.writeQueue.length < this.maxQueueSize / 2) {
|
100
|
+
this.writeQueue.unshift(...entriesToWrite);
|
101
|
+
}
|
102
|
+
}
|
103
|
+
finally {
|
104
|
+
this.isWriting = false;
|
105
|
+
}
|
106
|
+
}
|
107
|
+
async ensureDirectoryExists() {
|
108
|
+
try {
|
109
|
+
await fs.access(this.debugDir);
|
110
|
+
}
|
111
|
+
catch {
|
112
|
+
await fs.mkdir(this.debugDir, {
|
113
|
+
recursive: true,
|
114
|
+
mode: 0o700,
|
115
|
+
});
|
116
|
+
}
|
117
|
+
}
|
118
|
+
async checkFileRotation() {
|
119
|
+
try {
|
120
|
+
const stats = await fs.stat(this.currentLogFile);
|
121
|
+
// Rotate by size
|
122
|
+
if (stats.size >= this.maxFileSize) {
|
123
|
+
this.currentLogFile = this.generateLogFileName();
|
124
|
+
return;
|
125
|
+
}
|
126
|
+
// Rotate by date (daily rotation)
|
127
|
+
const fileDate = new Date(stats.birthtime);
|
128
|
+
const today = new Date();
|
129
|
+
if (fileDate.toDateString() !== today.toDateString()) {
|
130
|
+
this.currentLogFile = this.generateLogFileName();
|
131
|
+
}
|
132
|
+
}
|
133
|
+
catch {
|
134
|
+
// File doesn't exist yet, that's fine
|
135
|
+
}
|
136
|
+
}
|
137
|
+
generateLogFileName() {
|
138
|
+
const now = new Date();
|
139
|
+
const dateString = now.toISOString().split('T')[0]; // YYYY-MM-DD
|
140
|
+
const timeString = now.toTimeString().split(' ')[0].replace(/:/g, '-'); // HH-MM-SS
|
141
|
+
return join(this.debugDir, `llxprt-debug-${dateString}-${timeString}.jsonl`);
|
142
|
+
}
|
143
|
+
}
|
144
|
+
//# sourceMappingURL=FileOutput.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"FileOutput.js","sourceRoot":"","sources":["../../../src/debug/FileOutput.ts"],"names":[],"mappings":"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"}
|