claudeos-core 1.5.0 → 1.5.1

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/CHANGELOG.md CHANGED
@@ -1,4 +1,16 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.5.1] — 2026-04-06
4
+
5
+ ### Fixed
6
+ - **Remove 13 bare catch blocks** — `catch { }` → `catch (_e) { }` across 9 files; enables error variable access during debugging
7
+ - **Windows backslash glob fix (3 locations)** — `scan-frontend.js` missing `dir.replace(/\\/g, "/")` at App/Pages Router (line 63), FSD (line 84), and components (line 98) scans; other locations already had this fix
8
+ - **Pattern C flat MyBatis XML detection** — `scan-java.js` xmlGlob now matches flat XML layout (e.g., `mapper/OrderMapper.xml`) in addition to domain subdirectory layout for Pattern C projects
9
+ - **Next.js reserved segment false positives** — Added `not-found`, `error`, `loading` to `skipPages` in `scan-frontend.js` to prevent Next.js App Router reserved directories from being detected as domains
10
+ - **cap variable shadowing** — Renamed outer-scope `cap` to `capDn` in `scan-java.js` to avoid shadowing the block-scoped `cap` in Pattern C branch
11
+
12
+ ### Changed
13
+ - **Gradle DB detection comment** — Added 2-line comment explaining postgres/sqlite exclusion rationale in `stack-detector.js` line 118
14
+
3
15
  ## [1.5.0] — 2026-04-05
4
16
  - feat: initial release claudeos-core v1.5.0
@@ -217,7 +217,7 @@ async function cmdInit(parsedArgs) {
217
217
  log(` ⏭️ pass1-${i}.json already exists, skipping`);
218
218
  continue;
219
219
  }
220
- } catch { /* malformed — re-run */ }
220
+ } catch (_e) { /* malformed — re-run */ }
221
221
  log(` ⚠️ pass1-${i}.json exists but is malformed, re-running`);
222
222
  }
223
223
 
@@ -110,7 +110,7 @@ function countFiles() {
110
110
  const scan = (dir) => {
111
111
  if (!fs.existsSync(dir)) return;
112
112
  let realDir;
113
- try { realDir = fs.realpathSync(dir); } catch { realDir = dir; }
113
+ try { realDir = fs.realpathSync(dir); } catch (_e) { realDir = dir; }
114
114
  if (visited.has(realDir)) return;
115
115
  visited.add(realDir);
116
116
  for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
@@ -50,7 +50,7 @@ async function main() {
50
50
  const pa = JSON.parse(fs.readFileSync(paPath, "utf-8"));
51
51
  detectedLanguage = pa.stack?.language || null;
52
52
  outputLang = pa.lang || "en";
53
- } catch { /* ignore */ }
53
+ } catch (_e) { /* ignore */ }
54
54
  }
55
55
 
56
56
  // Language-aware section keywords for CLAUDE.md validation
