log-llm-config 1.0.5 → 1.0.7
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/log_config_files.js +353 -1
- package/package.json +8 -8
package/dist/log_config_files.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { readFileSync, existsSync, mkdirSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { readFileSync, existsSync, mkdirSync, writeFileSync, readdirSync } from 'node:fs';
|
|
3
3
|
import { join, dirname } from 'node:path';
|
|
4
4
|
import { fileURLToPath } from 'node:url';
|
|
5
5
|
import { homedir } from 'node:os';
|
|
@@ -49,6 +49,28 @@ const JSON_FILE_PATHS = [
|
|
|
49
49
|
];
|
|
50
50
|
// VS Code/Cursor state database path
|
|
51
51
|
const VSCDB_PATH = join(homedir(), 'Library', 'Application Support', 'Cursor', 'User', 'globalStorage', 'state.vscdb');
|
|
52
|
+
// Claude configuration file paths
|
|
53
|
+
const CLAUDE_FILE_PATHS = [
|
|
54
|
+
// Project Root
|
|
55
|
+
{
|
|
56
|
+
path: join(PROJECT_ROOT, 'CLAUDE.md'),
|
|
57
|
+
file_type: 'claude_rule_config',
|
|
58
|
+
},
|
|
59
|
+
// Local Overrides (project-level)
|
|
60
|
+
{
|
|
61
|
+
path: join(PROJECT_ROOT, 'CLAUDE.local.md'),
|
|
62
|
+
file_type: 'claude_rule_config',
|
|
63
|
+
},
|
|
64
|
+
// Home Directory
|
|
65
|
+
{
|
|
66
|
+
path: join(homedir(), '.claude', 'CLAUDE.md'),
|
|
67
|
+
file_type: 'claude_rule_config',
|
|
68
|
+
},
|
|
69
|
+
];
|
|
70
|
+
// Claude rules directory
|
|
71
|
+
const CLAUDE_RULES_DIR = join(homedir(), '.claude', 'rules');
|
|
72
|
+
// Cursor rules directory (project-level)
|
|
73
|
+
const CURSOR_RULES_DIR = join(PROJECT_ROOT, '.cursor', 'rules');
|
|
52
74
|
/**
|
|
53
75
|
* Read and parse an MCP config file
|
|
54
76
|
*/
|
|
@@ -86,6 +108,190 @@ function readJSONFile(filePath) {
|
|
|
86
108
|
return null;
|
|
87
109
|
}
|
|
88
110
|
}
|
|
111
|
+
/**
|
|
112
|
+
* Read a markdown/text file and return as content string
|
|
113
|
+
*/
|
|
114
|
+
function readMarkdownFile(filePath) {
|
|
115
|
+
try {
|
|
116
|
+
if (!existsSync(filePath)) {
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
const content = readFileSync(filePath, 'utf-8');
|
|
120
|
+
return content;
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
if (error.code === 'EACCES' || error.code === 'EPERM') {
|
|
124
|
+
console.warn(`Permission denied reading ${filePath} (may require elevated permissions)`);
|
|
125
|
+
}
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Get parent directory paths for monorepo support
|
|
131
|
+
* Checks parent directories up to 5 levels for CLAUDE.md files
|
|
132
|
+
*/
|
|
133
|
+
function getParentClaudeFiles(projectRoot) {
|
|
134
|
+
const files = [];
|
|
135
|
+
let currentPath = projectRoot;
|
|
136
|
+
let levels = 0;
|
|
137
|
+
const maxLevels = 5; // Limit to prevent infinite loops
|
|
138
|
+
while (levels < maxLevels) {
|
|
139
|
+
const parentPath = path.dirname(currentPath);
|
|
140
|
+
if (parentPath === currentPath) {
|
|
141
|
+
// Reached filesystem root
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
const claudePath = join(parentPath, 'CLAUDE.md');
|
|
145
|
+
if (existsSync(claudePath)) {
|
|
146
|
+
files.push({
|
|
147
|
+
path: claudePath,
|
|
148
|
+
file_type: 'claude_rule_config',
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
currentPath = parentPath;
|
|
152
|
+
levels++;
|
|
153
|
+
}
|
|
154
|
+
return files;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Get all markdown files from Claude rules directory
|
|
158
|
+
*/
|
|
159
|
+
function getClaudeRuleFiles() {
|
|
160
|
+
const files = [];
|
|
161
|
+
try {
|
|
162
|
+
if (!existsSync(CLAUDE_RULES_DIR)) {
|
|
163
|
+
return files;
|
|
164
|
+
}
|
|
165
|
+
const entries = readdirSync(CLAUDE_RULES_DIR, { withFileTypes: true });
|
|
166
|
+
for (const entry of entries) {
|
|
167
|
+
if (entry.isFile() && entry.name.endsWith('.md')) {
|
|
168
|
+
files.push({
|
|
169
|
+
path: join(CLAUDE_RULES_DIR, entry.name),
|
|
170
|
+
file_type: 'claude_rule',
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
catch (error) {
|
|
176
|
+
console.warn(`Error reading Claude rules directory ${CLAUDE_RULES_DIR}:`, error instanceof Error ? error.message : String(error));
|
|
177
|
+
}
|
|
178
|
+
return files;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Get all rule files from Cursor rules directory
|
|
182
|
+
* Supports new format (.cursor/rules/rule-name/RULE.md) and legacy format (.cursor/rules/*.mdc or *.md)
|
|
183
|
+
*/
|
|
184
|
+
function getCursorRuleFiles() {
|
|
185
|
+
const files = [];
|
|
186
|
+
try {
|
|
187
|
+
if (!existsSync(CURSOR_RULES_DIR)) {
|
|
188
|
+
return files;
|
|
189
|
+
}
|
|
190
|
+
const entries = readdirSync(CURSOR_RULES_DIR, { withFileTypes: true });
|
|
191
|
+
for (const entry of entries) {
|
|
192
|
+
if (entry.isDirectory()) {
|
|
193
|
+
// New format: rule folder containing RULE.md
|
|
194
|
+
const ruleMdPath = join(CURSOR_RULES_DIR, entry.name, 'RULE.md');
|
|
195
|
+
if (existsSync(ruleMdPath)) {
|
|
196
|
+
files.push({
|
|
197
|
+
path: ruleMdPath,
|
|
198
|
+
file_type: 'cursor_rule',
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
else if (entry.isFile()) {
|
|
203
|
+
// Legacy format: flat .mdc or .md files
|
|
204
|
+
if (entry.name.endsWith('.mdc') || entry.name.endsWith('.md')) {
|
|
205
|
+
files.push({
|
|
206
|
+
path: join(CURSOR_RULES_DIR, entry.name),
|
|
207
|
+
file_type: 'cursor_rule',
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
catch (error) {
|
|
214
|
+
console.warn(`Error reading Cursor rules directory ${CURSOR_RULES_DIR}:`, error instanceof Error ? error.message : String(error));
|
|
215
|
+
}
|
|
216
|
+
return files;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Get AGENTS.md files from project root and subdirectories
|
|
220
|
+
* Supports nested AGENTS.md files as per Cursor documentation
|
|
221
|
+
*/
|
|
222
|
+
function getAgentsMdFiles(projectRoot) {
|
|
223
|
+
const files = [];
|
|
224
|
+
// Check project root
|
|
225
|
+
const rootAgentsMd = join(projectRoot, 'AGENTS.md');
|
|
226
|
+
if (existsSync(rootAgentsMd)) {
|
|
227
|
+
files.push({
|
|
228
|
+
path: rootAgentsMd,
|
|
229
|
+
file_type: 'cursor_rule',
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
// Check subdirectories (1 level deep for now, can be extended)
|
|
233
|
+
try {
|
|
234
|
+
const entries = readdirSync(projectRoot, { withFileTypes: true });
|
|
235
|
+
for (const entry of entries) {
|
|
236
|
+
if (entry.isDirectory() && !entry.name.startsWith('.') && entry.name !== 'node_modules') {
|
|
237
|
+
const subdirAgentsMd = join(projectRoot, entry.name, 'AGENTS.md');
|
|
238
|
+
if (existsSync(subdirAgentsMd)) {
|
|
239
|
+
files.push({
|
|
240
|
+
path: subdirAgentsMd,
|
|
241
|
+
file_type: 'cursor_rule',
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
catch (error) {
|
|
248
|
+
console.warn(`Error reading subdirectories for AGENTS.md in ${projectRoot}:`, error instanceof Error ? error.message : String(error));
|
|
249
|
+
}
|
|
250
|
+
return files;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Get .cursorrules file from project root (legacy format, deprecated but still supported)
|
|
254
|
+
*/
|
|
255
|
+
function getCursorRulesFile(projectRoot) {
|
|
256
|
+
const files = [];
|
|
257
|
+
const cursorRulesPath = join(projectRoot, '.cursorrules');
|
|
258
|
+
if (existsSync(cursorRulesPath)) {
|
|
259
|
+
files.push({
|
|
260
|
+
path: cursorRulesPath,
|
|
261
|
+
file_type: 'cursor_rule',
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
return files;
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Get subdirectory Claude files for monorepo support
|
|
268
|
+
* Checks immediate subdirectories (1 level deep) for CLAUDE.md files
|
|
269
|
+
*/
|
|
270
|
+
function getSubdirectoryClaudeFiles(projectRoot) {
|
|
271
|
+
const files = [];
|
|
272
|
+
try {
|
|
273
|
+
if (!existsSync(projectRoot)) {
|
|
274
|
+
return files;
|
|
275
|
+
}
|
|
276
|
+
const entries = readdirSync(projectRoot, { withFileTypes: true });
|
|
277
|
+
for (const entry of entries) {
|
|
278
|
+
// Only check immediate subdirectories (not files, not hidden dirs like .git, node_modules, etc.)
|
|
279
|
+
if (entry.isDirectory() && !entry.name.startsWith('.') && entry.name !== 'node_modules') {
|
|
280
|
+
const claudePath = join(projectRoot, entry.name, 'CLAUDE.md');
|
|
281
|
+
if (existsSync(claudePath)) {
|
|
282
|
+
files.push({
|
|
283
|
+
path: claudePath,
|
|
284
|
+
file_type: 'claude_rule_config',
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
catch (error) {
|
|
291
|
+
console.warn(`Error reading subdirectories in ${projectRoot}:`, error instanceof Error ? error.message : String(error));
|
|
292
|
+
}
|
|
293
|
+
return files;
|
|
294
|
+
}
|
|
89
295
|
/**
|
|
90
296
|
* Read composerState from Cursor's state.vscdb SQLite database
|
|
91
297
|
*/
|
|
@@ -185,6 +391,152 @@ function collectConfigFiles() {
|
|
|
185
391
|
},
|
|
186
392
|
});
|
|
187
393
|
}
|
|
394
|
+
// Read Claude configuration files (project root, local overrides, home directory)
|
|
395
|
+
for (const { path, file_type } of CLAUDE_FILE_PATHS) {
|
|
396
|
+
try {
|
|
397
|
+
const markdownContent = readMarkdownFile(path);
|
|
398
|
+
if (markdownContent !== null) { // Log even if empty (null means file doesn't exist or error)
|
|
399
|
+
console.log(`Found ${file_type} at: ${path}`);
|
|
400
|
+
configFiles.push({
|
|
401
|
+
file_type,
|
|
402
|
+
file_path: path,
|
|
403
|
+
raw_content: {
|
|
404
|
+
content: markdownContent,
|
|
405
|
+
source: 'claude_rule_config_file',
|
|
406
|
+
},
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
catch (error) {
|
|
411
|
+
console.warn(`Error reading ${path}: ${error instanceof Error ? error.message : String(error)}`);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
// Read parent directory Claude files (for monorepo support)
|
|
415
|
+
const parentClaudeFiles = getParentClaudeFiles(PROJECT_ROOT);
|
|
416
|
+
for (const { path, file_type } of parentClaudeFiles) {
|
|
417
|
+
try {
|
|
418
|
+
const markdownContent = readMarkdownFile(path);
|
|
419
|
+
if (markdownContent !== null) { // Log even if empty
|
|
420
|
+
console.log(`Found ${file_type} at: ${path}`);
|
|
421
|
+
configFiles.push({
|
|
422
|
+
file_type,
|
|
423
|
+
file_path: path,
|
|
424
|
+
raw_content: {
|
|
425
|
+
content: markdownContent,
|
|
426
|
+
source: 'claude_rule_config_file',
|
|
427
|
+
},
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
catch (error) {
|
|
432
|
+
console.warn(`Error reading ${path}: ${error instanceof Error ? error.message : String(error)}`);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
// Read subdirectory Claude files (for monorepo support - root/subdir/CLAUDE.md)
|
|
436
|
+
const subdirectoryClaudeFiles = getSubdirectoryClaudeFiles(PROJECT_ROOT);
|
|
437
|
+
for (const { path, file_type } of subdirectoryClaudeFiles) {
|
|
438
|
+
try {
|
|
439
|
+
const markdownContent = readMarkdownFile(path);
|
|
440
|
+
if (markdownContent !== null) { // Log even if empty
|
|
441
|
+
console.log(`Found ${file_type} at: ${path}`);
|
|
442
|
+
configFiles.push({
|
|
443
|
+
file_type,
|
|
444
|
+
file_path: path,
|
|
445
|
+
raw_content: {
|
|
446
|
+
content: markdownContent,
|
|
447
|
+
source: 'claude_rule_config_file',
|
|
448
|
+
},
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
catch (error) {
|
|
453
|
+
console.warn(`Error reading ${path}: ${error instanceof Error ? error.message : String(error)}`);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
// Read Claude rule files from ~/.claude/rules/*.md
|
|
457
|
+
const claudeRuleFiles = getClaudeRuleFiles();
|
|
458
|
+
for (const { path, file_type } of claudeRuleFiles) {
|
|
459
|
+
try {
|
|
460
|
+
const markdownContent = readMarkdownFile(path);
|
|
461
|
+
if (markdownContent !== null) { // Log even if empty
|
|
462
|
+
console.log(`Found ${file_type} at: ${path}`);
|
|
463
|
+
configFiles.push({
|
|
464
|
+
file_type,
|
|
465
|
+
file_path: path,
|
|
466
|
+
raw_content: {
|
|
467
|
+
content: markdownContent,
|
|
468
|
+
source: 'claude_rule_file',
|
|
469
|
+
},
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
catch (error) {
|
|
474
|
+
console.warn(`Error reading ${path}: ${error instanceof Error ? error.message : String(error)}`);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
// Read Cursor rule files from .cursor/rules/ (new format: folders with RULE.md, legacy: .mdc/.md files)
|
|
478
|
+
const cursorRuleFiles = getCursorRuleFiles();
|
|
479
|
+
for (const { path, file_type } of cursorRuleFiles) {
|
|
480
|
+
try {
|
|
481
|
+
const markdownContent = readMarkdownFile(path);
|
|
482
|
+
if (markdownContent !== null) { // Log even if empty
|
|
483
|
+
console.log(`Found ${file_type} at: ${path}`);
|
|
484
|
+
configFiles.push({
|
|
485
|
+
file_type,
|
|
486
|
+
file_path: path,
|
|
487
|
+
raw_content: {
|
|
488
|
+
content: markdownContent,
|
|
489
|
+
source: 'cursor_rule_file',
|
|
490
|
+
},
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
catch (error) {
|
|
495
|
+
console.warn(`Error reading ${path}: ${error instanceof Error ? error.message : String(error)}`);
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
// Read AGENTS.md files (project root and subdirectories)
|
|
499
|
+
const agentsMdFiles = getAgentsMdFiles(PROJECT_ROOT);
|
|
500
|
+
for (const { path, file_type } of agentsMdFiles) {
|
|
501
|
+
try {
|
|
502
|
+
const markdownContent = readMarkdownFile(path);
|
|
503
|
+
if (markdownContent !== null) { // Log even if empty
|
|
504
|
+
console.log(`Found ${file_type} at: ${path}`);
|
|
505
|
+
configFiles.push({
|
|
506
|
+
file_type,
|
|
507
|
+
file_path: path,
|
|
508
|
+
raw_content: {
|
|
509
|
+
content: markdownContent,
|
|
510
|
+
source: 'cursor_rule_file',
|
|
511
|
+
},
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
catch (error) {
|
|
516
|
+
console.warn(`Error reading ${path}: ${error instanceof Error ? error.message : String(error)}`);
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
// Read .cursorrules file (legacy format, deprecated but still supported)
|
|
520
|
+
const cursorRulesFiles = getCursorRulesFile(PROJECT_ROOT);
|
|
521
|
+
for (const { path, file_type } of cursorRulesFiles) {
|
|
522
|
+
try {
|
|
523
|
+
const markdownContent = readMarkdownFile(path);
|
|
524
|
+
if (markdownContent !== null) { // Log even if empty
|
|
525
|
+
console.log(`Found ${file_type} at: ${path}`);
|
|
526
|
+
configFiles.push({
|
|
527
|
+
file_type,
|
|
528
|
+
file_path: path,
|
|
529
|
+
raw_content: {
|
|
530
|
+
content: markdownContent,
|
|
531
|
+
source: 'cursor_rule_file',
|
|
532
|
+
},
|
|
533
|
+
});
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
catch (error) {
|
|
537
|
+
console.warn(`Error reading ${path}: ${error instanceof Error ? error.message : String(error)}`);
|
|
538
|
+
}
|
|
539
|
+
}
|
|
188
540
|
return configFiles;
|
|
189
541
|
}
|
|
190
542
|
/**
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "log-llm-config",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
4
4
|
"description": "CLI helpers for logging hardware UUIDs and posting startup payloads to Optimus Security.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
|
-
"log-llm-config": "
|
|
8
|
-
"log_uuid": "
|
|
9
|
-
"log_config_files": "
|
|
7
|
+
"log-llm-config": "dist/cli.js",
|
|
8
|
+
"log_uuid": "dist/log_uuid.js",
|
|
9
|
+
"log_config_files": "dist/log_config_files.js"
|
|
10
10
|
},
|
|
11
11
|
"scripts": {
|
|
12
12
|
"build": "tsc -p tsconfig.json",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"license": "UNLICENSED",
|
|
27
27
|
"repository": {
|
|
28
28
|
"type": "git",
|
|
29
|
-
"url": "https://github.com/optimuslabs-io/optimus-secure-fdn.git",
|
|
29
|
+
"url": "git+https://github.com/optimuslabs-io/optimus-secure-fdn.git",
|
|
30
30
|
"directory": "npx_packages/log-llm-config"
|
|
31
31
|
},
|
|
32
32
|
"bugs": {
|
|
@@ -41,11 +41,11 @@
|
|
|
41
41
|
"node": ">=18"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
|
-
"@types/node": "^
|
|
45
|
-
"@vitest/ui": "^
|
|
44
|
+
"@types/node": "^24.10.1",
|
|
45
|
+
"@vitest/ui": "^4.0.15",
|
|
46
46
|
"ts-node": "^10.9.2",
|
|
47
47
|
"typescript": "^5.4.5",
|
|
48
|
-
"vitest": "^
|
|
48
|
+
"vitest": "^4.0.15"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
51
|
"axios": "^1.7.9"
|