claudeos-core 1.0.7 → 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.
Potentially problematic release.
This version of claudeos-core might be problematic. Click here for more details.
- package/CHANGELOG.md +84 -1
- package/CONTRIBUTING.md +15 -4
- package/README.de.md +187 -11
- package/README.es.md +187 -11
- package/README.fr.md +187 -11
- package/README.hi.md +187 -11
- package/README.ja.md +186 -10
- package/README.ko.md +331 -364
- package/README.md +200 -11
- package/README.ru.md +187 -11
- package/README.vi.md +188 -12
- package/README.zh-CN.md +186 -10
- package/bin/cli.js +183 -61
- package/bootstrap.sh +128 -21
- package/content-validator/index.js +131 -60
- package/health-checker/index.js +29 -23
- package/import-linter/index.js +14 -8
- package/manifest-generator/index.js +26 -20
- package/package.json +84 -75
- package/pass-json-validator/index.js +92 -70
- package/pass-prompts/templates/common/header.md +4 -4
- package/pass-prompts/templates/common/lang-instructions.json +27 -0
- package/pass-prompts/templates/common/pass3-footer.md +2 -3
- package/pass-prompts/templates/java-spring/pass1.md +84 -81
- package/pass-prompts/templates/java-spring/pass2.md +66 -66
- package/pass-prompts/templates/java-spring/pass3.md +60 -60
- package/pass-prompts/templates/kotlin-spring/pass1.md +172 -0
- package/pass-prompts/templates/kotlin-spring/pass2.md +109 -0
- package/pass-prompts/templates/kotlin-spring/pass3.md +98 -0
- package/pass-prompts/templates/node-express/pass1.md +73 -73
- package/pass-prompts/templates/node-express/pass2.md +66 -66
- package/pass-prompts/templates/node-express/pass3.md +53 -53
- package/pass-prompts/templates/node-nextjs/pass1.md +68 -68
- package/pass-prompts/templates/node-nextjs/pass2.md +61 -61
- package/pass-prompts/templates/node-nextjs/pass3.md +48 -48
- package/pass-prompts/templates/python-django/pass1.md +78 -78
- package/pass-prompts/templates/python-django/pass2.md +69 -69
- package/pass-prompts/templates/python-django/pass3.md +45 -45
- package/pass-prompts/templates/python-fastapi/pass1.md +76 -76
- package/pass-prompts/templates/python-fastapi/pass2.md +67 -67
- package/pass-prompts/templates/python-fastapi/pass3.md +45 -45
- package/plan-installer/index.js +623 -97
- package/plan-validator/index.js +54 -23
- package/sync-checker/index.js +25 -14
|
@@ -3,15 +3,15 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* ClaudeOS-Core — Pass JSON Validator
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* - JSON
|
|
9
|
-
* - pass1-*.json: analyzedAt, passNum, domains, analysisPerDomain
|
|
10
|
-
* - pass2-merged.json:
|
|
11
|
-
*
|
|
12
|
-
* - project-analysis.json: stack, domains, frontend, summary
|
|
6
|
+
* Role: Validate format and required keys of JSON files generated by Pass 1-3
|
|
7
|
+
* Validation items:
|
|
8
|
+
* - JSON is parseable
|
|
9
|
+
* - pass1-*.json: analyzedAt, passNum, domains, analysisPerDomain keys exist
|
|
10
|
+
* - pass2-merged.json: fuzzy validation of common required sections (10) + backend sections (2)
|
|
11
|
+
* empty value detection, top-level key count check (<5 ERROR, <9 WARNING)
|
|
12
|
+
* - project-analysis.json: stack, domains, frontend, summary keys exist
|
|
13
13
|
*
|
|
14
|
-
*
|
|
14
|
+
* Usage: npx claudeos-core <cmd> or node claudeos-core-tools/pass-json-validator/index.js
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
const fs = require("fs");
|
|
@@ -29,7 +29,7 @@ async function main() {
|
|
|
29
29
|
console.log("╚══════════════════════════════════════╝\n");
|
|
30
30
|
|
|
31
31
|
if (!fs.existsSync(GEN_DIR)) {
|
|
32
|
-
console.log(" ❌ claudeos-core/generated/
|
|
32
|
+
console.log(" ❌ claudeos-core/generated/ directory not found\n");
|
|
33
33
|
process.exit(1);
|
|
34
34
|
}
|
|
35
35
|
|
|
@@ -37,11 +37,11 @@ async function main() {
|
|
|
37
37
|
const warnings = [];
|
|
38
38
|
let checked = 0;
|
|
39
39
|
|
|
40
|
-
// ───
|
|
40
|
+
// ─── Helpers: JSON parse + key validation ────────────────────────
|
|
41
41
|
function validateJson(filePath, requiredKeys, optionalKeys) {
|
|
42
42
|
const r = rel(filePath);
|
|
43
43
|
if (!fs.existsSync(filePath)) {
|
|
44
|
-
errors.push({ file: r, type: "MISSING", msg: "
|
|
44
|
+
errors.push({ file: r, type: "MISSING", msg: "File not found" });
|
|
45
45
|
return null;
|
|
46
46
|
}
|
|
47
47
|
checked++;
|
|
@@ -50,18 +50,18 @@ async function main() {
|
|
|
50
50
|
const raw = fs.readFileSync(filePath, "utf-8");
|
|
51
51
|
data = JSON.parse(raw);
|
|
52
52
|
} catch (e) {
|
|
53
|
-
errors.push({ file: r, type: "PARSE_ERROR", msg: `JSON
|
|
53
|
+
errors.push({ file: r, type: "PARSE_ERROR", msg: `JSON parse failed: ${e.message}` });
|
|
54
54
|
return null;
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
for (const key of requiredKeys) {
|
|
58
58
|
if (!(key in data)) {
|
|
59
|
-
errors.push({ file: r, type: "MISSING_KEY", msg:
|
|
59
|
+
errors.push({ file: r, type: "MISSING_KEY", msg: `Required key '${key}' missing` });
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
62
|
for (const key of (optionalKeys || [])) {
|
|
63
63
|
if (!(key in data)) {
|
|
64
|
-
warnings.push({ file: r, type: "MISSING_KEY", msg:
|
|
64
|
+
warnings.push({ file: r, type: "MISSING_KEY", msg: `Recommended key '${key}' missing` });
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
67
|
return data;
|
|
@@ -72,17 +72,18 @@ async function main() {
|
|
|
72
72
|
const pa = validateJson(
|
|
73
73
|
path.join(GEN_DIR, "project-analysis.json"),
|
|
74
74
|
["analyzedAt", "stack", "domains", "frontend", "summary"],
|
|
75
|
-
["template", "templates", "rootPackage", "activeDomains"]
|
|
75
|
+
["lang", "template", "templates", "rootPackage", "activeDomains"]
|
|
76
76
|
);
|
|
77
77
|
if (pa) {
|
|
78
78
|
if (!pa.stack || !pa.stack.language) {
|
|
79
|
-
errors.push({ file: "project-analysis.json", type: "INVALID_STACK", msg: "stack.language
|
|
79
|
+
errors.push({ file: "project-analysis.json", type: "INVALID_STACK", msg: "stack.language is missing" });
|
|
80
80
|
}
|
|
81
81
|
if (!Array.isArray(pa.domains)) {
|
|
82
|
-
errors.push({ file: "project-analysis.json", type: "INVALID_DOMAINS", msg: "domains
|
|
82
|
+
errors.push({ file: "project-analysis.json", type: "INVALID_DOMAINS", msg: "domains is not an array" });
|
|
83
83
|
} else {
|
|
84
84
|
console.log(` stack: ${pa.stack?.language || "?"} / ${pa.stack?.framework || "?"}`);
|
|
85
|
-
console.log(` domains: ${pa.domains.length}
|
|
85
|
+
console.log(` domains: ${pa.domains.length}`);
|
|
86
|
+
console.log(` lang: ${pa.lang || "en (default)"}`);
|
|
86
87
|
const tmpl = pa.templates || pa.template;
|
|
87
88
|
if (typeof tmpl === "object") {
|
|
88
89
|
console.log(` templates: backend=${tmpl.backend || "none"}, frontend=${tmpl.frontend || "none"}`);
|
|
@@ -102,19 +103,19 @@ async function main() {
|
|
|
102
103
|
);
|
|
103
104
|
if (dg) {
|
|
104
105
|
if (!Array.isArray(dg.groups)) {
|
|
105
|
-
errors.push({ file: "domain-groups.json", type: "INVALID_GROUPS", msg: "groups
|
|
106
|
+
errors.push({ file: "domain-groups.json", type: "INVALID_GROUPS", msg: "groups is not an array" });
|
|
106
107
|
} else {
|
|
107
|
-
console.log(` ${dg.totalGroups}
|
|
108
|
+
console.log(` ${dg.totalGroups} groups, ${dg.totalDomains} domains`);
|
|
108
109
|
}
|
|
109
110
|
}
|
|
110
111
|
|
|
111
112
|
// ─── 3. pass1-*.json ──────────────────────────────────
|
|
112
113
|
console.log(" [3/4] pass1-*.json...");
|
|
113
114
|
const pass1Files = await glob("pass1-*.json", { cwd: GEN_DIR, absolute: true });
|
|
114
|
-
// pass1-prompt.md
|
|
115
|
+
// Exclude pass1-prompt.md
|
|
115
116
|
const pass1JsonFiles = pass1Files.filter(f => f.endsWith(".json"));
|
|
116
117
|
if (pass1JsonFiles.length === 0) {
|
|
117
|
-
warnings.push({ file: "pass1-*.json", type: "NO_FILES", msg: "pass1 JSON
|
|
118
|
+
warnings.push({ file: "pass1-*.json", type: "NO_FILES", msg: "No pass1 JSON found (not yet executed?)" });
|
|
118
119
|
}
|
|
119
120
|
for (const f of pass1JsonFiles) {
|
|
120
121
|
const data = validateJson(f,
|
|
@@ -123,13 +124,13 @@ async function main() {
|
|
|
123
124
|
);
|
|
124
125
|
if (data) {
|
|
125
126
|
if (!Array.isArray(data.domains) || data.domains.length === 0) {
|
|
126
|
-
warnings.push({ file: rel(f), type: "EMPTY_DOMAINS", msg: "
|
|
127
|
+
warnings.push({ file: rel(f), type: "EMPTY_DOMAINS", msg: "No analyzed domains found" });
|
|
127
128
|
}
|
|
128
129
|
if (typeof data.analysisPerDomain !== "object") {
|
|
129
|
-
errors.push({ file: rel(f), type: "INVALID_ANALYSIS", msg: "analysisPerDomain
|
|
130
|
+
errors.push({ file: rel(f), type: "INVALID_ANALYSIS", msg: "analysisPerDomain is not an object" });
|
|
130
131
|
} else {
|
|
131
132
|
const domainCount = Object.keys(data.analysisPerDomain).length;
|
|
132
|
-
console.log(` ${path.basename(f)}: ${domainCount}
|
|
133
|
+
console.log(` ${path.basename(f)}: ${domainCount} domains analyzed`);
|
|
133
134
|
}
|
|
134
135
|
}
|
|
135
136
|
}
|
|
@@ -138,92 +139,110 @@ async function main() {
|
|
|
138
139
|
console.log(" [4/4] pass2-merged.json...");
|
|
139
140
|
const p2path = path.join(GEN_DIR, "pass2-merged.json");
|
|
140
141
|
if (!fs.existsSync(p2path)) {
|
|
141
|
-
warnings.push({ file: "pass2-merged.json", type: "NO_FILE", msg: "
|
|
142
|
+
warnings.push({ file: "pass2-merged.json", type: "NO_FILE", msg: "Not yet generated (Pass 2 not executed?)" });
|
|
142
143
|
} else {
|
|
143
144
|
checked++;
|
|
144
145
|
let data;
|
|
145
146
|
try {
|
|
146
147
|
data = JSON.parse(fs.readFileSync(p2path, "utf-8"));
|
|
147
148
|
} catch (e) {
|
|
148
|
-
errors.push({ file: "pass2-merged.json", type: "PARSE_ERROR", msg: `JSON
|
|
149
|
+
errors.push({ file: "pass2-merged.json", type: "PARSE_ERROR", msg: `JSON parse failed: ${e.message}` });
|
|
149
150
|
data = null;
|
|
150
151
|
}
|
|
151
152
|
|
|
152
153
|
if (data) {
|
|
153
154
|
const keys = Object.keys(data);
|
|
154
|
-
console.log(`
|
|
155
|
+
console.log(` ${keys.length} top-level keys: ${keys.slice(0, 5).join(", ")}${keys.length > 5 ? " ..." : ""}`);
|
|
155
156
|
|
|
156
|
-
//
|
|
157
|
+
// Required sections common to all stacks (intersection of all 5 stack pass2 prompts)
|
|
157
158
|
const REQUIRED_SECTIONS = [
|
|
158
|
-
"commonPatterns", // 1.
|
|
159
|
-
"sharedPatterns", // 2.
|
|
160
|
-
"domainSpecific", // 3.
|
|
161
|
-
"antiPatterns", // 4.
|
|
162
|
-
"namingConventions", // 5.
|
|
163
|
-
"commonUtilities", // 6.
|
|
164
|
-
"security", // 7.
|
|
165
|
-
"testing", // 9.
|
|
166
|
-
"logging", // 10.
|
|
167
|
-
"codeQuality", // 12.
|
|
159
|
+
"commonPatterns", // 1. Universal patterns
|
|
160
|
+
"sharedPatterns", // 2. Majority patterns
|
|
161
|
+
"domainSpecific", // 3. Domain-specific patterns
|
|
162
|
+
"antiPatterns", // 4. Anti-pattern summary
|
|
163
|
+
"namingConventions", // 5. Naming conventions summary
|
|
164
|
+
"commonUtilities", // 6. Common classes/utilities list
|
|
165
|
+
"security", // 7. Security/auth patterns
|
|
166
|
+
"testing", // 9. Testing strategy summary
|
|
167
|
+
"logging", // 10. Logging/monitoring strategy
|
|
168
|
+
"codeQuality", // 12. Code quality tools
|
|
168
169
|
];
|
|
169
170
|
|
|
170
|
-
//
|
|
171
|
+
// Sections only in backend stacks (java/node-express/django/fastapi/kotlin)
|
|
171
172
|
const BACKEND_SECTIONS = [
|
|
172
|
-
"database", // 8. DB
|
|
173
|
-
"performance", // 11.
|
|
173
|
+
"database", // 8. DB patterns
|
|
174
|
+
"performance", // 11. Performance patterns
|
|
174
175
|
];
|
|
175
176
|
|
|
176
|
-
//
|
|
177
|
+
// Sections only in kotlin-spring with CQRS/BFF/multi-module detected
|
|
178
|
+
const KOTLIN_CQRS_SECTIONS = [
|
|
179
|
+
"bffPatterns", // 7. BFF patterns summary
|
|
180
|
+
"interModuleCommunication", // Inter-module communication
|
|
181
|
+
];
|
|
182
|
+
// Sections for all kotlin-spring projects (regardless of CQRS)
|
|
183
|
+
const KOTLIN_BASE_SECTIONS = [
|
|
184
|
+
"buildModulePatterns", // 13. Build & module patterns
|
|
185
|
+
];
|
|
186
|
+
|
|
187
|
+
// Check stack from project-analysis.json
|
|
177
188
|
const paPath = path.join(GEN_DIR, "project-analysis.json");
|
|
178
|
-
let isBackend = true; //
|
|
189
|
+
let isBackend = true; // Default: also validate backend sections
|
|
190
|
+
let isKotlin = false;
|
|
191
|
+
let isKotlinCqrs = false;
|
|
179
192
|
if (fs.existsSync(paPath)) {
|
|
180
193
|
try {
|
|
181
|
-
const
|
|
182
|
-
const frontend =
|
|
183
|
-
const framework =
|
|
194
|
+
const paData = JSON.parse(fs.readFileSync(paPath, "utf-8"));
|
|
195
|
+
const frontend = paData.stack?.frontend;
|
|
196
|
+
const framework = paData.stack?.framework;
|
|
197
|
+
const language = paData.stack?.language;
|
|
198
|
+
const architecture = paData.stack?.architecture;
|
|
184
199
|
isBackend = !frontend || ["express", "nestjs", "django", "fastapi", "spring-boot"].includes(framework);
|
|
185
|
-
|
|
200
|
+
isKotlin = language === "kotlin";
|
|
201
|
+
isKotlinCqrs = isKotlin && (architecture === "cqrs" || paData.stack?.multiModule);
|
|
202
|
+
} catch { /* If project-analysis parsing fails, conservatively assume backend */ }
|
|
186
203
|
}
|
|
187
204
|
|
|
188
|
-
const sectionsToCheck =
|
|
189
|
-
|
|
190
|
-
:
|
|
205
|
+
const sectionsToCheck = [
|
|
206
|
+
...REQUIRED_SECTIONS,
|
|
207
|
+
...(isBackend ? BACKEND_SECTIONS : []),
|
|
208
|
+
...(isKotlin ? KOTLIN_BASE_SECTIONS : []),
|
|
209
|
+
...(isKotlinCqrs ? KOTLIN_CQRS_SECTIONS : []),
|
|
210
|
+
];
|
|
191
211
|
|
|
192
|
-
//
|
|
193
|
-
|
|
212
|
+
// Key existence validation (case-insensitive fuzzy matching)
|
|
213
|
+
// Normalize a key to a comparable form: lowercase, strip separators
|
|
214
|
+
const normalize = (s) => s.toLowerCase().replace(/[_\-\s]/g, "");
|
|
215
|
+
const normalizedKeys = keys.map(normalize);
|
|
194
216
|
for (const section of sectionsToCheck) {
|
|
195
|
-
const
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
section.replace(/([A-Z])/g, " $1").toLowerCase(), // camelCase → space
|
|
200
|
-
];
|
|
201
|
-
const found = variants.some(v => lowerKeys.some(k => k.includes(v.replace(/_/g, ""))));
|
|
217
|
+
const sectionNorm = normalize(section);
|
|
218
|
+
// Exact normalized match first, then containment (only for names >= 6 chars to avoid false positives)
|
|
219
|
+
const found = normalizedKeys.some(k => k === sectionNorm)
|
|
220
|
+
|| (sectionNorm.length >= 6 && normalizedKeys.some(k => k.includes(sectionNorm) || sectionNorm.includes(k)));
|
|
202
221
|
if (!found) {
|
|
203
222
|
warnings.push({
|
|
204
223
|
file: "pass2-merged.json",
|
|
205
224
|
type: "MISSING_SECTION",
|
|
206
|
-
msg: `'${section}'
|
|
225
|
+
msg: `'${section}' section missing (Claude may have used a different key name)`,
|
|
207
226
|
});
|
|
208
227
|
}
|
|
209
228
|
}
|
|
210
229
|
|
|
211
|
-
//
|
|
230
|
+
// Top-level key count validation
|
|
212
231
|
if (keys.length < 5) {
|
|
213
232
|
errors.push({
|
|
214
233
|
file: "pass2-merged.json",
|
|
215
234
|
type: "INSUFFICIENT_KEYS",
|
|
216
|
-
msg:
|
|
235
|
+
msg: `Only ${keys.length} top-level keys — merge is incomplete (minimum 5 required)`,
|
|
217
236
|
});
|
|
218
237
|
} else if (keys.length < 9) {
|
|
219
238
|
warnings.push({
|
|
220
239
|
file: "pass2-merged.json",
|
|
221
240
|
type: "FEW_KEYS",
|
|
222
|
-
msg:
|
|
241
|
+
msg: `${keys.length} top-level keys — some sections may be missing (recommended 9+)`,
|
|
223
242
|
});
|
|
224
243
|
}
|
|
225
244
|
|
|
226
|
-
//
|
|
245
|
+
// Value depth validation — detect empty objects/arrays
|
|
227
246
|
let emptyCount = 0;
|
|
228
247
|
for (const [k, v] of Object.entries(data)) {
|
|
229
248
|
const isEmpty =
|
|
@@ -237,18 +256,18 @@ async function main() {
|
|
|
237
256
|
warnings.push({
|
|
238
257
|
file: "pass2-merged.json",
|
|
239
258
|
type: "EMPTY_VALUES",
|
|
240
|
-
msg: `${emptyCount}
|
|
259
|
+
msg: `${emptyCount} items have empty values — analysis content may be missing`,
|
|
241
260
|
});
|
|
242
261
|
}
|
|
243
262
|
|
|
244
263
|
const missingCount = warnings.filter(w => w.file === "pass2-merged.json" && w.type === "MISSING_SECTION").length;
|
|
245
264
|
if (missingCount === 0 && keys.length >= 9) {
|
|
246
|
-
console.log(` ✅
|
|
265
|
+
console.log(` ✅ Structure validation passed (${keys.length} keys, ${emptyCount} empty values)`);
|
|
247
266
|
}
|
|
248
267
|
}
|
|
249
268
|
}
|
|
250
269
|
|
|
251
|
-
// ───
|
|
270
|
+
// ─── Output results ─────────────────────────────────────────
|
|
252
271
|
console.log(`\n Checked ${checked} files\n`);
|
|
253
272
|
if (errors.length) {
|
|
254
273
|
console.log(` ❌ ERRORS (${errors.length}):`);
|
|
@@ -264,10 +283,13 @@ async function main() {
|
|
|
264
283
|
console.log(" ✅ All JSON validation passed\n");
|
|
265
284
|
}
|
|
266
285
|
|
|
267
|
-
// stale-report
|
|
286
|
+
// Record in stale-report
|
|
268
287
|
if (fs.existsSync(GEN_DIR)) {
|
|
269
288
|
const rp = path.join(GEN_DIR, "stale-report.json");
|
|
270
|
-
|
|
289
|
+
let ex = {};
|
|
290
|
+
if (fs.existsSync(rp)) {
|
|
291
|
+
try { ex = JSON.parse(fs.readFileSync(rp, "utf-8")); } catch { ex = {}; }
|
|
292
|
+
}
|
|
271
293
|
ex.jsonValidation = { checkedAt: new Date().toISOString(), checked, errors: errors.length, warnings: warnings.length };
|
|
272
294
|
ex.summary = { ...ex.summary, jsonErrors: errors.length, jsonWarnings: warnings.length };
|
|
273
295
|
fs.writeFileSync(rp, JSON.stringify(ex, null, 2));
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
You are a code analysis tool. Analyze the project source code according to the instructions below and save the results as a JSON file.
|
|
2
|
+
Do not converse. Output only the analysis results in JSON format.
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
Project root path: {{PROJECT_ROOT}}
|
|
5
|
+
Interpret all file paths relative to this root.
|
|
6
6
|
|
|
7
7
|
---
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"supported": ["en", "ko", "zh-CN", "ja", "es", "vi", "hi", "ru", "fr", "de"],
|
|
3
|
+
"labels": {
|
|
4
|
+
"en": "English",
|
|
5
|
+
"ko": "한국어 (Korean)",
|
|
6
|
+
"zh-CN": "简体中文 (Chinese Simplified)",
|
|
7
|
+
"ja": "日本語 (Japanese)",
|
|
8
|
+
"es": "Español (Spanish)",
|
|
9
|
+
"vi": "Tiếng Việt (Vietnamese)",
|
|
10
|
+
"hi": "हिन्दी (Hindi)",
|
|
11
|
+
"ru": "Русский (Russian)",
|
|
12
|
+
"fr": "Français (French)",
|
|
13
|
+
"de": "Deutsch (German)"
|
|
14
|
+
},
|
|
15
|
+
"instructions": {
|
|
16
|
+
"en": "",
|
|
17
|
+
"ko": "\n---\n\n## ⚠️ LANGUAGE REQUIREMENT (MANDATORY)\n\nGenerate ALL output file content in **Korean (한국어)**.\n\nThis applies to:\n- CLAUDE.md\n- All files under claudeos-core/standard/\n- All files under .claude/rules/\n- All files under claudeos-core/skills/\n- All files under claudeos-core/guide/\n- All files under claudeos-core/plan/\n- All files under claudeos-core/database/\n- All files under claudeos-core/mcp-guide/\n\nRules:\n- All headings, descriptions, explanations, comments, and documentation text MUST be in Korean.\n- Code examples inside ```code blocks``` keep their original syntax (Java/Kotlin/Python/JS class names, method names, annotations, keywords remain in English as they are programming language syntax).\n- JSON keys in generated files (e.g., frontmatter `paths:`, `name:`) remain in English.\n- Markdown structural elements (```markdown, ---, ✅, ❌) remain as-is.\n- Use natural, professional Korean — not machine-translated style.\n- Technical terms that are commonly used in English among Korean developers (e.g., Controller, Service, Repository, DTO, API, CRUD) may remain in English or be written as 컨트롤러, 서비스, etc. — use whichever is more natural in context.\n\n---\n\n",
|
|
18
|
+
"zh-CN": "\n---\n\n## ⚠️ LANGUAGE REQUIREMENT (MANDATORY)\n\nGenerate ALL output file content in **Simplified Chinese (简体中文)**.\n\nThis applies to:\n- CLAUDE.md\n- All files under claudeos-core/standard/\n- All files under .claude/rules/\n- All files under claudeos-core/skills/\n- All files under claudeos-core/guide/\n- All files under claudeos-core/plan/\n- All files under claudeos-core/database/\n- All files under claudeos-core/mcp-guide/\n\nRules:\n- All headings, descriptions, explanations, comments, and documentation text MUST be in Simplified Chinese.\n- Code examples inside ```code blocks``` keep their original syntax.\n- JSON keys and frontmatter keys remain in English.\n- Use natural, professional Simplified Chinese.\n- Technical terms commonly used in English among Chinese developers may remain in English where natural.\n\n---\n\n",
|
|
19
|
+
"ja": "\n---\n\n## ⚠️ LANGUAGE REQUIREMENT (MANDATORY)\n\nGenerate ALL output file content in **Japanese (日本語)**.\n\nThis applies to:\n- CLAUDE.md\n- All files under claudeos-core/standard/\n- All files under .claude/rules/\n- All files under claudeos-core/skills/\n- All files under claudeos-core/guide/\n- All files under claudeos-core/plan/\n- All files under claudeos-core/database/\n- All files under claudeos-core/mcp-guide/\n\nRules:\n- All headings, descriptions, explanations, comments, and documentation text MUST be in Japanese.\n- Code examples inside ```code blocks``` keep their original syntax.\n- JSON keys and frontmatter keys remain in English.\n- Use natural, professional Japanese (です/ます体 for documentation).\n- Technical terms commonly used in English among Japanese developers (e.g., コントローラー, サービス) may use katakana or English — whichever is more natural.\n\n---\n\n",
|
|
20
|
+
"es": "\n---\n\n## ⚠️ LANGUAGE REQUIREMENT (MANDATORY)\n\nGenerate ALL output file content in **Spanish (Español)**.\n\nThis applies to:\n- CLAUDE.md\n- All files under claudeos-core/standard/\n- All files under .claude/rules/\n- All files under claudeos-core/skills/\n- All files under claudeos-core/guide/\n- All files under claudeos-core/plan/\n- All files under claudeos-core/database/\n- All files under claudeos-core/mcp-guide/\n\nRules:\n- All headings, descriptions, explanations, comments, and documentation text MUST be in Spanish.\n- Code examples inside ```code blocks``` keep their original syntax.\n- JSON keys and frontmatter keys remain in English.\n- Use natural, professional Spanish.\n- Technical terms commonly used in English among Spanish-speaking developers may remain in English where natural.\n\n---\n\n",
|
|
21
|
+
"vi": "\n---\n\n## ⚠️ LANGUAGE REQUIREMENT (MANDATORY)\n\nGenerate ALL output file content in **Vietnamese (Tiếng Việt)**.\n\nThis applies to:\n- CLAUDE.md\n- All files under claudeos-core/standard/\n- All files under .claude/rules/\n- All files under claudeos-core/skills/\n- All files under claudeos-core/guide/\n- All files under claudeos-core/plan/\n- All files under claudeos-core/database/\n- All files under claudeos-core/mcp-guide/\n\nRules:\n- All headings, descriptions, explanations, comments, and documentation text MUST be in Vietnamese.\n- Code examples inside ```code blocks``` keep their original syntax.\n- JSON keys and frontmatter keys remain in English.\n- Use natural, professional Vietnamese.\n- Technical terms commonly used in English among Vietnamese developers may remain in English where natural.\n\n---\n\n",
|
|
22
|
+
"hi": "\n---\n\n## ⚠️ LANGUAGE REQUIREMENT (MANDATORY)\n\nGenerate ALL output file content in **Hindi (हिन्दी)**.\n\nThis applies to:\n- CLAUDE.md\n- All files under claudeos-core/standard/\n- All files under .claude/rules/\n- All files under claudeos-core/skills/\n- All files under claudeos-core/guide/\n- All files under claudeos-core/plan/\n- All files under claudeos-core/database/\n- All files under claudeos-core/mcp-guide/\n\nRules:\n- All headings, descriptions, explanations, comments, and documentation text MUST be in Hindi.\n- Code examples inside ```code blocks``` keep their original syntax.\n- JSON keys and frontmatter keys remain in English.\n- Use natural, professional Hindi (Devanagari script).\n- Technical terms commonly used in English among Hindi-speaking developers may remain in English where natural.\n\n---\n\n",
|
|
23
|
+
"ru": "\n---\n\n## ⚠️ LANGUAGE REQUIREMENT (MANDATORY)\n\nGenerate ALL output file content in **Russian (Русский)**.\n\nThis applies to:\n- CLAUDE.md\n- All files under claudeos-core/standard/\n- All files under .claude/rules/\n- All files under claudeos-core/skills/\n- All files under claudeos-core/guide/\n- All files under claudeos-core/plan/\n- All files under claudeos-core/database/\n- All files under claudeos-core/mcp-guide/\n\nRules:\n- All headings, descriptions, explanations, comments, and documentation text MUST be in Russian.\n- Code examples inside ```code blocks``` keep their original syntax.\n- JSON keys and frontmatter keys remain in English.\n- Use natural, professional Russian.\n- Technical terms commonly used in English among Russian-speaking developers may remain in English where natural.\n\n---\n\n",
|
|
24
|
+
"fr": "\n---\n\n## ⚠️ LANGUAGE REQUIREMENT (MANDATORY)\n\nGenerate ALL output file content in **French (Français)**.\n\nThis applies to:\n- CLAUDE.md\n- All files under claudeos-core/standard/\n- All files under .claude/rules/\n- All files under claudeos-core/skills/\n- All files under claudeos-core/guide/\n- All files under claudeos-core/plan/\n- All files under claudeos-core/database/\n- All files under claudeos-core/mcp-guide/\n\nRules:\n- All headings, descriptions, explanations, comments, and documentation text MUST be in French.\n- Code examples inside ```code blocks``` keep their original syntax.\n- JSON keys and frontmatter keys remain in English.\n- Use natural, professional French.\n- Technical terms commonly used in English among French-speaking developers may remain in English where natural.\n\n---\n\n",
|
|
25
|
+
"de": "\n---\n\n## ⚠️ LANGUAGE REQUIREMENT (MANDATORY)\n\nGenerate ALL output file content in **German (Deutsch)**.\n\nThis applies to:\n- CLAUDE.md\n- All files under claudeos-core/standard/\n- All files under .claude/rules/\n- All files under claudeos-core/skills/\n- All files under claudeos-core/guide/\n- All files under claudeos-core/plan/\n- All files under claudeos-core/database/\n- All files under claudeos-core/mcp-guide/\n\nRules:\n- All headings, descriptions, explanations, comments, and documentation text MUST be in German.\n- Code examples inside ```code blocks``` keep their original syntax.\n- JSON keys and frontmatter keys remain in English.\n- Use natural, professional German.\n- Technical terms commonly used in English among German-speaking developers may remain in English where natural.\n\n---\n\n"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -1,97 +1,100 @@
|
|
|
1
|
-
claudeos-core/generated/project-analysis.json
|
|
2
|
-
|
|
1
|
+
Read claudeos-core/generated/project-analysis.json and
|
|
2
|
+
perform a deep analysis of the following domains only: {{DOMAIN_GROUP}}
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
For each domain, select one representative file per layer, read its code, and analyze it.
|
|
5
|
+
Prioritize files with the richest patterns.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Analysis items (per domain):
|
|
8
8
|
|
|
9
|
-
1. Controller
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
- URL
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
- API
|
|
18
|
-
-
|
|
9
|
+
1. Controller Patterns
|
|
10
|
+
- Class annotations (@Controller vs @RestController, inheritance)
|
|
11
|
+
- Method mappings (@GetMapping, @PostMapping, @PutMapping, @DeleteMapping, @PatchMapping)
|
|
12
|
+
- URL patterns (RESTful conventions, naming conventions, versioning)
|
|
13
|
+
- Parameter binding (@RequestBody, @PathVariable, @RequestParam, @ModelAttribute, @RequestHeader)
|
|
14
|
+
- Response format (ResponseEntity, custom response wrappers, direct return)
|
|
15
|
+
- Error handling (try-catch patterns, @ExceptionHandler, @ControllerAdvice)
|
|
16
|
+
- Authentication/authorization (@AuthenticationPrincipal, @PreAuthorize, SecurityContext)
|
|
17
|
+
- API documentation (Swagger/SpringDoc annotations)
|
|
18
|
+
- Pagination (Pageable, custom paging parameters)
|
|
19
19
|
|
|
20
|
-
2. Service
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
-
|
|
20
|
+
2. Service Patterns
|
|
21
|
+
- Class annotations (@Service, @Transactional)
|
|
22
|
+
- Transaction strategy (class-level vs method-level, readOnly separation, propagation)
|
|
23
|
+
- Dependency injection (constructor injection, @RequiredArgsConstructor, @Autowired)
|
|
24
|
+
- Business exception handling (custom Exception hierarchy, exception message management)
|
|
25
|
+
- Validation logic placement (within Service vs separate Validator)
|
|
26
|
+
- Event handling (ApplicationEventPublisher, @EventListener)
|
|
27
27
|
|
|
28
|
-
3.
|
|
29
|
-
- ORM
|
|
30
|
-
- Repository/Mapper
|
|
31
|
-
-
|
|
32
|
-
-
|
|
33
|
-
-
|
|
34
|
-
- NULL
|
|
35
|
-
- PK
|
|
36
|
-
- N+1
|
|
37
|
-
-
|
|
28
|
+
3. Data Access Patterns
|
|
29
|
+
- ORM approach (MyBatis XML/Annotation, JPA/Hibernate, QueryDSL, JDBC Template)
|
|
30
|
+
- Repository/Mapper interface structure (inheritance, custom methods)
|
|
31
|
+
- Read/write separation
|
|
32
|
+
- Pagination approach (Pageable, PageHelper, RowBounds, custom)
|
|
33
|
+
- Audit columns (createdAt/updatedAt/createdBy/updatedBy, @CreatedDate, @LastModifiedDate)
|
|
34
|
+
- NULL handling strategy
|
|
35
|
+
- PK generation strategy (AUTO_INCREMENT, SEQUENCE, UUID, custom ID generation)
|
|
36
|
+
- N+1 problem handling (fetch join, @EntityGraph, BatchSize)
|
|
37
|
+
- Dynamic queries (Specification, QueryDSL, MyBatis <if>/<choose>)
|
|
38
38
|
|
|
39
|
-
4. DTO/Entity
|
|
40
|
-
-
|
|
41
|
-
- Lombok
|
|
42
|
-
- Request/Response DTO
|
|
43
|
-
- DTO
|
|
44
|
-
-
|
|
45
|
-
-
|
|
46
|
-
-
|
|
39
|
+
4. DTO/VO/Entity Patterns
|
|
40
|
+
- Class structure (inheritance, Base class, Record usage)
|
|
41
|
+
- Lombok usage scope (@Getter, @Setter, @Builder, @Data, @Value)
|
|
42
|
+
- Request/Response DTO separation rules
|
|
43
|
+
- DTO naming conventions
|
|
44
|
+
- **DTO vs VO distinction**: DTO (data transfer, mutable) vs VO (domain concept, immutable, equality by value)
|
|
45
|
+
- VO usage patterns (Java Record as VO, @Value with Lombok, custom equals/hashCode)
|
|
46
|
+
- VO location (domain layer vs shared module)
|
|
47
|
+
- Field type conventions (Boolean handling, date types, Enum management)
|
|
48
|
+
- Validation annotations (@NotNull, @NotBlank, @Size, @Pattern, custom)
|
|
49
|
+
- Conversion approach (MapStruct, ModelMapper, manual conversion)
|
|
47
50
|
|
|
48
|
-
5. Interceptor/Filter/AOP
|
|
49
|
-
- HandlerInterceptor
|
|
50
|
-
- Filter
|
|
51
|
-
- AOP
|
|
52
|
-
-
|
|
51
|
+
5. Interceptor/Filter/AOP Patterns
|
|
52
|
+
- HandlerInterceptor usage
|
|
53
|
+
- Filter chain (SecurityFilterChain, custom Filters)
|
|
54
|
+
- AOP usage (@Aspect, logging, performance measurement, auditing)
|
|
55
|
+
- Middleware registration order
|
|
53
56
|
|
|
54
|
-
6.
|
|
55
|
-
- Profile
|
|
56
|
-
-
|
|
57
|
-
-
|
|
58
|
-
-
|
|
57
|
+
6. Configuration/Environment Patterns
|
|
58
|
+
- Profile separation (local/dev/stg/prod)
|
|
59
|
+
- Configuration loading (@ConfigurationProperties, @Value, Environment)
|
|
60
|
+
- Multi-module structure
|
|
61
|
+
- External configuration (application.yml structure, environment variables)
|
|
59
62
|
|
|
60
|
-
7.
|
|
61
|
-
-
|
|
62
|
-
-
|
|
63
|
-
-
|
|
64
|
-
-
|
|
63
|
+
7. Logging Patterns
|
|
64
|
+
- Logger usage (SLF4J, Logback, Log4j2)
|
|
65
|
+
- Log level policy
|
|
66
|
+
- Structured logging (MDC, JSON format)
|
|
67
|
+
- Request/response logging approach
|
|
65
68
|
|
|
66
|
-
8.
|
|
67
|
-
-
|
|
68
|
-
-
|
|
69
|
+
8. Testing Patterns
|
|
70
|
+
- Test framework (JUnit 5, Mockito, AssertJ)
|
|
71
|
+
- Test classification (unit/integration/slice)
|
|
69
72
|
- @SpringBootTest vs @WebMvcTest vs @DataJpaTest
|
|
70
|
-
-
|
|
71
|
-
-
|
|
72
|
-
-
|
|
73
|
+
- Mocking strategy (@MockBean, @Mock, @InjectMocks)
|
|
74
|
+
- Test data management (TestFixture, Builder pattern)
|
|
75
|
+
- Test naming conventions
|
|
73
76
|
|
|
74
|
-
9.
|
|
75
|
-
-
|
|
77
|
+
9. Domain-Specific Patterns
|
|
78
|
+
- File upload/download (MultipartFile, S3)
|
|
76
79
|
- Excel import/export (Apache POI, EasyExcel)
|
|
77
|
-
-
|
|
78
|
-
-
|
|
79
|
-
-
|
|
80
|
-
-
|
|
81
|
-
-
|
|
82
|
-
-
|
|
83
|
-
-
|
|
84
|
-
- API
|
|
80
|
+
- Bulk processing (Batch CUD, Spring Batch)
|
|
81
|
+
- State transition logic (state machine, Enum-based)
|
|
82
|
+
- Scheduling (@Scheduled, Quartz)
|
|
83
|
+
- External API integration (RestTemplate, WebClient, FeignClient, RestClient)
|
|
84
|
+
- Caching (@Cacheable, Redis, Caffeine)
|
|
85
|
+
- Messaging (Kafka, RabbitMQ)
|
|
86
|
+
- Internationalization (MessageSource, LocaleResolver)
|
|
87
|
+
- API versioning strategy
|
|
85
88
|
|
|
86
|
-
10.
|
|
87
|
-
-
|
|
88
|
-
-
|
|
89
|
-
-
|
|
90
|
-
-
|
|
91
|
-
-
|
|
89
|
+
10. Anti-patterns / Inconsistencies
|
|
90
|
+
- Code with differing styles within the domain
|
|
91
|
+
- Patterns inconsistent with other domains
|
|
92
|
+
- Legacy-looking patterns
|
|
93
|
+
- Performance issues (N+1, unnecessary queries, memory waste)
|
|
94
|
+
- Security issues (SQL Injection potential, missing authorization)
|
|
92
95
|
|
|
93
|
-
|
|
94
|
-
|
|
96
|
+
Do not create files. Analysis only.
|
|
97
|
+
Save results to claudeos-core/generated/pass1-{{PASS_NUM}}.json in the following format:
|
|
95
98
|
|
|
96
99
|
{
|
|
97
100
|
"analyzedAt": "ISO timestamp",
|
|
@@ -102,7 +105,7 @@ claudeos-core/generated/project-analysis.json을 읽고,
|
|
|
102
105
|
"representativeFiles": {
|
|
103
106
|
"controller": "UserController.java",
|
|
104
107
|
"service": "UserService.java",
|
|
105
|
-
"repository": "UserRepository.java
|
|
108
|
+
"repository": "UserRepository.java or UserMapper.java",
|
|
106
109
|
"entity": "User.java",
|
|
107
110
|
"dto": "UserRequestDto.java"
|
|
108
111
|
},
|
|
@@ -121,7 +124,7 @@ claudeos-core/generated/project-analysis.json을 읽고,
|
|
|
121
124
|
}
|
|
122
125
|
},
|
|
123
126
|
"crossDomainCommon": {
|
|
124
|
-
"description": "
|
|
127
|
+
"description": "Patterns commonly used across domains in this group",
|
|
125
128
|
"patterns": []
|
|
126
129
|
}
|
|
127
130
|
}
|