@@ -327,7 +327,7 @@ async function main() {
327
327
  const rp = path.join(GEN_DIR, "stale-report.json");
328
328
  let ex = {};
329
329
  if (fs.existsSync(rp)) {
330
- try { ex = JSON.parse(fs.readFileSync(rp, "utf-8")); } catch { ex = {}; }
330
+ try { ex = JSON.parse(fs.readFileSync(rp, "utf-8")); } catch (_e) { ex = {}; }
331
331
  }
332
332
  ex.contentValidation = { checkedAt: new Date().toISOString(), checked, errors: errors.length, warnings: warnings.length, details: { errors, warnings } };
333
333
  ex.summary = { ...ex.summary, contentErrors: errors.length, contentWarnings: warnings.length };
@@ -108,7 +108,7 @@ function main() {
108
108
  const rp = path.join(GEN, "stale-report.json");
109
109
  let ex = {};
110
110
  if (fs.existsSync(rp)) {
111
- try { ex = JSON.parse(fs.readFileSync(rp, "utf-8")); } catch { ex = {}; }
111
+ try { ex = JSON.parse(fs.readFileSync(rp, "utf-8")); } catch (_e) { ex = {}; }
112
112
  }
113
113
  ex.generatedAt = new Date().toISOString();
114
114
  ex.healthCheck = { results, status: hasErr ? "fail" : "pass" };
package/lib/safe-fs.js CHANGED
@@ -50,7 +50,7 @@ function readJsonSafe(filePath, fallback = null) {
50
50
  function existsSafe(filePath) {
51
51
  try {
52
52
  return fs.existsSync(filePath);
53
- } catch {
53
+ } catch (_e) {
54
54
  return false;
55
55
  }
56
56
  }
@@ -95,7 +95,7 @@ function statSafe(filePath) {
95
95
  bytes: s.size,
96
96
  modified: s.mtime.toISOString().split("T")[0],
97
97
  };
98
- } catch {
98
+ } catch (_e) {
99
99
  return null;
100
100
  }
101
101
  }
@@ -48,7 +48,7 @@ function stat(f) {
48
48
  function frontmatter(f) {
49
49
  try {
50
50
  return matter(fs.readFileSync(f, "utf-8")).data || {};
51
- } catch {
51
+ } catch (_e) {
52
52
  return {};
53
53
  }
54
54
  }
@@ -169,7 +169,7 @@ async function main() {
169
169
  const srPath = path.join(GEN, "stale-report.json");
170
170
  let sr = {};
171
171
  if (fs.existsSync(srPath)) {
172
- try { sr = JSON.parse(fs.readFileSync(srPath, "utf-8")); } catch { sr = {}; }
172
+ try { sr = JSON.parse(fs.readFileSync(srPath, "utf-8")); } catch (_e) { sr = {}; }
173
173
  }
174
174
  sr.generatedAt = new Date().toISOString();
175
175
  if (!sr.summary) sr.summary = {};
package/package.json CHANGED
@@ -1,87 +1,87 @@
1
- {
2
- "name": "claudeos-core",
3
- "version": "1.5.0",
4
- "description": "Auto-generate Claude Code documentation from your actual source code — Standards, Rules, Skills, and Guides tailored to your project",
5
- "main": "bin/cli.js",
6
- "bin": {
7
- "claudeos-core": "bin/cli.js"
8
- },
9
- "files": [
10
- "bin/",
11
- "lib/",
12
- "content-validator/",
13
- "health-checker/",
14
- "manifest-generator/",
15
- "pass-json-validator/",
16
- "pass-prompts/",
17
- "plan-installer/",
18
- "plan-validator/",
19
- "sync-checker/",
20
- "bootstrap.sh",
21
- "README.md",
22
- "README.ko.md",
23
- "LICENSE",
24
- "CHANGELOG.md",
25
- "CONTRIBUTING.md",
26
- "README.zh-CN.md",
27
- "README.ja.md",
28
- "README.es.md",
29
- "README.vi.md",
30
- "README.hi.md",
31
- "README.ru.md",
32
- "README.fr.md",
33
- "README.de.md"
34
- ],
35
- "scripts": {
36
- "init": "node bin/cli.js init",
37
- "health": "node bin/cli.js health",
38
- "validate": "node bin/cli.js validate",
39
- "refresh": "node bin/cli.js refresh",
40
- "restore": "node bin/cli.js restore",
41
- "test": "node --test tests/*.test.js",
42
- "test:health": "node health-checker/index.js"
43
- },
44
- "keywords": [
45
- "claude-code",
46
- "automation",
47
- "code-analysis",
48
- "CLAUDE.md",
49
- "standards",
50
- "rules",
51
- "skills",
52
- "scaffolding",
53
- "i18n",
54
- "multi-language",
55
- "spring-boot",
56
- "kotlin",
57
- "exposed",
58
- "jooq",
59
- "cqrs",
60
- "bff",
61
- "multi-module",
62
- "monorepo",
63
- "nextjs",
64
- "express",
65
- "fastify",
66
- "angular",
67
- "django",
68
- "fastapi"
69
- ],
70
- "author": "claudeos-core <claudeoscore@gmail.com> (https://github.com/claudeos-core)",
71
- "license": "ISC",
72
- "repository": {
73
- "type": "git",
74
- "url": "git+https://github.com/claudeos-core/claudeos-core.git"
75
- },
76
- "homepage": "https://github.com/claudeos-core/claudeos-core#readme",
77
- "bugs": {
78
- "url": "https://github.com/claudeos-core/claudeos-core/issues"
79
- },
80
- "engines": {
81
- "node": ">=18.0.0"
82
- },
83
- "dependencies": {
84
- "glob": "^13.0.6",
85
- "gray-matter": "^4.0.3"
86
- }
87
- }
1
+ {
2
+ "name": "claudeos-core",
3
+ "version": "1.5.1",
4
+ "description": "Auto-generate Claude Code documentation from your actual source code — Standards, Rules, Skills, and Guides tailored to your project",
5
+ "main": "bin/cli.js",
6
+ "bin": {
7
+ "claudeos-core": "bin/cli.js"
8
+ },
9
+ "files": [
10
+ "bin/",
11
+ "lib/",
12
+ "content-validator/",
13
+ "health-checker/",
14
+ "manifest-generator/",
15
+ "pass-json-validator/",
16
+ "pass-prompts/",
17
+ "plan-installer/",
18
+ "plan-validator/",
19
+ "sync-checker/",
20
+ "bootstrap.sh",
21
+ "README.md",
22
+ "README.ko.md",
23
+ "LICENSE",
24
+ "CHANGELOG.md",
25
+ "CONTRIBUTING.md",
26
+ "README.zh-CN.md",
27
+ "README.ja.md",
28
+ "README.es.md",
29
+ "README.vi.md",
30
+ "README.hi.md",
31
+ "README.ru.md",
32
+ "README.fr.md",
33
+ "README.de.md"
34
+ ],
35
+ "scripts": {
36
+ "init": "node bin/cli.js init",
37
+ "health": "node bin/cli.js health",
38
+ "validate": "node bin/cli.js validate",
39
+ "refresh": "node bin/cli.js refresh",
40
+ "restore": "node bin/cli.js restore",
41
+ "test": "node --test tests/*.test.js",
42
+ "test:health": "node health-checker/index.js"
43
+ },
44
+ "keywords": [
45
+ "claude-code",
46
+ "automation",
47
+ "code-analysis",
48
+ "CLAUDE.md",
49
+ "standards",
50
+ "rules",
51
+ "skills",
52
+ "scaffolding",
53
+ "i18n",
54
+ "multi-language",
55
+ "spring-boot",
56
+ "kotlin",
57
+ "exposed",
58
+ "jooq",
59
+ "cqrs",
60
+ "bff",
61
+ "multi-module",
62
+ "monorepo",
63
+ "nextjs",
64
+ "express",
65
+ "fastify",
66
+ "angular",
67
+ "django",
68
+ "fastapi"
69
+ ],
70
+ "author": "claudeos-core <claudeoscore@gmail.com> (https://github.com/claudeos-core)",
71
+ "license": "ISC",
72
+ "repository": {
73
+ "type": "git",
74
+ "url": "git+https://github.com/claudeos-core/claudeos-core.git"
75
+ },
76
+ "homepage": "https://github.com/claudeos-core/claudeos-core#readme",
77
+ "bugs": {
78
+ "url": "https://github.com/claudeos-core/claudeos-core/issues"
79
+ },
80
+ "engines": {
81
+ "node": ">=18.0.0"
82
+ },
83
+ "dependencies": {
84
+ "glob": "^13.0.6",
85
+ "gray-matter": "^4.0.3"
86
+ }
87
+ }
@@ -197,7 +197,7 @@ async function main() {
197
197
  isBackend = !frontend || ["express", "nestjs", "django", "fastapi", "spring-boot"].includes(framework);
198
198
  isKotlin = language === "kotlin";
199
199
  isKotlinCqrs = isKotlin && (architecture === "cqrs" || paData.stack?.multiModule);
200
- } catch { /* If project-analysis parsing fails, conservatively assume backend */ }
200
+ } catch (_e) { /* If project-analysis parsing fails, conservatively assume backend */ }
201
201
  }
202
202
 
203
203
  const sectionsToCheck = [
@@ -286,7 +286,7 @@ async function main() {
286
286
  const rp = path.join(GEN_DIR, "stale-report.json");
287
287
  let ex = {};
288
288
  if (fs.existsSync(rp)) {
289
- try { ex = JSON.parse(fs.readFileSync(rp, "utf-8")); } catch { ex = {}; }
289
+ try { ex = JSON.parse(fs.readFileSync(rp, "utf-8")); } catch (_e) { ex = {}; }
290
290
  }
291
291
  ex.jsonValidation = { checkedAt: new Date().toISOString(), checked, errors: errors.length, warnings: warnings.length };
292
292
  ex.summary = { ...ex.summary, jsonErrors: errors.length, jsonWarnings: warnings.length };
@@ -56,11 +56,11 @@ async function scanFrontendDomains(stack, ROOT) {
56
56
  ...await glob("{app,src/app}/*/", { cwd: ROOT }),
57
57
  ...await glob("{pages,src/pages}/*/", { cwd: ROOT }),
58
58
  ];
59
- const skipPages = ["api", "_app", "_document", "fonts"];
59
+ const skipPages = ["api", "_app", "_document", "fonts", "not-found", "error", "loading"];
60
60
  for (const dir of allDirs) {
61
61
  const name = path.basename(dir);
62
62
  if (skipPages.includes(name) || name.startsWith("(") || name.startsWith("[") || name.startsWith("_") || name.startsWith(".")) continue;
63
- const files = await glob(`${dir}**/*.{tsx,jsx,ts,js,vue}`, { cwd: ROOT });
63
+ const files = await glob(`${dir.replace(/\\/g, "/")}**/*.{tsx,jsx,ts,js,vue}`, { cwd: ROOT });
64
64
  if (files.length > 0) {
65
65
  const pages = files.filter(f => /page\.|index\./.test(f)).length;
66
66
  const layouts = files.filter(f => /layout\./.test(f)).length;
@@ -81,7 +81,7 @@ async function scanFrontendDomains(stack, ROOT) {
81
81
  for (const dir of fsdDirs) {
82
82
  const name = path.basename(dir);
83
83
  if (["ui", "common", "shared", "lib", "config", "index"].includes(name)) continue;
84
- const files = await glob(`${dir}**/*.{tsx,jsx,ts,js,vue}`, { cwd: ROOT, ignore: ["**/*.spec.*", "**/*.test.*", "**/*.stories.*"] });
84
+ const files = await glob(`${dir.replace(/\\/g, "/")}**/*.{tsx,jsx,ts,js,vue}`, { cwd: ROOT, ignore: ["**/*.spec.*", "**/*.test.*", "**/*.stories.*"] });
85
85
  if (files.length > 0) {
86
86
  const uiFiles = files.filter(f => /\bui\b/.test(f)).length;
87
87
  const modelFiles = files.filter(f => /model|store|hook/.test(f)).length;
@@ -95,7 +95,7 @@ async function scanFrontendDomains(stack, ROOT) {
95
95
  for (const dir of compDirs) {
96
96
  const name = path.basename(dir);
97
97
  if (["ui", "common", "shared", "layout", "icons"].includes(name)) continue;
98
- const files = await glob(`${dir}**/*.{tsx,jsx,vue}`, { cwd: ROOT });
98
+ const files = await glob(`${dir.replace(/\\/g, "/")}**/*.{tsx,jsx,vue}`, { cwd: ROOT });
99
99
  if (files.length >= 2) {
100
100
  frontendDomains.push({ name: `comp-${name}`, type: "frontend", components: files.length, totalFiles: files.length });
101
101
  }
@@ -148,7 +148,12 @@ async function scanJavaDomains(stack, ROOT) {
148
148
  dtoGlob = `src/main/java/**/dto/${cap}*.java`;
149
149
  aggGlob = `src/main/java/**/aggregator/${cap}*.java`;
150
150
  }
151
- const xmlGlob = `src/main/resources/{mapper,mybatis}/**/${dn}/*.xml`;
151
+ // Pattern C (flat): XML may be in flat directory without domain subdirectory (e.g., mapper/OrderMapper.xml)
152
+ // Other patterns: XML is in domain subdirectory (e.g., mapper/order/OrderMapper.xml)
153
+ const capDn = dn.charAt(0).toUpperCase() + dn.slice(1);
154
+ const xmlGlob = p === "C"
155
+ ? `src/main/resources/{mapper,mybatis}/**/{${dn}/${capDn}*.xml,${capDn}*.xml}`
156
+ : `src/main/resources/{mapper,mybatis}/**/${dn}/*.xml`;
152
157
 
153
158
  const svc = await glob(svcGlob, { cwd: ROOT });
154
159
  const mpr = await glob(mprGlob, { cwd: ROOT });
@@ -115,6 +115,8 @@ async function detectStack(ROOT) {
115
115
  if (jv) stack.languageVersion = jv[1];
116
116
 
117
117
  detectFirst(stack, "orm", g, GRADLE_ORM_RULES);
118
+ // Exclude "postgres" (substring of postgresql — false positive on r2dbc-postgres) and "sqlite" (rare in Gradle deps)
119
+ // "postgresql" is still matched via DB_KEYWORD_RULES; h2 uses word-boundary check separately
118
120
  detectDb(stack, g, DB_KEYWORD_RULES.filter(([kw]) => !["postgres", "sqlite"].includes(kw)));
119
121
 
120
122
  // Kotlin detection: override language if Kotlin plugin found
@@ -247,7 +247,7 @@ async function main() {
247
247
  const rp = path.join(GEN, "stale-report.json");
248
248
  let ex = {};
249
249
  if (fs.existsSync(rp)) {
250
- try { ex = JSON.parse(fs.readFileSync(rp, "utf-8")); } catch { ex = {}; }
250
+ try { ex = JSON.parse(fs.readFileSync(rp, "utf-8")); } catch (_e) { ex = {}; }
251
251
  }
252
252
  ex.planValidation = { checkedAt: new Date().toISOString(), mode, total, synced, drift, missing };
253
253
  if (!ex.summary) ex.summary = {};
@@ -109,7 +109,7 @@ async function main() {
109
109
  const rp = path.join(GEN, "stale-report.json");
110
110
  let ex = {};
111
111
  if (fs.existsSync(rp)) {
112
- try { ex = JSON.parse(fs.readFileSync(rp, "utf-8")); } catch { ex = {}; }
112
+ try { ex = JSON.parse(fs.readFileSync(rp, "utf-8")); } catch (_e) { ex = {}; }
113
113
  }
114
114
  ex.syncMisses = {
115
115
  checkedAt: new Date().toISOString(),