@noyrax/documentation-system-plugin 1.0.4-beta.10 → 1.0.4-beta.12

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/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@noyrax/documentation-system-plugin",
3
3
  "displayName": "Noyrax",
4
4
  "description": "Documentation that never drifts. Automatic documentation generation with validation and drift detection. Generates 5-dimensional documentation structure (modules, symbols, dependencies, ADRs, changes) for codebases.",
5
- "version": "1.0.4-beta.10",
5
+ "version": "1.0.4-beta.12",
6
6
  "publisher": "noyrax",
7
7
  "repository": {
8
8
  "type": "git",
@@ -241,15 +241,87 @@ function verifyClaim(claim, workspaceRoot) {
241
241
  return true;
242
242
  }
243
243
 
244
+ /**
245
+ * Findet das docs/ Verzeichnis durch intelligente Suche.
246
+ * Sucht im gegebenen Verzeichnis und in Parent-Verzeichnissen (max. 5 Ebenen).
247
+ *
248
+ * @param startDir Das Verzeichnis, von dem aus gesucht werden soll
249
+ * @param maxDepth Maximale Anzahl von Parent-Ebenen, die durchsucht werden sollen (default: 5)
250
+ * @returns Der Pfad zum docs/ Verzeichnis oder null, wenn nicht gefunden
251
+ */
252
+ function findDocsDirectory(startDir, maxDepth = 5) {
253
+ let currentDir = path.resolve(startDir);
254
+ let depth = 0;
255
+
256
+ while (depth < maxDepth) {
257
+ const docsPath = path.join(currentDir, 'docs');
258
+ if (fs.existsSync(docsPath)) {
259
+ const stats = fs.statSync(docsPath);
260
+ if (stats.isDirectory()) {
261
+ return docsPath;
262
+ }
263
+ }
264
+
265
+ const parentDir = path.dirname(currentDir);
266
+
267
+ // Stop if we've reached the root (parent equals current)
268
+ if (parentDir === currentDir) {
269
+ break;
270
+ }
271
+
272
+ currentDir = parentDir;
273
+ depth++;
274
+ }
275
+
276
+ return null;
277
+ }
278
+
244
279
  /**
245
280
  * Hauptfunktion
246
281
  */
247
282
  function main() {
248
- const workspaceRoot = path.join(__dirname, '..');
249
- const adrDir = path.join(workspaceRoot, 'docs', 'adr');
283
+ // Workspace-Root bestimmen:
284
+ // 1. Falls als erstes Argument übergeben, verwenden
285
+ // 2. Sonst process.cwd() verwenden (wird vom MCP-Tool als cwd gesetzt)
286
+ // 3. Fallback: __dirname + '/..' (für Kompatibilität mit direktem Aufruf)
287
+ let workspaceRoot;
288
+
289
+ if (process.argv.length >= 3 && process.argv[2] !== '--' && process.argv[2] !== '--verbose') {
290
+ // Erstes Argument ist Workspace-Root (vor -- oder --verbose)
291
+ workspaceRoot = path.resolve(process.argv[2]);
292
+ // Argument aus process.argv entfernen, damit --verbose weiterhin funktioniert
293
+ process.argv.splice(2, 1);
294
+ } else {
295
+ // Standard: process.cwd() (wird vom MCP-Tool als cwd gesetzt)
296
+ workspaceRoot = process.cwd();
297
+
298
+ // Fallback: __dirname + '/..' (nur wenn process.cwd() nicht das richtige Verzeichnis ist)
299
+ // Prüfe, ob docs/ in process.cwd() gefunden werden kann
300
+ const docsFromCwd = findDocsDirectory(workspaceRoot);
301
+ if (!docsFromCwd) {
302
+ // Fallback: Versuche __dirname + '/..'
303
+ const fallbackRoot = path.join(__dirname, '..');
304
+ const docsFromFallback = findDocsDirectory(fallbackRoot);
305
+ if (docsFromFallback) {
306
+ workspaceRoot = fallbackRoot;
307
+ }
308
+ }
309
+ }
310
+
311
+ // docs/ Verzeichnis finden (intelligente Suche)
312
+ const docsPath = findDocsDirectory(workspaceRoot);
313
+ if (!docsPath) {
314
+ console.log('⚠️ ADR directory not found, skipping verification');
315
+ console.log(` Searched from: ${workspaceRoot}`);
316
+ process.exit(0);
317
+ }
318
+
319
+ const adrDir = path.join(docsPath, 'adr');
250
320
 
251
321
  if (!fs.existsSync(adrDir)) {
252
322
  console.log('⚠️ ADR directory not found, skipping verification');
323
+ console.log(` Docs directory found: ${docsPath}`);
324
+ console.log(` ADR directory expected: ${adrDir}`);
253
325
  process.exit(0);
254
326
  }
255
327
 
@@ -16,14 +16,54 @@ const { execSync } = require('child_process');
16
16
  const errors = [];
17
17
  const warnings = [];
18
18
 
19
+ /**
20
+ * Findet ein Verzeichnis durch intelligente Suche.
21
+ * Sucht im gegebenen Verzeichnis und in Parent-Verzeichnissen (max. 5 Ebenen).
22
+ *
23
+ * @param startDir Das Verzeichnis, von dem aus gesucht werden soll
24
+ * @param targetPath Relativer Pfad zum gesuchten Verzeichnis (z.B. 'mcp/src' oder 'package.json')
25
+ * @param maxDepth Maximale Anzahl von Parent-Ebenen, die durchsucht werden sollen (default: 5)
26
+ * @returns Der Pfad zum Verzeichnis/File oder null, wenn nicht gefunden
27
+ */
28
+ function findDirectoryOrFile(startDir, targetPath, maxDepth = 5) {
29
+ let currentDir = path.resolve(startDir);
30
+ let depth = 0;
31
+
32
+ while (depth < maxDepth) {
33
+ const targetFullPath = path.join(currentDir, targetPath);
34
+ if (fs.existsSync(targetFullPath)) {
35
+ return targetFullPath;
36
+ }
37
+
38
+ const parentDir = path.dirname(currentDir);
39
+
40
+ // Stop if we've reached the root (parent equals current)
41
+ if (parentDir === currentDir) {
42
+ break;
43
+ }
44
+
45
+ currentDir = parentDir;
46
+ depth++;
47
+ }
48
+
49
+ return null;
50
+ }
51
+
19
52
  /**
20
53
  * Prüft ob mcp/ direkt nach src/ importiert
21
54
  */
22
- function checkMcpToSrcImports() {
55
+ function checkMcpToSrcImports(workspaceRoot) {
23
56
  console.log('🔍 Checking for invalid imports from mcp/ to src/...');
24
57
 
25
- const mcpSrcDir = path.join(__dirname, '..', 'mcp', 'src');
26
- if (!fs.existsSync(mcpSrcDir)) {
58
+ // Suche mcp/src relativ zu workspaceRoot
59
+ let mcpSrcDir = findDirectoryOrFile(workspaceRoot, 'mcp/src');
60
+ if (!mcpSrcDir) {
61
+ // Fallback: Versuche __dirname + '/..' (Plugin-interne Suche)
62
+ const fallbackRoot = path.join(__dirname, '..');
63
+ mcpSrcDir = findDirectoryOrFile(fallbackRoot, 'mcp/src');
64
+ }
65
+
66
+ if (!mcpSrcDir) {
27
67
  console.log('⚠️ mcp/src directory not found, skipping check');
28
68
  return;
29
69
  }
@@ -82,13 +122,30 @@ function checkImportDirections() {
82
122
  /**
83
123
  * Prüft package.json type Feld
84
124
  */
85
- function checkPackageJsonType() {
125
+ function checkPackageJsonType(workspaceRoot) {
86
126
  console.log('🔍 Checking package.json type fields...');
87
127
 
88
- const rootPackageJson = path.join(__dirname, '..', 'package.json');
89
- const mcpPackageJson = path.join(__dirname, '..', 'mcp', 'package.json');
128
+ // Suche package.json relativ zu workspaceRoot
129
+ let rootPackageJson = findDirectoryOrFile(workspaceRoot, 'package.json');
130
+ if (!rootPackageJson) {
131
+ // Fallback: Versuche __dirname + '/..' (Plugin-interne Suche)
132
+ const fallbackRoot = path.join(__dirname, '..');
133
+ rootPackageJson = findDirectoryOrFile(fallbackRoot, 'package.json');
134
+ }
90
135
 
91
- if (fs.existsSync(rootPackageJson)) {
136
+ let mcpPackageJson = findDirectoryOrFile(workspaceRoot, 'mcp/package.json');
137
+ if (!mcpPackageJson && rootPackageJson) {
138
+ // Wenn rootPackageJson gefunden wurde, versuche mcp/package.json relativ dazu
139
+ const rootDir = path.dirname(rootPackageJson);
140
+ mcpPackageJson = findDirectoryOrFile(rootDir, 'mcp/package.json');
141
+ }
142
+ if (!mcpPackageJson) {
143
+ // Fallback: Versuche __dirname + '/..' (Plugin-interne Suche)
144
+ const fallbackRoot = path.join(__dirname, '..');
145
+ mcpPackageJson = findDirectoryOrFile(fallbackRoot, 'mcp/package.json');
146
+ }
147
+
148
+ if (rootPackageJson && fs.existsSync(rootPackageJson)) {
92
149
  const rootPkg = JSON.parse(fs.readFileSync(rootPackageJson, 'utf8'));
93
150
  if (!rootPkg.type) {
94
151
  console.log('✅ Root package.json has no type field (defaults to CommonJS)');
@@ -141,11 +198,39 @@ function getAllTsFiles(dir) {
141
198
  * Hauptfunktion
142
199
  */
143
200
  function main() {
201
+ // Workspace-Root bestimmen:
202
+ // 1. Falls als erstes Argument übergeben, verwenden
203
+ // 2. Sonst process.cwd() verwenden (wird vom MCP-Tool als cwd gesetzt)
204
+ // 3. Fallback: __dirname + '/..' (für Kompatibilität mit direktem Aufruf)
205
+ let workspaceRoot;
206
+
207
+ if (process.argv.length >= 3 && process.argv[2] !== '--' && process.argv[2] !== '--verbose') {
208
+ // Erstes Argument ist Workspace-Root (vor -- oder --verbose)
209
+ workspaceRoot = path.resolve(process.argv[2]);
210
+ // Argument aus process.argv entfernen, damit --verbose weiterhin funktioniert
211
+ process.argv.splice(2, 1);
212
+ } else {
213
+ // Standard: process.cwd() (wird vom MCP-Tool als cwd gesetzt)
214
+ workspaceRoot = process.cwd();
215
+
216
+ // Fallback: __dirname + '/..' (nur wenn process.cwd() nicht das richtige Verzeichnis ist)
217
+ // Prüfe, ob package.json in process.cwd() gefunden werden kann
218
+ const packageJsonFromCwd = findDirectoryOrFile(workspaceRoot, 'package.json');
219
+ if (!packageJsonFromCwd) {
220
+ // Fallback: Versuche __dirname + '/..'
221
+ const fallbackRoot = path.join(__dirname, '..');
222
+ const packageJsonFromFallback = findDirectoryOrFile(fallbackRoot, 'package.json');
223
+ if (packageJsonFromFallback) {
224
+ workspaceRoot = fallbackRoot;
225
+ }
226
+ }
227
+ }
228
+
144
229
  console.log('🚀 Starting architecture verification...\n');
145
230
 
146
- checkMcpToSrcImports();
231
+ checkMcpToSrcImports(workspaceRoot);
147
232
  checkImportDirections();
148
- checkPackageJsonType();
233
+ checkPackageJsonType(workspaceRoot);
149
234
 
150
235
  console.log('\n📊 Verification Summary:');
151
236
  console.log(` Errors: ${errors.length}`);
@@ -88,11 +88,45 @@ function extractExports(filePath) {
88
88
  return exports;
89
89
  }
90
90
 
91
+ /**
92
+ * Findet das src/ Verzeichnis durch intelligente Suche.
93
+ * Sucht im gegebenen Verzeichnis und in Parent-Verzeichnissen (max. 5 Ebenen).
94
+ *
95
+ * @param startDir Das Verzeichnis, von dem aus gesucht werden soll
96
+ * @param maxDepth Maximale Anzahl von Parent-Ebenen, die durchsucht werden sollen (default: 5)
97
+ * @returns Der Pfad zum src/ Verzeichnis oder null, wenn nicht gefunden
98
+ */
99
+ function findSrcDirectory(startDir, maxDepth = 5) {
100
+ let currentDir = path.resolve(startDir);
101
+ let depth = 0;
102
+
103
+ while (depth < maxDepth) {
104
+ const srcPath = path.join(currentDir, 'src');
105
+ if (fs.existsSync(srcPath)) {
106
+ const stats = fs.statSync(srcPath);
107
+ if (stats.isDirectory()) {
108
+ return srcPath;
109
+ }
110
+ }
111
+
112
+ const parentDir = path.dirname(currentDir);
113
+
114
+ // Stop if we've reached the root (parent equals current)
115
+ if (parentDir === currentDir) {
116
+ break;
117
+ }
118
+
119
+ currentDir = parentDir;
120
+ depth++;
121
+ }
122
+
123
+ return null;
124
+ }
125
+
91
126
  /**
92
127
  * Prüft ob ein Import verfügbar ist
93
128
  */
94
- function checkImport(importPath, importedName, fromFile) {
95
- const workspaceRoot = path.join(__dirname, '..');
129
+ function checkImport(importPath, importedName, fromFile, workspaceRoot) {
96
130
 
97
131
  // Resolve import path
98
132
  let targetFile;
@@ -196,7 +230,7 @@ function checkFileImports(filePath, workspaceRoot) {
196
230
 
197
231
  // Check each imported name
198
232
  importedNames.forEach(name => {
199
- checkImport(importPath, name, filePath);
233
+ checkImport(importPath, name, filePath, workspaceRoot);
200
234
  });
201
235
  }
202
236
  }
@@ -205,16 +239,46 @@ function checkFileImports(filePath, workspaceRoot) {
205
239
  * Hauptfunktion
206
240
  */
207
241
  function main() {
208
- const workspaceRoot = path.join(__dirname, '..');
209
-
210
- console.log('🚀 Starting import verification...\n');
242
+ // Workspace-Root bestimmen:
243
+ // 1. Falls als erstes Argument übergeben, verwenden
244
+ // 2. Sonst process.cwd() verwenden (wird vom MCP-Tool als cwd gesetzt)
245
+ // 3. Fallback: __dirname + '/..' (für Kompatibilität mit direktem Aufruf)
246
+ let workspaceRoot;
211
247
 
212
- // Check src/ directory
213
- const srcDir = path.join(workspaceRoot, 'src');
214
- if (!fs.existsSync(srcDir)) {
248
+ if (process.argv.length >= 3 && process.argv[2] !== '--' && process.argv[2] !== '--verbose') {
249
+ // Erstes Argument ist Workspace-Root (vor -- oder --verbose)
250
+ workspaceRoot = path.resolve(process.argv[2]);
251
+ // Argument aus process.argv entfernen, damit --verbose weiterhin funktioniert
252
+ process.argv.splice(2, 1);
253
+ } else {
254
+ // Standard: process.cwd() (wird vom MCP-Tool als cwd gesetzt)
255
+ workspaceRoot = process.cwd();
256
+
257
+ // Fallback: __dirname + '/..' (nur wenn process.cwd() nicht das richtige Verzeichnis ist)
258
+ // Prüfe, ob src/ in process.cwd() gefunden werden kann
259
+ const srcFromCwd = findSrcDirectory(workspaceRoot);
260
+ if (!srcFromCwd) {
261
+ // Fallback: Versuche __dirname + '/..'
262
+ const fallbackRoot = path.join(__dirname, '..');
263
+ const srcFromFallback = findSrcDirectory(fallbackRoot);
264
+ if (srcFromFallback) {
265
+ workspaceRoot = fallbackRoot;
266
+ }
267
+ }
268
+ }
269
+
270
+ // src/ Verzeichnis finden (intelligente Suche)
271
+ const srcDir = findSrcDirectory(workspaceRoot);
272
+ if (!srcDir) {
215
273
  console.log('⚠️ src/ directory not found, skipping verification');
274
+ console.log(` Searched from: ${workspaceRoot}`);
216
275
  process.exit(0);
217
276
  }
277
+
278
+ // workspaceRoot auf Basis des gefundenen src/ korrigieren
279
+ workspaceRoot = path.dirname(srcDir);
280
+
281
+ console.log('🚀 Starting import verification...\n');
218
282
 
219
283
  const files = getAllTsFiles(srcDir);
220
284
  console.log(`📁 Found ${files.length} TypeScript files\n`);