claudeos-core 1.2.4 → 1.3.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.

Potentially problematic release.


This version of claudeos-core might be problematic. Click here for more details.

Files changed (44) hide show
  1. package/CHANGELOG.md +65 -0
  2. package/README.de.md +41 -6
  3. package/README.es.md +42 -6
  4. package/README.fr.md +42 -6
  5. package/README.hi.md +42 -6
  6. package/README.ja.md +43 -6
  7. package/README.ko.md +42 -6
  8. package/README.md +53 -11
  9. package/README.ru.md +42 -6
  10. package/README.vi.md +42 -6
  11. package/README.zh-CN.md +42 -6
  12. package/bin/cli.js +171 -36
  13. package/bootstrap.sh +71 -23
  14. package/content-validator/index.js +9 -4
  15. package/health-checker/index.js +4 -3
  16. package/lib/safe-fs.js +110 -0
  17. package/manifest-generator/index.js +13 -7
  18. package/package.json +4 -2
  19. package/pass-json-validator/index.js +3 -5
  20. package/pass-prompts/templates/java-spring/pass1.md +3 -0
  21. package/pass-prompts/templates/java-spring/pass2.md +3 -3
  22. package/pass-prompts/templates/java-spring/pass3.md +17 -0
  23. package/pass-prompts/templates/kotlin-spring/pass1.md +3 -0
  24. package/pass-prompts/templates/kotlin-spring/pass2.md +5 -5
  25. package/pass-prompts/templates/kotlin-spring/pass3.md +17 -0
  26. package/pass-prompts/templates/node-express/pass1.md +3 -0
  27. package/pass-prompts/templates/node-express/pass2.md +4 -1
  28. package/pass-prompts/templates/node-express/pass3.md +20 -1
  29. package/pass-prompts/templates/node-nextjs/pass1.md +13 -3
  30. package/pass-prompts/templates/node-nextjs/pass2.md +6 -4
  31. package/pass-prompts/templates/node-nextjs/pass3.md +20 -1
  32. package/pass-prompts/templates/python-django/pass1.md +3 -1
  33. package/pass-prompts/templates/python-django/pass2.md +4 -4
  34. package/pass-prompts/templates/python-django/pass3.md +18 -0
  35. package/pass-prompts/templates/python-fastapi/pass1.md +3 -0
  36. package/pass-prompts/templates/python-fastapi/pass2.md +4 -4
  37. package/pass-prompts/templates/python-fastapi/pass3.md +18 -0
  38. package/plan-installer/domain-grouper.js +74 -0
  39. package/plan-installer/index.js +35 -1305
  40. package/plan-installer/prompt-generator.js +99 -0
  41. package/plan-installer/stack-detector.js +326 -0
  42. package/plan-installer/structure-scanner.js +783 -0
  43. package/plan-validator/index.js +84 -20
  44. package/sync-checker/index.js +7 -3
package/bootstrap.sh CHANGED
@@ -23,6 +23,9 @@ GENERATED_DIR="$PROJECT_ROOT/claudeos-core/generated"
23
23
 
24
24
  cd "$PROJECT_ROOT"
25
25
 
26
+ # Cleanup temp files on exit (Ctrl+C, errors, etc.)
27
+ trap 'rm -f "$GENERATED_DIR"/_tmp_*.md "$GENERATED_DIR"/_tmp_*.md.final 2>/dev/null' EXIT
28
+
26
29
  # ─── Language selection (required) ──────────────────────────────
27
30
  SUPPORTED_LANGS=("en" "ko" "zh-CN" "ja" "es" "vi" "hi" "ru" "fr" "de")
28
31
  LANG_LABELS=("English" "한국어 (Korean)" "简体中文 (Chinese Simplified)" "日本語 (Japanese)" "Español (Spanish)" "Tiếng Việt (Vietnamese)" "हिन्दी (Hindi)" "Русский (Russian)" "Français (French)" "Deutsch (German)")
@@ -32,7 +35,7 @@ CLAUDEOS_LANG=""
32
35
  # Parse --lang argument
33
36
  while [[ $# -gt 0 ]]; do
34
37
  case $1 in
35
- --lang) CLAUDEOS_LANG="$2"; shift 2 ;;
38
+ --lang) [ -z "$2" ] && echo " ❌ --lang requires a value" && exit 1; CLAUDEOS_LANG="$2"; shift 2 ;;
36
39
  --lang=*) CLAUDEOS_LANG="${1#*=}"; shift ;;
37
40
  *) echo "⚠️ Unknown argument: $1 (ignored)"; shift ;;
38
41
  esac
@@ -42,17 +45,21 @@ done
42
45
  if [ -z "$CLAUDEOS_LANG" ]; then
43
46
  echo ""
44
47
  echo "╔══════════════════════════════════════════════════╗"
