create-claude-context 1.0.0 → 1.2.0
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/LICENSE +21 -21
- package/README.md +146 -146
- package/bin/create-claude-context.js +61 -61
- package/lib/detector.js +373 -373
- package/lib/index.js +170 -170
- package/lib/installer.js +371 -362
- package/lib/placeholder.js +208 -208
- package/lib/prompts.js +287 -287
- package/lib/spinner.js +60 -60
- package/lib/validate.js +147 -147
- package/package.json +59 -59
- package/templates/CLAUDE.md.template +235 -235
- package/templates/base/README.md +257 -257
- package/templates/base/RPI_WORKFLOW_PLAN.md +320 -320
- package/templates/base/agents/api-developer.md +76 -76
- package/templates/base/agents/context-engineer.md +525 -525
- package/templates/base/agents/core-architect.md +76 -76
- package/templates/base/agents/database-ops.md +76 -76
- package/templates/base/agents/deployment-ops.md +76 -76
- package/templates/base/agents/integration-hub.md +76 -76
- package/templates/base/analytics/README.md +114 -114
- package/templates/base/automation/config.json +58 -0
- package/templates/base/automation/generators/code-mapper.js +308 -0
- package/templates/base/automation/generators/index-builder.js +321 -0
- package/templates/base/automation/hooks/post-commit.sh +83 -0
- package/templates/base/automation/hooks/pre-commit.sh +103 -0
- package/templates/base/ci-templates/README.md +108 -108
- package/templates/base/ci-templates/github-actions/context-check.yml +144 -144
- package/templates/base/ci-templates/github-actions/validate-docs.yml +105 -105
- package/templates/base/commands/analytics.md +238 -238
- package/templates/base/commands/auto-sync.md +172 -0
- package/templates/base/commands/collab.md +194 -194
- package/templates/base/commands/help.md +450 -450
- package/templates/base/commands/rpi-implement.md +115 -115
- package/templates/base/commands/rpi-plan.md +93 -93
- package/templates/base/commands/rpi-research.md +88 -88
- package/templates/base/commands/session-resume.md +144 -0
- package/templates/base/commands/session-save.md +112 -0
- package/templates/base/commands/validate-all.md +77 -77
- package/templates/base/commands/verify-docs-current.md +86 -86
- package/templates/base/config/base.json +57 -57
- package/templates/base/config/environments/development.json +13 -13
- package/templates/base/config/environments/production.json +17 -17
- package/templates/base/config/environments/staging.json +13 -13
- package/templates/base/config/local.json.example +21 -21
- package/templates/base/context/.meta/generated-at.json +18 -0
- package/templates/base/context/ARCHITECTURE_SNAPSHOT.md +156 -156
- package/templates/base/context/CODE_TO_WORKFLOW_MAP.md +94 -94
- package/templates/base/context/FILE_OWNERSHIP.md +57 -0
- package/templates/base/context/INTEGRATION_POINTS.md +92 -0
- package/templates/base/context/KNOWN_GOTCHAS.md +195 -195
- package/templates/base/context/TESTING_MAP.md +95 -0
- package/templates/base/context/WORKFLOW_INDEX.md +129 -129
- package/templates/base/context/workflows/WORKFLOW_TEMPLATE.md +294 -294
- package/templates/base/indexes/agents/CAPABILITY_MATRIX.md +255 -255
- package/templates/base/indexes/agents/CATEGORY_INDEX.md +44 -44
- package/templates/base/indexes/code/CATEGORY_INDEX.md +38 -38
- package/templates/base/indexes/routing/CATEGORY_INDEX.md +39 -39
- package/templates/base/indexes/search/CATEGORY_INDEX.md +39 -39
- package/templates/base/indexes/workflows/CATEGORY_INDEX.md +38 -38
- package/templates/base/knowledge/README.md +98 -98
- package/templates/base/knowledge/sessions/README.md +88 -88
- package/templates/base/knowledge/sessions/TEMPLATE.md +150 -150
- package/templates/base/knowledge/shared/decisions/0001-adopt-context-engineering.md +144 -144
- package/templates/base/knowledge/shared/decisions/README.md +49 -49
- package/templates/base/knowledge/shared/decisions/TEMPLATE.md +123 -123
- package/templates/base/knowledge/shared/patterns/README.md +62 -62
- package/templates/base/knowledge/shared/patterns/TEMPLATE.md +120 -120
- package/templates/base/plans/PLAN_TEMPLATE.md +250 -250
- package/templates/base/research/RESEARCH_TEMPLATE.md +153 -153
- package/templates/base/schemas/agent.schema.json +141 -141
- package/templates/base/schemas/anchors.schema.json +54 -0
- package/templates/base/schemas/automation.schema.json +93 -0
- package/templates/base/schemas/command.schema.json +134 -134
- package/templates/base/schemas/hashes.schema.json +40 -0
- package/templates/base/schemas/manifest.schema.json +117 -117
- package/templates/base/schemas/plan.schema.json +136 -136
- package/templates/base/schemas/research.schema.json +115 -115
- package/templates/base/schemas/roles.schema.json +34 -0
- package/templates/base/schemas/session.schema.json +77 -0
- package/templates/base/schemas/settings.schema.json +244 -244
- package/templates/base/schemas/staleness.schema.json +53 -0
- package/templates/base/schemas/team-config.schema.json +42 -0
- package/templates/base/schemas/workflow.schema.json +126 -126
- package/templates/base/session/checkpoints/.gitkeep +2 -0
- package/templates/base/session/current/state.json +20 -0
- package/templates/base/session/history/.gitkeep +2 -0
- package/templates/base/settings.json +79 -57
- package/templates/base/standards/COMPATIBILITY.md +219 -219
- package/templates/base/standards/EXTENSION_GUIDELINES.md +280 -280
- package/templates/base/standards/QUALITY_CHECKLIST.md +211 -211
- package/templates/base/standards/README.md +66 -66
- package/templates/base/sync/anchors.json +6 -0
- package/templates/base/sync/hashes.json +6 -0
- package/templates/base/sync/staleness.json +10 -0
- package/templates/base/team/README.md +168 -168
- package/templates/base/team/config.json +79 -79
- package/templates/base/team/roles.json +145 -145
- package/templates/base/tools/bin/claude-context.js +151 -151
- package/templates/base/tools/lib/anchor-resolver.js +276 -0
- package/templates/base/tools/lib/config-loader.js +363 -363
- package/templates/base/tools/lib/detector.js +350 -350
- package/templates/base/tools/lib/diagnose.js +206 -206
- package/templates/base/tools/lib/drift-detector.js +373 -0
- package/templates/base/tools/lib/errors.js +199 -199
- package/templates/base/tools/lib/index.js +36 -24
- package/templates/base/tools/lib/init.js +192 -192
- package/templates/base/tools/lib/logger.js +230 -230
- package/templates/base/tools/lib/placeholder.js +201 -201
- package/templates/base/tools/lib/session-manager.js +354 -0
- package/templates/base/tools/lib/validate.js +521 -521
- package/templates/base/tools/package.json +49 -49
|
@@ -1,230 +1,230 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Claude Context Engineering - Logger
|
|
3
|
-
*
|
|
4
|
-
* Structured logging with levels, file output, and operation tracking.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
const fs = require('fs');
|
|
8
|
-
const path = require('path');
|
|
9
|
-
const chalk = require('chalk');
|
|
10
|
-
|
|
11
|
-
const LOG_LEVELS = {
|
|
12
|
-
debug: 0,
|
|
13
|
-
info: 1,
|
|
14
|
-
warn: 2,
|
|
15
|
-
error: 3,
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
const LEVEL_COLORS = {
|
|
19
|
-
debug: chalk.gray,
|
|
20
|
-
info: chalk.blue,
|
|
21
|
-
warn: chalk.yellow,
|
|
22
|
-
error: chalk.red,
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
const LEVEL_ICONS = {
|
|
26
|
-
debug: '🔍',
|
|
27
|
-
info: 'ℹ️ ',
|
|
28
|
-
warn: '⚠️ ',
|
|
29
|
-
error: '❌',
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Create a logger instance
|
|
34
|
-
*/
|
|
35
|
-
function createLogger(options = {}) {
|
|
36
|
-
const config = {
|
|
37
|
-
level: options.level || 'info',
|
|
38
|
-
file: options.file || null,
|
|
39
|
-
maxSizeMb: options.maxSizeMb || 10,
|
|
40
|
-
console: options.console !== false,
|
|
41
|
-
timestamps: options.timestamps !== false,
|
|
42
|
-
colors: options.colors !== false,
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
// Ensure log directory exists if file logging enabled
|
|
46
|
-
if (config.file) {
|
|
47
|
-
const logDir = path.dirname(config.file);
|
|
48
|
-
if (!fs.existsSync(logDir)) {
|
|
49
|
-
fs.mkdirSync(logDir, { recursive: true });
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Check if we should log at this level
|
|
55
|
-
*/
|
|
56
|
-
function shouldLog(level) {
|
|
57
|
-
return LOG_LEVELS[level] >= LOG_LEVELS[config.level];
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Format a log message
|
|
62
|
-
*/
|
|
63
|
-
function formatMessage(level, message, meta = {}) {
|
|
64
|
-
const timestamp = new Date().toISOString();
|
|
65
|
-
const parts = [];
|
|
66
|
-
|
|
67
|
-
if (config.timestamps) {
|
|
68
|
-
parts.push(`[${timestamp}]`);
|
|
69
|
-
}
|
|
70
|
-
parts.push(`[${level.toUpperCase()}]`);
|
|
71
|
-
parts.push(message);
|
|
72
|
-
|
|
73
|
-
if (Object.keys(meta).length > 0) {
|
|
74
|
-
parts.push(JSON.stringify(meta));
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
return parts.join(' ');
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Write to console with colors
|
|
82
|
-
*/
|
|
83
|
-
function writeConsole(level, message, meta) {
|
|
84
|
-
if (!config.console) return;
|
|
85
|
-
|
|
86
|
-
const colorFn = config.colors ? LEVEL_COLORS[level] : (s) => s;
|
|
87
|
-
const icon = LEVEL_ICONS[level];
|
|
88
|
-
const timestamp = config.timestamps
|
|
89
|
-
? chalk.gray(`[${new Date().toISOString()}] `)
|
|
90
|
-
: '';
|
|
91
|
-
|
|
92
|
-
let output = `${timestamp}${icon} ${colorFn(message)}`;
|
|
93
|
-
|
|
94
|
-
if (Object.keys(meta).length > 0) {
|
|
95
|
-
output += '\n' + chalk.gray(JSON.stringify(meta, null, 2));
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
if (level === 'error') {
|
|
99
|
-
console.error(output);
|
|
100
|
-
} else {
|
|
101
|
-
console.log(output);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Write to file
|
|
107
|
-
*/
|
|
108
|
-
function writeFile(level, message, meta) {
|
|
109
|
-
if (!config.file) return;
|
|
110
|
-
|
|
111
|
-
try {
|
|
112
|
-
const formatted = formatMessage(level, message, meta) + '\n';
|
|
113
|
-
fs.appendFileSync(config.file, formatted);
|
|
114
|
-
|
|
115
|
-
// Check file size and rotate if needed
|
|
116
|
-
const stats = fs.statSync(config.file);
|
|
117
|
-
const sizeMb = stats.size / (1024 * 1024);
|
|
118
|
-
if (sizeMb > config.maxSizeMb) {
|
|
119
|
-
rotateLog();
|
|
120
|
-
}
|
|
121
|
-
} catch (error) {
|
|
122
|
-
// Silently fail file logging
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* Rotate log file
|
|
128
|
-
*/
|
|
129
|
-
function rotateLog() {
|
|
130
|
-
if (!config.file || !fs.existsSync(config.file)) return;
|
|
131
|
-
|
|
132
|
-
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
133
|
-
const rotatedPath = config.file.replace('.log', `-${timestamp}.log`);
|
|
134
|
-
|
|
135
|
-
try {
|
|
136
|
-
fs.renameSync(config.file, rotatedPath);
|
|
137
|
-
} catch (error) {
|
|
138
|
-
// Silently fail rotation
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* Core log function
|
|
144
|
-
*/
|
|
145
|
-
function log(level, message, meta = {}) {
|
|
146
|
-
if (!shouldLog(level)) return;
|
|
147
|
-
|
|
148
|
-
writeConsole(level, message, meta);
|
|
149
|
-
writeFile(level, message, meta);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* Start an operation and return tracking object
|
|
154
|
-
*/
|
|
155
|
-
function startOperation(name) {
|
|
156
|
-
const operationId = generateId();
|
|
157
|
-
const startTime = Date.now();
|
|
158
|
-
|
|
159
|
-
log('info', `Operation started: ${name}`, { operation_id: operationId });
|
|
160
|
-
|
|
161
|
-
return {
|
|
162
|
-
id: operationId,
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Log progress
|
|
166
|
-
*/
|
|
167
|
-
progress: (message, meta = {}) => {
|
|
168
|
-
log('debug', `[${name}] ${message}`, { operation_id: operationId, ...meta });
|
|
169
|
-
},
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* Mark operation as successful
|
|
173
|
-
*/
|
|
174
|
-
success: (message = 'completed', meta = {}) => {
|
|
175
|
-
const duration = Date.now() - startTime;
|
|
176
|
-
log('info', `Operation completed: ${name} - ${message}`, {
|
|
177
|
-
operation_id: operationId,
|
|
178
|
-
duration_ms: duration,
|
|
179
|
-
...meta,
|
|
180
|
-
});
|
|
181
|
-
return { success: true, duration };
|
|
182
|
-
},
|
|
183
|
-
|
|
184
|
-
/**
|
|
185
|
-
* Mark operation as failed
|
|
186
|
-
*/
|
|
187
|
-
fail: (error, meta = {}) => {
|
|
188
|
-
const duration = Date.now() - startTime;
|
|
189
|
-
const errorMessage = error instanceof Error ? error.message : error;
|
|
190
|
-
log('error', `Operation failed: ${name} - ${errorMessage}`, {
|
|
191
|
-
operation_id: operationId,
|
|
192
|
-
duration_ms: duration,
|
|
193
|
-
error: error instanceof Error ? { name: error.name, stack: error.stack } : error,
|
|
194
|
-
...meta,
|
|
195
|
-
});
|
|
196
|
-
return { success: false, duration, error };
|
|
197
|
-
},
|
|
198
|
-
};
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
* Generate a short unique ID
|
|
203
|
-
*/
|
|
204
|
-
function generateId() {
|
|
205
|
-
return Math.random().toString(36).substring(2, 10);
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
// Return logger interface
|
|
209
|
-
return {
|
|
210
|
-
debug: (message, meta) => log('debug', message, meta),
|
|
211
|
-
info: (message, meta) => log('info', message, meta),
|
|
212
|
-
warn: (message, meta) => log('warn', message, meta),
|
|
213
|
-
error: (message, meta) => log('error', message, meta),
|
|
214
|
-
startOperation,
|
|
215
|
-
setLevel: (level) => { config.level = level; },
|
|
216
|
-
getLevel: () => config.level,
|
|
217
|
-
};
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
// Default logger instance
|
|
221
|
-
const logger = createLogger({
|
|
222
|
-
level: process.env.CLAUDE_LOG_LEVEL || 'info',
|
|
223
|
-
file: process.env.CLAUDE_LOG_FILE || null,
|
|
224
|
-
});
|
|
225
|
-
|
|
226
|
-
module.exports = {
|
|
227
|
-
createLogger,
|
|
228
|
-
logger,
|
|
229
|
-
LOG_LEVELS,
|
|
230
|
-
};
|
|
1
|
+
/**
|
|
2
|
+
* Claude Context Engineering - Logger
|
|
3
|
+
*
|
|
4
|
+
* Structured logging with levels, file output, and operation tracking.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
const chalk = require('chalk');
|
|
10
|
+
|
|
11
|
+
const LOG_LEVELS = {
|
|
12
|
+
debug: 0,
|
|
13
|
+
info: 1,
|
|
14
|
+
warn: 2,
|
|
15
|
+
error: 3,
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const LEVEL_COLORS = {
|
|
19
|
+
debug: chalk.gray,
|
|
20
|
+
info: chalk.blue,
|
|
21
|
+
warn: chalk.yellow,
|
|
22
|
+
error: chalk.red,
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const LEVEL_ICONS = {
|
|
26
|
+
debug: '🔍',
|
|
27
|
+
info: 'ℹ️ ',
|
|
28
|
+
warn: '⚠️ ',
|
|
29
|
+
error: '❌',
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Create a logger instance
|
|
34
|
+
*/
|
|
35
|
+
function createLogger(options = {}) {
|
|
36
|
+
const config = {
|
|
37
|
+
level: options.level || 'info',
|
|
38
|
+
file: options.file || null,
|
|
39
|
+
maxSizeMb: options.maxSizeMb || 10,
|
|
40
|
+
console: options.console !== false,
|
|
41
|
+
timestamps: options.timestamps !== false,
|
|
42
|
+
colors: options.colors !== false,
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
// Ensure log directory exists if file logging enabled
|
|
46
|
+
if (config.file) {
|
|
47
|
+
const logDir = path.dirname(config.file);
|
|
48
|
+
if (!fs.existsSync(logDir)) {
|
|
49
|
+
fs.mkdirSync(logDir, { recursive: true });
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Check if we should log at this level
|
|
55
|
+
*/
|
|
56
|
+
function shouldLog(level) {
|
|
57
|
+
return LOG_LEVELS[level] >= LOG_LEVELS[config.level];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Format a log message
|
|
62
|
+
*/
|
|
63
|
+
function formatMessage(level, message, meta = {}) {
|
|
64
|
+
const timestamp = new Date().toISOString();
|
|
65
|
+
const parts = [];
|
|
66
|
+
|
|
67
|
+
if (config.timestamps) {
|
|
68
|
+
parts.push(`[${timestamp}]`);
|
|
69
|
+
}
|
|
70
|
+
parts.push(`[${level.toUpperCase()}]`);
|
|
71
|
+
parts.push(message);
|
|
72
|
+
|
|
73
|
+
if (Object.keys(meta).length > 0) {
|
|
74
|
+
parts.push(JSON.stringify(meta));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return parts.join(' ');
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Write to console with colors
|
|
82
|
+
*/
|
|
83
|
+
function writeConsole(level, message, meta) {
|
|
84
|
+
if (!config.console) return;
|
|
85
|
+
|
|
86
|
+
const colorFn = config.colors ? LEVEL_COLORS[level] : (s) => s;
|
|
87
|
+
const icon = LEVEL_ICONS[level];
|
|
88
|
+
const timestamp = config.timestamps
|
|
89
|
+
? chalk.gray(`[${new Date().toISOString()}] `)
|
|
90
|
+
: '';
|
|
91
|
+
|
|
92
|
+
let output = `${timestamp}${icon} ${colorFn(message)}`;
|
|
93
|
+
|
|
94
|
+
if (Object.keys(meta).length > 0) {
|
|
95
|
+
output += '\n' + chalk.gray(JSON.stringify(meta, null, 2));
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (level === 'error') {
|
|
99
|
+
console.error(output);
|
|
100
|
+
} else {
|
|
101
|
+
console.log(output);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Write to file
|
|
107
|
+
*/
|
|
108
|
+
function writeFile(level, message, meta) {
|
|
109
|
+
if (!config.file) return;
|
|
110
|
+
|
|
111
|
+
try {
|
|
112
|
+
const formatted = formatMessage(level, message, meta) + '\n';
|
|
113
|
+
fs.appendFileSync(config.file, formatted);
|
|
114
|
+
|
|
115
|
+
// Check file size and rotate if needed
|
|
116
|
+
const stats = fs.statSync(config.file);
|
|
117
|
+
const sizeMb = stats.size / (1024 * 1024);
|
|
118
|
+
if (sizeMb > config.maxSizeMb) {
|
|
119
|
+
rotateLog();
|
|
120
|
+
}
|
|
121
|
+
} catch (error) {
|
|
122
|
+
// Silently fail file logging
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Rotate log file
|
|
128
|
+
*/
|
|
129
|
+
function rotateLog() {
|
|
130
|
+
if (!config.file || !fs.existsSync(config.file)) return;
|
|
131
|
+
|
|
132
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
133
|
+
const rotatedPath = config.file.replace('.log', `-${timestamp}.log`);
|
|
134
|
+
|
|
135
|
+
try {
|
|
136
|
+
fs.renameSync(config.file, rotatedPath);
|
|
137
|
+
} catch (error) {
|
|
138
|
+
// Silently fail rotation
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Core log function
|
|
144
|
+
*/
|
|
145
|
+
function log(level, message, meta = {}) {
|
|
146
|
+
if (!shouldLog(level)) return;
|
|
147
|
+
|
|
148
|
+
writeConsole(level, message, meta);
|
|
149
|
+
writeFile(level, message, meta);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Start an operation and return tracking object
|
|
154
|
+
*/
|
|
155
|
+
function startOperation(name) {
|
|
156
|
+
const operationId = generateId();
|
|
157
|
+
const startTime = Date.now();
|
|
158
|
+
|
|
159
|
+
log('info', `Operation started: ${name}`, { operation_id: operationId });
|
|
160
|
+
|
|
161
|
+
return {
|
|
162
|
+
id: operationId,
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Log progress
|
|
166
|
+
*/
|
|
167
|
+
progress: (message, meta = {}) => {
|
|
168
|
+
log('debug', `[${name}] ${message}`, { operation_id: operationId, ...meta });
|
|
169
|
+
},
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Mark operation as successful
|
|
173
|
+
*/
|
|
174
|
+
success: (message = 'completed', meta = {}) => {
|
|
175
|
+
const duration = Date.now() - startTime;
|
|
176
|
+
log('info', `Operation completed: ${name} - ${message}`, {
|
|
177
|
+
operation_id: operationId,
|
|
178
|
+
duration_ms: duration,
|
|
179
|
+
...meta,
|
|
180
|
+
});
|
|
181
|
+
return { success: true, duration };
|
|
182
|
+
},
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Mark operation as failed
|
|
186
|
+
*/
|
|
187
|
+
fail: (error, meta = {}) => {
|
|
188
|
+
const duration = Date.now() - startTime;
|
|
189
|
+
const errorMessage = error instanceof Error ? error.message : error;
|
|
190
|
+
log('error', `Operation failed: ${name} - ${errorMessage}`, {
|
|
191
|
+
operation_id: operationId,
|
|
192
|
+
duration_ms: duration,
|
|
193
|
+
error: error instanceof Error ? { name: error.name, stack: error.stack } : error,
|
|
194
|
+
...meta,
|
|
195
|
+
});
|
|
196
|
+
return { success: false, duration, error };
|
|
197
|
+
},
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Generate a short unique ID
|
|
203
|
+
*/
|
|
204
|
+
function generateId() {
|
|
205
|
+
return Math.random().toString(36).substring(2, 10);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Return logger interface
|
|
209
|
+
return {
|
|
210
|
+
debug: (message, meta) => log('debug', message, meta),
|
|
211
|
+
info: (message, meta) => log('info', message, meta),
|
|
212
|
+
warn: (message, meta) => log('warn', message, meta),
|
|
213
|
+
error: (message, meta) => log('error', message, meta),
|
|
214
|
+
startOperation,
|
|
215
|
+
setLevel: (level) => { config.level = level; },
|
|
216
|
+
getLevel: () => config.level,
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Default logger instance
|
|
221
|
+
const logger = createLogger({
|
|
222
|
+
level: process.env.CLAUDE_LOG_LEVEL || 'info',
|
|
223
|
+
file: process.env.CLAUDE_LOG_FILE || null,
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
module.exports = {
|
|
227
|
+
createLogger,
|
|
228
|
+
logger,
|
|
229
|
+
LOG_LEVELS,
|
|
230
|
+
};
|