45
- echo "║ Select output language (required) ║"
48
+ echo "║ Select generated document language (required) ║"
46
49
  echo "╚══════════════════════════════════════════════════╝"
47
50
  echo ""
51
+ echo " Generated files (CLAUDE.md, Standards, Rules,"
52
+ echo " Skills, Guides) will be written in this language."
53
+ echo ""
48
54
  for i in "${!SUPPORTED_LANGS[@]}"; do
49
55
  printf " %2d. %-6s — %s\n" "$((i+1))" "${SUPPORTED_LANGS[$i]}" "${LANG_LABELS[$i]}"
50
56
  done
51
57
  echo ""
52
- read -p " Enter number (1-10) or language code: " LANG_INPUT
58
+ LANG_COUNT=${#SUPPORTED_LANGS[@]}
59
+ read -rp " Enter number (1-${LANG_COUNT}) or language code: " LANG_INPUT
53
60
 
54
61
  # Accept number
55
- if [[ "$LANG_INPUT" =~ ^[0-9]+$ ]] && [ "$LANG_INPUT" -ge 1 ] && [ "$LANG_INPUT" -le 10 ]; then
62
+ if [[ "$LANG_INPUT" =~ ^[0-9]+$ ]] && [ "$LANG_INPUT" -ge 1 ] && [ "$LANG_INPUT" -le "$LANG_COUNT" ]; then
56
63
  CLAUDEOS_LANG="${SUPPORTED_LANGS[$((LANG_INPUT-1))]}"
57
64
  else
58
65
  # Accept language code
@@ -76,12 +83,42 @@ fi
76
83
  export CLAUDEOS_LANG
77
84
  export CLAUDEOS_ROOT="$PROJECT_ROOT"
78
85
 
79
- # ─── Prompt placeholder substitution helper ────────────────────
80
- inject_project_root() {
81
- # Use perl with $ENV{} to avoid sed metachar issues with &, \, etc. in paths
82
- export _PROJECT_ROOT="$PROJECT_ROOT"
83
- perl -pe 's/\{\{PROJECT_ROOT\}\}/$ENV{_PROJECT_ROOT}/g'
84
- }
86
+ # ─── Prerequisites check ──────────────────────────────────────
87
+ if ! command -v node &> /dev/null; then
88
+ echo ""
89
+ echo " ❌ Node.js not found."
90
+ echo " Install: https://nodejs.org/"
91
+ echo ""
92
+ exit 1
93
+ fi
94
+
95
+ NODE_MAJOR=$(node -e "console.log(process.versions.node.split('.')[0])")
96
+ if ! [[ "$NODE_MAJOR" =~ ^[0-9]+$ ]] || [ "$NODE_MAJOR" -lt 18 ]; then
97
+ echo ""
98
+ echo " ❌ Node.js v18+ required (current: v$(node --version))"
99
+ echo " Install: https://nodejs.org/"
100
+ echo ""
101
+ exit 1
102
+ fi
103
+
104
+ if ! command -v claude &> /dev/null; then
105
+ echo ""
106
+ echo " ❌ Claude Code CLI not found."
107
+ echo " Install: https://code.claude.com/docs/en/overview"
108
+ echo " Then run: claude (and complete authentication)"
109
+ echo ""
110
+ exit 1
111
+ fi
112
+
113
+ if ! command -v perl &> /dev/null; then
114
+ echo ""
115
+ echo " ❌ perl not found (required for placeholder substitution)."
116
+ echo " Install perl or use the Node.js CLI instead: npx claudeos-core init"
117
+ echo ""
118
+ exit 1
119
+ fi
120
+
121
+
85
122
 
86
123
  echo ""
87
124
  echo "╔════════════════════════════════════════════════════╗"
@@ -176,24 +213,25 @@ for i in $(seq 1 "$TOTAL_GROUPS"); do
176
213
  if [ ! -f "$PROMPT_FILE" ]; then
177
214
  PROMPT_FILE="$GENERATED_DIR/pass1-prompt.md"
178
215
  fi
179
- PASS1_TEMPLATE=$(cat "$PROMPT_FILE")
180
-
181
- # Substitute placeholders via temp file (avoids sed special char issues with &, \, etc.)
216
+ # Substitute placeholders via temp file (avoids sed special char issues and $() newline stripping)
182
217
  TMP_PROMPT="$GENERATED_DIR/_tmp_pass1_prompt.md"
183
- printf '%s' "$PASS1_TEMPLATE" > "$TMP_PROMPT"
218
+ cp "$PROMPT_FILE" "$TMP_PROMPT"
184
219
  # Use perl with $ENV{} for safe literal replacement (no shell interpolation into Perl code)
185
220
  export _DOMAIN_LIST="$DOMAIN_LIST"
186
221
  export _PASS_NUM="$i"
187
222
  perl -pi -e 's/\{\{DOMAIN_GROUP\}\}/$ENV{_DOMAIN_LIST}/g' "$TMP_PROMPT"
188
223
  perl -pi -e 's/\{\{PASS_NUM\}\}/$ENV{_PASS_NUM}/g' "$TMP_PROMPT"
189
- # inject_project_root uses perl with $ENV{} which is safe for special chars in paths
190
- PASS1_PROMPT=$(cat "$TMP_PROMPT" | inject_project_root)
191
- rm -f "$TMP_PROMPT"
224
+ # inject_project_root: pipe through perl, write to final temp file
225
+ export _PROJECT_ROOT="$PROJECT_ROOT"
226
+ perl -pe 's/\{\{PROJECT_ROOT\}\}/$ENV{_PROJECT_ROOT}/g' "$TMP_PROMPT" > "${TMP_PROMPT}.final"
227
+ mv "${TMP_PROMPT}.final" "$TMP_PROMPT"
192
228
 
193
- if ! (cd "$PROJECT_ROOT" && claude -p "$PASS1_PROMPT" --dangerously-skip-permissions); then
229
+ if ! (cd "$PROJECT_ROOT" && cat "$TMP_PROMPT" | claude -p --dangerously-skip-permissions); then
230
+ rm -f "$TMP_PROMPT"
194
231
  echo " ❌ Pass 1-${i} failed. Aborting."
195
232
  exit 1
196
233
  fi
234
+ rm -f "$TMP_PROMPT"
197
235
 
198
236
  # Verify JSON was created
199
237
  if [ ! -f "$GENERATED_DIR/pass1-${i}.json" ]; then
@@ -203,6 +241,7 @@ for i in $(seq 1 "$TOTAL_GROUPS"); do
203
241
 
204
242
  echo " ✅ pass1-${i}.json created"
205
243
  done
244
+ unset _DOMAIN_LIST _PASS_NUM _PROJECT_ROOT
206
245
  echo ""
207
246
 
208
247
  # ─── [5] Pass 2: Merge analysis results ─────────────────────────
@@ -213,12 +252,16 @@ echo "━━━━━━━━━━━━━━━━━━━━━━━━
213
252
  if [ -f "$GENERATED_DIR/pass2-merged.json" ]; then
214
253
  echo " ⏭️ pass2-merged.json already exists, skipping"
215
254
  else
216
- PASS2_PROMPT=$(cat "$GENERATED_DIR/pass2-prompt.md" | inject_project_root)
255
+ TMP_PASS2="$GENERATED_DIR/_tmp_pass2_prompt.md"
256
+ export _PROJECT_ROOT="$PROJECT_ROOT"
257
+ perl -pe 's/\{\{PROJECT_ROOT\}\}/$ENV{_PROJECT_ROOT}/g' "$GENERATED_DIR/pass2-prompt.md" > "$TMP_PASS2"
217
258
 
218
- if ! (cd "$PROJECT_ROOT" && claude -p "$PASS2_PROMPT" --dangerously-skip-permissions); then
259
+ if ! (cd "$PROJECT_ROOT" && cat "$TMP_PASS2" | claude -p --dangerously-skip-permissions); then
260
+ rm -f "$TMP_PASS2"
219
261
  echo " ❌ Pass 2 failed. Aborting."
220
262
  exit 1
221
263
  fi
264
+ rm -f "$TMP_PASS2"
222
265
 
223
266
  if [ ! -f "$GENERATED_DIR/pass2-merged.json" ]; then
224
267
  echo " ❌ pass2-merged.json was not created. Aborting."
@@ -233,17 +276,22 @@ echo ""
233
276
  echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
234
277
  echo "[6] Pass 3 — Generating all files..."
235
278
  echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
236
- PASS3_PROMPT=$(cat "$GENERATED_DIR/pass3-prompt.md" | inject_project_root)
279
+ TMP_PASS3="$GENERATED_DIR/_tmp_pass3_prompt.md"
280
+ export _PROJECT_ROOT="$PROJECT_ROOT"
281
+ perl -pe 's/\{\{PROJECT_ROOT\}\}/$ENV{_PROJECT_ROOT}/g' "$GENERATED_DIR/pass3-prompt.md" > "$TMP_PASS3"
237
282
 
238
- if ! (cd "$PROJECT_ROOT" && claude -p "$PASS3_PROMPT" --dangerously-skip-permissions); then
283
+ if ! (cd "$PROJECT_ROOT" && cat "$TMP_PASS3" | claude -p --dangerously-skip-permissions); then
284
+ rm -f "$TMP_PASS3"
239
285
  echo " ❌ Pass 3 failed. Aborting."
240
286
  exit 1
241
287
  fi
288
+ rm -f "$TMP_PASS3"
242
289
 
243
290
  if [ ! -f "$PROJECT_ROOT/CLAUDE.md" ]; then
244
291
  echo " ❌ CLAUDE.md was not created. Pass 3 may have failed silently."
245
292
  exit 1
246
293
  fi
294
+ unset _PROJECT_ROOT
247
295
  echo ""
248
296
 
249
297
  # ─── [7] Run verification tools ───────────────────────────────
@@ -271,7 +319,7 @@ fi
271
319
  echo ""
272
320
 
273
321
  # ─── Complete ───────────────────────────────────────────────
274
- TOTAL_FILES=$(find .claude claudeos-core -type f 2>/dev/null | grep -v node_modules | wc -l | tr -d ' ')
322
+ TOTAL_FILES=$(find .claude claudeos-core -type f 2>/dev/null | grep -v '/node_modules/' | grep -v '/generated/' | wc -l | tr -d ' ')
275
323
  TOTAL_GROUPS_DONE=$TOTAL_GROUPS
276
324
  PASS1_FILES=$(ls -1 "$GENERATED_DIR"/pass1-*.json 2>/dev/null | wc -l | tr -d ' ')
277
325
 
@@ -33,9 +33,9 @@ const GEN_DIR = path.join(ROOT, "claudeos-core/generated");
33
33
  function rel(p) { return path.relative(ROOT, p).replace(/\\/g, "/"); }
34
34
 
35
35
  async function main() {
36
- console.log("\n╔══════════════════════════════════════╗");
36
+ console.log("\n╔═══════════════════════════════════════╗");
37
37
  console.log("║ ClaudeOS-Core — Content Validator ║");
38
- console.log("╚══════════════════════════════════════╝\n");
38
+ console.log("╚═══════════════════════════════════════╝\n");
39
39
 
40
40
  const errors = [];
41
41
  const warnings = [];
@@ -83,7 +83,10 @@ async function main() {
83
83
  const enKeywords = SECTION_KEYWORDS.en;
84
84
  for (let i = 0; i < enKeywords.length; i++) {
85
85
  const candidates = [enKeywords[i], langKeywords[i]].filter(Boolean);
86
- const found = candidates.some(kw => content.toLowerCase().includes(kw.toLowerCase()));
86
+ const found = candidates.some(kw => {
87
+ const re = new RegExp(`(^|#|\\s)${kw.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}`, "im");
88
+ return re.test(content);
89
+ });
87
90
  if (!found) {
88
91
  warnings.push({ file: "CLAUDE.md", type: "MISSING_SECTION", msg: `'${enKeywords[i]}' / '${langKeywords[i]}' section is missing` });
89
92
  }
@@ -164,7 +167,9 @@ async function main() {
164
167
  if (!badKeywords.some(kw => c.includes(kw))) {
165
168
  warnings.push({ file: r, type: "NO_BAD_EXAMPLE", msg: "No incorrect example (❌) found" });
166
169
  }
167
- if (!c.includes("|") && !c.includes("rule") && !c.includes("Rule") && !c.includes("table")) {
170
+ // Check for markdown table: at least one line with | col | col | pattern
171
+ const hasMarkdownTable = /\|.+\|.+\|/.test(c);
172
+ if (!hasMarkdownTable) {
168
173
  warnings.push({ file: r, type: "NO_TABLE", msg: "Rules summary table appears to be missing" });
169
174
  }
170
175
  // Kotlin code block check: core and backend standard files should contain ```kotlin blocks
@@ -36,9 +36,9 @@ function run(name, script) {
36
36
  }
37
37
 
38
38
  function main() {
39
- console.log("\n╔══════════════════════════════════════╗");
39
+ console.log("\n╔═══════════════════════════════════════╗");
40
40
  console.log("║ ClaudeOS-Core — Health Checker ║");
41
- console.log("╚══════════════════════════════════════╝\n");
41
+ console.log("╚═══════════════════════════════════════╝\n");
42
42
 
43
43
  // ─── [0] Run manifest-generator first (prerequisite) ──────────────────
44
44
  // Must run first because sync-checker reads sync-map.json
@@ -112,10 +112,11 @@ function main() {
112
112
  }
113
113
  ex.generatedAt = new Date().toISOString();
114
114
  ex.healthCheck = { results, status: hasErr ? "fail" : "pass" };
115
+ if (!ex.summary) ex.summary = {};
115
116
  ex.summary = {
116
117
  ...ex.summary,
117
118
  totalIssues: results.filter((r) => r.status === "fail").length,
118
- status: hasErr ? "fail" : "ok",
119
+ healthStatus: hasErr ? "fail" : "ok",
119
120
  };
120
121
  fs.writeFileSync(rp, JSON.stringify(ex, null, 2));
121
122
  }
package/lib/safe-fs.js ADDED
@@ -0,0 +1,110 @@
1
+ /**
2
+ * ClaudeOS-Core — Safe filesystem utilities
3
+ *
4
+ * Wraps fs operations with consistent error handling.
5
+ * All read functions return a fallback value on failure instead of throwing.
6
+ */
7
+
8
+ const fs = require("fs");
9
+ const path = require("path");
10
+
11
+ /**
12
+ * Safely read a file as UTF-8 string.
13
+ * @param {string} filePath
14
+ * @param {string} [fallback=""] - returned on error
15
+ * @returns {string}
16
+ */
17
+ function readFileSafe(filePath, fallback = "") {
18
+ try {
19
+ return fs.readFileSync(filePath, "utf-8");
20
+ } catch (e) {
21
+ if (e.code !== "ENOENT") {
22
+ console.warn(` ⚠️ Cannot read ${path.basename(filePath)}: ${e.code || e.message}`);
23
+ }
24
+ return fallback;
25
+ }
26
+ }
27
+
28
+ /**
29
+ * Safely parse a JSON file.
30
+ * @param {string} filePath
31
+ * @param {*} [fallback=null] - returned on error
32
+ * @returns {*}
33
+ */
34
+ function readJsonSafe(filePath, fallback = null) {
35
+ const raw = readFileSafe(filePath, null);
36
+ if (raw === null) return fallback;
37
+ try {
38
+ return JSON.parse(raw);
39
+ } catch (e) {
40
+ console.warn(` ⚠️ JSON parse error in ${path.basename(filePath)}: ${e.message}`);
41
+ return fallback;
42
+ }
43
+ }
44
+
45
+ /**
46
+ * Check if a file exists (swallows permission errors).
47
+ * @param {string} filePath
48
+ * @returns {boolean}
49
+ */
50
+ function existsSafe(filePath) {
51
+ try {
52
+ return fs.existsSync(filePath);
53
+ } catch {
54
+ return false;
55
+ }
56
+ }
57
+
58
+ /**
59
+ * Ensure a directory exists (recursive).
60
+ * @param {string} dir
61
+ */
62
+ function ensureDir(dir) {
63
+ if (!fs.existsSync(dir)) {
64
+ fs.mkdirSync(dir, { recursive: true });
65
+ }
66
+ }
67
+
68
+ /**
69
+ * Write a file with error reporting.
70
+ * @param {string} filePath
71
+ * @param {string} content
72
+ * @returns {boolean} success
73
+ */
74
+ function writeFileSafe(filePath, content) {
75
+ try {
76
+ fs.writeFileSync(filePath, content);
77
+ return true;
78
+ } catch (e) {
79
+ console.error(` ❌ Cannot write ${path.basename(filePath)}: ${e.code || e.message}`);
80
+ return false;
81
+ }
82
+ }
83
+
84
+ /**
85
+ * Get file stat safely.
86
+ * @param {string} filePath
87
+ * @returns {{ lines: number, bytes: number, modified: string } | null}
88
+ */
89
+ function statSafe(filePath) {
90
+ try {
91
+ const c = fs.readFileSync(filePath, "utf-8");
92
+ const s = fs.statSync(filePath);
93
+ return {
94
+ lines: c.split("\n").length,
95
+ bytes: s.size,
96
+ modified: s.mtime.toISOString().split("T")[0],
97
+ };
98
+ } catch {
99
+ return null;
100
+ }
101
+ }
102
+
103
+ module.exports = {
104
+ readFileSafe,
105
+ readJsonSafe,
106
+ existsSafe,
107
+ ensureDir,
108
+ writeFileSafe,
109
+ statSafe,
110
+ };
@@ -67,9 +67,9 @@ function extractFileBlocks(f) {
67
67
  }
68
68
 
69
69
  async function main() {
70
- console.log("\n╔══════════════════════════════════════╗");
70
+ console.log("\n╔═══════════════════════════════════════╗");
71
71
  console.log("║ ClaudeOS-Core — Manifest Generator ║");
72
- console.log("╚══════════════════════════════════════╝\n");
72
+ console.log("╚═══════════════════════════════════════╝\n");
73
73
 
74
74
  if (!fs.existsSync(GEN)) fs.mkdirSync(GEN, { recursive: true });
75
75
 
@@ -142,11 +142,17 @@ async function main() {
142
142
  fs.writeFileSync(path.join(GEN, "plan-manifest.json"), JSON.stringify(pm, null, 2));
143
143
  console.log(` ✅ plan-manifest.json — ${pm.plans.length} plans`);
144
144
 
145
- // ─── Initialize stale-report.json ──────────────────────────
146
- fs.writeFileSync(
147
- path.join(GEN, "stale-report.json"),
148
- JSON.stringify({ generatedAt: new Date().toISOString(), summary: { totalIssues: 0, status: "initial" } }, null, 2)
149
- );
145
+ // ─── Initialize stale-report.json (preserve existing sub-tool results) ──
146
+ const srPath = path.join(GEN, "stale-report.json");
147
+ let sr = {};
148
+ if (fs.existsSync(srPath)) {
149
+ try { sr = JSON.parse(fs.readFileSync(srPath, "utf-8")); } catch { sr = {}; }
150
+ }
151
+ sr.generatedAt = new Date().toISOString();
152
+ if (!sr.summary) sr.summary = {};
153
+ sr.summary.totalIssues = 0;
154
+ sr.summary.status = "initial";
155
+ fs.writeFileSync(srPath, JSON.stringify(sr, null, 2));
150
156
  console.log(" ✅ stale-report.json — initialized");
151
157
  console.log("\n 📁 Output: claudeos-core/generated/ (4 files)\n");
152
158
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claudeos-core",
3
- "version": "1.2.4",
3
+ "version": "1.3.0",
4
4
  "description": "Auto-generate Claude Code documentation from your actual source code — Standards, Rules, Skills, and Guides tailored to your project",
5
5
  "main": "bin/cli.js",
6
6
  "bin": {
@@ -8,6 +8,7 @@
8
8
  },
9
9
  "files": [
10
10
  "bin/",
11
+ "lib/",
11
12
  "content-validator/",
12
13
  "health-checker/",
13
14
  "manifest-generator/",
@@ -37,7 +38,8 @@
37
38
  "validate": "node bin/cli.js validate",
38
39
  "refresh": "node bin/cli.js refresh",
39
40
  "restore": "node bin/cli.js restore",
40
- "test": "node health-checker/index.js"
41
+ "test": "node --test tests/*.test.js",
42
+ "test:health": "node health-checker/index.js"
41
43
  },
42
44
  "keywords": [
43
45
  "claude-code",
@@ -24,9 +24,9 @@ const GEN_DIR = path.join(ROOT, "claudeos-core/generated");
24
24
  function rel(p) { return path.relative(ROOT, p).replace(/\\/g, "/"); }
25
25
 
26
26
  async function main() {
27
- console.log("\n╔══════════════════════════════════════╗");
27
+ console.log("\n╔═══════════════════════════════════════╗");
28
28
  console.log("║ ClaudeOS-Core — Pass JSON Validator ║");
29
- console.log("╚══════════════════════════════════════╝\n");
29
+ console.log("╚═══════════════════════════════════════╝\n");
30
30
 
31
31
  if (!fs.existsSync(GEN_DIR)) {
32
32
  console.log(" ❌ claudeos-core/generated/ directory not found\n");
@@ -111,9 +111,7 @@ async function main() {
111
111
 
112
112
  // ─── 3. pass1-*.json ──────────────────────────────────
113
113
  console.log(" [3/4] pass1-*.json...");
114
- const pass1Files = await glob("pass1-*.json", { cwd: GEN_DIR, absolute: true });
115
- // Exclude pass1-prompt.md
116
- const pass1JsonFiles = pass1Files.filter(f => f.endsWith(".json"));
114
+ const pass1JsonFiles = await glob("pass1-*.json", { cwd: GEN_DIR, absolute: true });
117
115
  if (pass1JsonFiles.length === 0) {
118
116
  warnings.push({ file: "pass1-*.json", type: "NO_FILES", msg: "No pass1 JSON found (not yet executed?)" });
119
117
  }
@@ -12,6 +12,7 @@ Analysis items (per domain):
12
12
  - URL patterns (RESTful conventions, naming conventions, versioning)
13
13
  - Parameter binding (@RequestBody, @PathVariable, @RequestParam, @ModelAttribute, @RequestHeader)
14
14
  - Response format (ResponseEntity, custom response wrappers, direct return)
15
+ - If a custom response wrapper class exists, record its EXACT class name, EXACT method signatures (e.g., `success()`, `error()`), and EXACT import path. Do NOT guess or invent method names — read the actual source.
15
16
  - Error handling (try-catch patterns, @ExceptionHandler, @ControllerAdvice)
16
17
  - Authentication/authorization (@AuthenticationPrincipal, @PreAuthorize, SecurityContext)
17
18
  - API documentation (Swagger/SpringDoc annotations)
@@ -47,6 +48,8 @@ Analysis items (per domain):
47
48
  - Field type conventions (Boolean handling, date types, Enum management)
48
49
  - Validation annotations (@NotNull, @NotBlank, @Size, @Pattern, custom)
49
50
  - Conversion approach (MapStruct, ModelMapper, manual conversion)
51
+ - Import paths: record EXACT package paths for shared/utility classes
52
+ - Utility class locations: record EXACT package where shared utilities live
50
53
 
51
54
  5. Interceptor/Filter/AOP Patterns
52
55
  - HandlerInterceptor usage
@@ -35,9 +35,9 @@ Merge items:
35
35
  - DB table/column naming
36
36
 
37
37
  6. Common Classes/Utilities List
38
- - Base class fields (must not be redeclared)
39
- - Shared utility classes
40
- - Constants/Enum management approach
38
+ - Base class fields (must not be redeclared) with EXACT fully-qualified class names
39
+ - Shared utility classes with EXACT package paths (e.g., `com.company.common.util.DateUtils`)
40
+ - Constants/Enum management approach with EXACT locations
41
41
 
42
42
  7. Security/Authentication Patterns
43
43
  - Authentication method (JWT, Session, OAuth2)
@@ -4,6 +4,23 @@ generate all ClaudeOS-Core files based on the analysis results.
4
4
 
5
5
  Do not read the original source code again. Reference only the analysis results.
6
6
 
7
+ CRITICAL — Build Tool Consistency:
8
+ Check `stack.buildTool` and `stack.packageManager` in project-analysis.json.
9
+ ALL generated files MUST use the detected build tool's commands (e.g., Gradle or Maven).
10
+ NEVER mix Gradle/Maven commands. Also verify actual task names from build files.
11
+
12
+ CRITICAL — Cross-file Consistency:
13
+ Rules (.claude/rules/) and Standards (claudeos-core/standard/) MUST NOT contradict each other.
14
+ If a standard defines a specific pattern (e.g., import path, file naming, API usage),
15
+ the corresponding rule MUST use the same pattern. Before generating each rule file,
16
+ verify it is consistent with the related standard file.
17
+
18
+ CRITICAL — CLAUDE.md Reference Table Completeness:
19
+ The reference table in CLAUDE.md MUST list ALL generated standard files, not just core.
20
+ Include all backend-api, security-db, infra, and verification standards.
21
+ Alternatively, add a note directing readers to .claude/rules/00.core/00.standard-reference.md
22
+ for the complete list.
23
+
7
24
  Generation targets:
8
25
 
9
26
  1. CLAUDE.md (project root)
@@ -14,6 +14,7 @@ Analysis items (per domain):
14
14
  - URL patterns (RESTful conventions, naming, versioning)
15
15
  - Parameter binding (@RequestBody, @PathVariable, @RequestParam, @ModelAttribute)
16
16
  - Response format (ResponseEntity, custom response wrappers, sealed class responses)
17
+ - If a custom response wrapper class exists, record its EXACT class name, EXACT method signatures (e.g., `success()`, `error()`), and EXACT import path. Do NOT guess or invent method names — read the actual source.
17
18
  - Error handling (try-catch, @ExceptionHandler, @ControllerAdvice, Result/Either pattern)
18
19
  - Authentication/authorization (@AuthenticationPrincipal, @PreAuthorize, SecurityContext)
19
20
  - API documentation (Swagger/SpringDoc annotations)
@@ -61,6 +62,8 @@ Analysis items (per domain):
61
62
  - Validation annotations (@field:NotNull, @field:NotBlank, @field:Size, custom)
62
63
  - Conversion approach (mapstruct-kotlin, manual extension functions, toEntity/toDto)
63
64
  - Serialization (Jackson Kotlin module, kotlinx.serialization)
65
+ - Import paths: record EXACT package paths for shared classes (e.g., `com.company.shared.util.DateUtils`, not an invented path)
66
+ - Utility class locations: record EXACT module and package where shared utilities live
64
67
 
65
68
  6. Aggregate/Aggregate Root Patterns
66
69
  - Aggregate boundary definition (which entities belong together)
@@ -43,11 +43,11 @@ Merge items:
43
43
  - Module naming conventions (what suffix: -server, -lib, -adapter)
44
44
 
45
45
  6. Common Classes/Utilities List
46
- - Shared library (shared-lib) key classes and utilities
47
- - Integration library (integration-lib) contracts and adapters
48
- - Base classes (must not be redeclared)
49
- - Shared constants/Enum management
50
- - Common extension functions
46
+ - Shared library (shared-lib) key classes and utilities with EXACT package paths (e.g., `com.company.shared.util.DateUtils`)
47
+ - Integration library (integration-lib) contracts and adapters with EXACT package paths
48
+ - Base classes (must not be redeclared) with EXACT fully-qualified class names
49
+ - Shared constants/Enum management with EXACT locations
50
+ - Common extension functions with EXACT file locations
51
51
 
52
52
  7. BFF Patterns Summary
53
53
  - Feign Client declaration conventions
@@ -4,6 +4,23 @@ generate all ClaudeOS-Core files based on the analysis results.
4
4
 
5
5
  Do not read the original source code again. Reference only the analysis results.
6
6
 
7
+ CRITICAL — Build Tool Consistency:
8
+ Check `stack.buildTool` and `stack.packageManager` in project-analysis.json.
9
+ ALL generated files MUST use the detected build tool's commands (e.g., Gradle tasks).
10
+ NEVER mix Gradle/Maven commands. Also verify actual task names from build.gradle(.kts).
11
+
12
+ CRITICAL — Cross-file Consistency:
13
+ Rules (.claude/rules/) and Standards (claudeos-core/standard/) MUST NOT contradict each other.
14
+ If a standard defines a specific pattern (e.g., import path, file naming, API usage),
15
+ the corresponding rule MUST use the same pattern. Before generating each rule file,
16
+ verify it is consistent with the related standard file.
17
+
18
+ CRITICAL — CLAUDE.md Reference Table Completeness:
19
+ The reference table in CLAUDE.md MUST list ALL generated standard files, not just core.
20
+ Include all backend-api, security-db, infra, and verification standards.
21
+ Alternatively, add a note directing readers to .claude/rules/00.core/00.standard-reference.md
22
+ for the complete list.
23
+
7
24
  Generation targets:
8
25
 
9
26
  1. CLAUDE.md (project root)
@@ -12,6 +12,7 @@ Analysis items (per domain):
12
12
  - URL patterns (RESTful conventions, naming, versioning)
13
13
  - Parameter handling (req.body, req.params, req.query, @Body(), @Param(), @Query())
14
14
  - Response format (res.json, interceptor, class-transformer, custom wrapper)
15
+ - If a custom response wrapper/helper exists, record its EXACT function/class name, EXACT method signatures, and EXACT import path. Do NOT guess — read the actual source.
15
16
  - Error handling (try-catch, HttpException, ExceptionFilter, error middleware)
16
17
  - Authentication (Passport, JWT Guard, custom middleware)
17
18
  - API documentation (Swagger @ApiTags, @ApiOperation, JSDoc)
@@ -40,6 +41,8 @@ Analysis items (per domain):
40
41
  - TypeScript usage level (interface vs type vs class, Generic usage)
41
42
  - Serialization/deserialization (class-transformer, custom serializer)
42
43
  - Enum/constants management
44
+ - File entry pattern: is the main file `index.ts` or named by module (e.g., `users.controller.ts`)? Record the exact convention.
45
+ - Import paths: record EXACT path aliases and import patterns used (e.g., `@/modules/`, `@app/`, relative paths)
43
46
 
44
47
  5. Configuration/Environment Patterns
45
48
  - Environment variable management (@nestjs/config, dotenv, envalid)
@@ -29,12 +29,15 @@ Merge items:
29
29
 
30
30
  5. Naming Conventions Summary
31
31
  - File/directory naming (kebab-case, camelCase, PascalCase)
32
+ - File entry pattern (index.ts vs module-named files — pick ONE that the project actually uses)
32
33
  - DTO/type naming conventions
33
34
  - Route URL patterns
34
35
  - Module/package structure conventions
35
36
 
36
37
  6. Common Types/Interfaces List
37
- - Shared type definition files
38
+ - Shared type definition files with EXACT import paths
39
+ - Utility functions with EXACT import paths
40
+ - Path aliases used in the project (e.g., `@/` → `src/`)
38
41
  - Utility types
39
42
  - Environment variable types
40
43
  - Constants/Enum management
@@ -4,11 +4,30 @@ generate all ClaudeOS-Core files based on the analysis results.
4
4
 
5
5
  Do not read the original source code again. Reference only the analysis results.
6
6
 
7
+ CRITICAL — Package Manager Consistency:
8
+ Check `stack.packageManager` in project-analysis.json (e.g., "pnpm", "yarn", "npm").
9
+ ALL generated files MUST use ONLY that detected package manager's commands.
10
+ For example, if packageManager is "pnpm": use `pnpm run build`, `pnpm run dev`, `pnpm install`, etc.
11
+ NEVER mix npm/yarn/pnpm commands. Also check `scripts` field in the project's package.json
12
+ for actual script names (e.g., "eslint" not "lint", "typecheck" not "tsc --noEmit").
13
+
14
+ CRITICAL — Cross-file Consistency:
15
+ Rules (.claude/rules/) and Standards (claudeos-core/standard/) MUST NOT contradict each other.
16
+ If a standard defines a specific pattern (e.g., import path, file naming, API usage),
17
+ the corresponding rule MUST use the same pattern. Before generating each rule file,
18
+ verify it is consistent with the related standard file.
19
+
20
+ CRITICAL — CLAUDE.md Reference Table Completeness:
21
+ The reference table in CLAUDE.md MUST list ALL generated standard files, not just core.
22
+ Include all frontend-ui, backend-api, security-db, infra, and verification standards.
23
+ Alternatively, add a note directing readers to .claude/rules/00.core/00.standard-reference.md
24
+ for the complete list.
25
+
7
26
  Generation targets:
8
27
 
9
28
  1. CLAUDE.md (project root)
10
29
  - Role definition (based on detected stack)
11
- - Build & Run Commands (npm/yarn/pnpm)
30
+ - Build & Run Commands (use ONLY the detected packageManager — never hardcode npm/yarn/pnpm)
12
31
  - Core architecture diagram
13
32
  - DB table/collection naming
14
33
  - Standard/Skills/Guide reference table