claudeos-core 1.6.2 → 1.7.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.
@@ -1,73 +1,76 @@
1
- /**
2
- * ClaudeOS-Core — Domain Grouper
3
- *
4
- * Splits domains into analysis groups, determines active domains,
5
- * and selects appropriate templates based on detected stack.
6
- */
7
-
8
- function splitDomainGroups(domains, type, template) {
9
- const MAX_FILES_PER_GROUP = 40;
10
- const MAX_DOMAINS_PER_GROUP = 4;
11
- const groups = [];
12
- let current = [];
13
- let fileCount = 0;
14
-
15
- for (const d of domains) {
16
- // Flush current group before adding if it would exceed limits
17
- if (current.length > 0 && (fileCount + d.totalFiles > MAX_FILES_PER_GROUP || current.length >= MAX_DOMAINS_PER_GROUP)) {
18
- groups.push({ type, template, domains: [...current], estimatedFiles: fileCount });
19
- current = [];
20
- fileCount = 0;
21
- }
22
- current.push(d.name);
23
- fileCount += d.totalFiles;
24
- }
25
- if (current.length > 0) {
26
- groups.push({ type, template, domains: [...current], estimatedFiles: fileCount });
27
- }
28
-
29
- return groups;
30
- }
31
-
32
- // ─── Determine active domains ───────────────────────────────────
33
- function determineActiveDomains(stack) {
34
- const isBackend = !!stack.framework;
35
- return {
36
- "00.core": true,
37
- "10.backend": !!isBackend,
38
- "20.frontend": !!stack.frontend,
39
- "30.security-db": !!(stack.database || stack.framework),
40
- "40.infra": true,
41
- "50.verification": true,
42
- "90.optional": true,
43
- };
44
- }
45
-
46
- // ─── Template selection (multi-stack) ──────────────────────────────
47
- function selectTemplates(stack) {
48
- const templates = { backend: null, frontend: null };
49
-
50
- // Backend template (requires a backend framework; language-only fallback skipped for pure frontend projects)
51
- if (stack.language === "kotlin") templates.backend = "kotlin-spring";
52
- else if (stack.language === "java") templates.backend = "java-spring";
53
- else if (stack.framework === "nestjs") templates.backend = "node-nestjs";
54
- else if (stack.framework === "express") templates.backend = "node-express";
55
- else if (stack.framework === "fastify") templates.backend = "node-fastify";
56
- else if (stack.framework === "django") templates.backend = "python-django";
57
- else if (stack.framework === "fastapi" || stack.framework === "flask") templates.backend = "python-fastapi";
58
- else if ((stack.language === "typescript" || stack.language === "javascript") && stack.framework) templates.backend = "node-express";
59
- else if (stack.language === "python" && stack.framework) templates.backend = "python-fastapi";
60
-
61
- // Frontend template
62
- if (stack.frontend === "nextjs" || stack.frontend === "react") {
63
- templates.frontend = "node-nextjs";
64
- } else if (stack.frontend === "vue") {
65
- templates.frontend = "vue-nuxt";
66
- } else if (stack.frontend === "angular") {
67
- templates.frontend = "angular";
68
- }
69
-
70
- return templates;
71
- }
72
-
73
- module.exports = { splitDomainGroups, determineActiveDomains, selectTemplates };
1
+ /**
2
+ * ClaudeOS-Core — Domain Grouper
3
+ *
4
+ * Splits domains into analysis groups, determines active domains,
5
+ * and selects appropriate templates based on detected stack.
6
+ */
7
+
8
+ function splitDomainGroups(domains, type, template) {
9
+ const MAX_FILES_PER_GROUP = 40;
10
+ const MAX_DOMAINS_PER_GROUP = 4;
11
+ const groups = [];
12
+ let current = [];
13
+ let fileCount = 0;
14
+
15
+ for (const d of domains) {
16
+ // Flush current group before adding if it would exceed limits
17
+ if (current.length > 0 && (fileCount + d.totalFiles > MAX_FILES_PER_GROUP || current.length >= MAX_DOMAINS_PER_GROUP)) {
18
+ groups.push({ type, template, domains: [...current], estimatedFiles: fileCount });
19
+ current = [];
20
+ fileCount = 0;
21
+ }
22
+ current.push(d.name);
23
+ fileCount += d.totalFiles;
24
+ }
25
+ if (current.length > 0) {
26
+ groups.push({ type, template, domains: [...current], estimatedFiles: fileCount });
27
+ }
28
+
29
+ return groups;
30
+ }
31
+
32
+ // ─── Determine active domains ───────────────────────────────────
33
+ function determineActiveDomains(stack) {
34
+ const isBackend = !!stack.framework && stack.framework !== "vite";
35
+ return {
36
+ "00.core": true,
37
+ "10.backend": !!isBackend,
38
+ "20.frontend": !!stack.frontend,
39
+ "30.security-db": !!(stack.database || isBackend || stack.frontend),
40
+ "40.infra": true,
41
+ "50.verification": true,
42
+ "90.optional": true,
43
+ };
44
+ }
45
+
46
+ // ─── Template selection (multi-stack) ──────────────────────────────
47
+ function selectTemplates(stack) {
48
+ const templates = { backend: null, frontend: null };
49
+
50
+ // Backend template (requires a backend framework; language-only fallback skipped for pure frontend projects)
51
+ if (stack.language === "kotlin") templates.backend = "kotlin-spring";
52
+ else if (stack.language === "java") templates.backend = "java-spring";
53
+ else if (stack.framework === "nestjs") templates.backend = "node-nestjs";
54
+ else if (stack.framework === "express") templates.backend = "node-express";
55
+ else if (stack.framework === "fastify") templates.backend = "node-fastify";
56
+ else if (stack.framework === "django") templates.backend = "python-django";
57
+ else if (stack.framework === "fastapi") templates.backend = "python-fastapi";
58
+ else if (stack.framework === "flask") templates.backend = "python-flask";
59
+ else if ((stack.language === "typescript" || stack.language === "javascript") && stack.framework && stack.framework !== "vite") templates.backend = "node-express";
60
+ else if (stack.language === "python" && stack.framework) templates.backend = "python-fastapi";
61
+
62
+ // Frontend template
63
+ if (stack.frontend === "nextjs") {
64
+ templates.frontend = "node-nextjs";
65
+ } else if (stack.frontend === "react") {
66
+ templates.frontend = stack.framework === "vite" ? "node-vite" : "node-nextjs";
67
+ } else if (stack.frontend === "vue") {
68
+ templates.frontend = "vue-nuxt";
69
+ } else if (stack.frontend === "angular") {
70
+ templates.frontend = "angular";
71
+ }
72
+
73
+ return templates;
74
+ }
75
+
76
+ module.exports = { splitDomainGroups, determineActiveDomains, selectTemplates };
@@ -1,126 +1,129 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * ClaudeOS-Core — plan-installer (orchestrator)
5
- *
6
- * Modules:
7
- * - stack-detector.js — detectStack()
8
- * - structure-scanner.js — scanStructure(), resolveSharedQueryDomains()
9
- * - domain-grouper.js — splitDomainGroups(), determineActiveDomains(), selectTemplates()
10
- * - prompt-generator.js — generatePrompts()
11
- */
12
-
13
- const path = require("path");
14
- const { ensureDir, writeFileSafe } = require("../lib/safe-fs");
15
- const { detectStack } = require("./stack-detector");
16
- const { scanStructure } = require("./structure-scanner");
17
- const { splitDomainGroups, determineActiveDomains, selectTemplates } = require("./domain-grouper");
18
- const { generatePrompts } = require("./prompt-generator");
19
-
20
- const ROOT = process.env.CLAUDEOS_ROOT || path.resolve(__dirname, "../..");
21
- const GENERATED_DIR = path.join(ROOT, "claudeos-core/generated");
22
- const TEMPLATES_DIR = path.join(__dirname, "../pass-prompts/templates");
23
-
24
- async function main() {
25
- console.log("\n╔═══════════════════════════════════════╗");
26
- console.log("║ ClaudeOS-Core — Plan Installer ║");
27
- console.log("╚═══════════════════════════════════════╝\n");
28
-
29
- ensureDir(GENERATED_DIR);
30
-
31
- // Phase 1: Stack detection
32
- console.log(" [Phase 1] Detecting stack...");
33
- const stack = await detectStack(ROOT);
34
- console.log(` Language: ${stack.language || "unknown"} ${stack.languageVersion || ""}`);
35
- console.log(` Framework: ${stack.framework || "none"} ${stack.frameworkVersion || ""}`);
36
- if (!stack.language && !stack.framework) {
37
- console.warn("\n ⚠️ No language or framework detected.");
38
- console.warn(" Supported: Java, Kotlin, TypeScript, JavaScript, Python");
39
- console.warn(" Ensure you have build.gradle, package.json, pyproject.toml, or requirements.txt in the project root.\n");
40
- }
41
- console.log(` Frontend: ${stack.frontend || "none"} ${stack.frontendVersion || ""}`);
42
- console.log(` Database: ${stack.database || "none"}`);
43
- console.log(` ORM: ${stack.orm || "none"}`);
44
- console.log(` PackageMgr: ${stack.packageManager || "none"}\n`);
45
-
46
- // Phase 2: Structure scan
47
- console.log(" [Phase 2] Scanning structure...");
48
- const { domains, backendDomains, frontendDomains, rootPackage, frontend } = await scanStructure(stack, ROOT);
49
- console.log(` Backend: ${backendDomains.length} domains`);
50
- console.log(` Frontend: ${frontendDomains.length} domains`);
51
- console.log(` Total: ${domains.length} domains`);
52
- if (rootPackage) console.log(` Package: ${rootPackage}`);
53
- if (frontend.exists) console.log(` Components: ${frontend.components} components, ${frontend.pages} pages, ${frontend.hooks} hooks`);
54
- if (backendDomains.length === 0 && frontendDomains.length === 0) {
55
- console.warn("\n ⚠️ No domains detected.");
56
- console.warn(" Pass 1 will be skipped. Generated output may be minimal.\n");
57
- }
58
- console.log();
59
-
60
- // Phase 3: Template selection
61
- console.log(" [Phase 3] Selecting templates...");
62
- const templates = selectTemplates(stack);
63
- const isMultiStack = !!(templates.backend && templates.frontend);
64
- if (templates.backend) console.log(` Backend: ${templates.backend}`);
65
- if (templates.frontend) console.log(` Frontend: ${templates.frontend}`);
66
- console.log(` Mode: ${isMultiStack ? "🔀 Multi-stack" : "Single-stack"}`);
67
- console.log();
68
-
69
- // Phase 4: Domain group splitting
70
- console.log(" [Phase 4] Splitting domain groups...");
71
- const allGroups = [];
72
- if (templates.backend && backendDomains.length > 0) allGroups.push(...splitDomainGroups(backendDomains, "backend", templates.backend));
73
- if (templates.frontend && frontendDomains.length > 0) allGroups.push(...splitDomainGroups(frontendDomains, "frontend", templates.frontend));
74
- allGroups.forEach((g, i) => { g.passNum = i + 1; });
75
- allGroups.forEach((g, i) => {
76
- const icon = g.type === "backend" ? "⚙️" : "🎨";
77
- console.log(` ${icon} Group ${i + 1}: [${g.domains.join(", ")}] (${g.type}, ~${g.estimatedFiles} files)`);
78
- });
79
- console.log();
80
-
81
- // Phase 5: Active domains
82
- console.log(" [Phase 5] Active domains...");
83
- const active = determineActiveDomains(stack);
84
- Object.entries(active).forEach(([k, v]) => console.log(` ${v ? "✅" : "⏭️"} ${k}`));
85
- console.log();
86
-
87
- // Phase 6: Prompt generation
88
- const lang = process.env.CLAUDEOS_LANG || "en";
89
- console.log(` [Phase 6] Generating prompts (lang: ${lang})...`);
90
- generatePrompts(templates, lang, TEMPLATES_DIR, GENERATED_DIR);
91
- console.log();
92
-
93
- // Save outputs
94
- const defaultPort = (stack.framework === "fastapi" || stack.framework === "django") ? 8000
95
- : stack.framework === "flask" ? 5000
96
- : (stack.framework === "express" || stack.framework === "nestjs" || stack.framework === "fastify") ? 3000 : 8080;
97
- const analysis = {
98
- analyzedAt: new Date().toISOString(), lang,
99
- stack: { ...stack, port: stack.port || defaultPort },
100
- templates, isMultiStack, rootPackage,
101
- domains, backendDomains, frontendDomains, frontend,
102
- activeDomains: active,
103
- summary: {
104
- totalDomains: domains.length, backendDomains: backendDomains.length,
105
- frontendDomains: frontendDomains.length,
106
- totalFiles: domains.reduce((s, d) => s + d.totalFiles, 0),
107
- },
108
- };
109
- writeFileSafe(path.join(GENERATED_DIR, "project-analysis.json"), JSON.stringify(analysis, null, 2));
110
- console.log(" 💾 project-analysis.json saved");
111
-
112
- const domainGroups = {
113
- generatedAt: new Date().toISOString(), isMultiStack, templates,
114
- totalDomains: domains.length, totalGroups: allGroups.length,
115
- maxDomainsPerGroup: 4, maxFilesPerGroup: 40, groups: allGroups,
116
- };
117
- writeFileSafe(path.join(GENERATED_DIR, "domain-groups.json"), JSON.stringify(domainGroups, null, 2));
118
- console.log(" 💾 domain-groups.json saved\n");
119
- console.log(" ✅ Plan Installer complete\n");
120
- }
121
-
122
- main().catch(e => {
123
- console.error(`\n ❌ Plan Installer failed: ${e.message || e}`);
124
- if (e.code === "EACCES" || e.code === "EPERM") console.error(" Check file/directory permissions.");
125
- process.exit(1);
126
- });
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * ClaudeOS-Core — plan-installer (orchestrator)
5
+ *
6
+ * Modules:
7
+ * - stack-detector.js — detectStack()
8
+ * - structure-scanner.js — scanStructure(), resolveSharedQueryDomains()
9
+ * - domain-grouper.js — splitDomainGroups(), determineActiveDomains(), selectTemplates()
10
+ * - prompt-generator.js — generatePrompts()
11
+ */
12
+
13
+ const path = require("path");
14
+ const { ensureDir, writeFileSafe } = require("../lib/safe-fs");
15
+ const { detectStack } = require("./stack-detector");
16
+ const { scanStructure } = require("./structure-scanner");
17
+ const { splitDomainGroups, determineActiveDomains, selectTemplates } = require("./domain-grouper");
18
+ const { generatePrompts } = require("./prompt-generator");
19
+
20
+ const ROOT = process.env.CLAUDEOS_ROOT || path.resolve(__dirname, "../..");
21
+ const GENERATED_DIR = path.join(ROOT, "claudeos-core/generated");
22
+ const TEMPLATES_DIR = path.join(__dirname, "../pass-prompts/templates");
23
+
24
+ async function main() {
25
+ console.log("\n╔═══════════════════════════════════════╗");
26
+ console.log("║ ClaudeOS-Core — Plan Installer ║");
27
+ console.log("╚═══════════════════════════════════════╝\n");
28
+
29
+ ensureDir(GENERATED_DIR);
30
+
31
+ // Phase 1: Stack detection
32
+ console.log(" [Phase 1] Detecting stack...");
33
+ const stack = await detectStack(ROOT);
34
+ console.log(` Language: ${stack.language || "unknown"} ${stack.languageVersion || ""}`);
35
+ console.log(` Framework: ${stack.framework || "none"} ${stack.frameworkVersion || ""}`);
36
+ if (!stack.language && !stack.framework) {
37
+ console.warn("\n ⚠️ No language or framework detected.");
38
+ console.warn(" Supported: Java, Kotlin, TypeScript, JavaScript, Python");
39
+ console.warn(" Ensure you have build.gradle, package.json, pyproject.toml, or requirements.txt in the project root.\n");
40
+ }
41
+ console.log(` Frontend: ${stack.frontend || "none"} ${stack.frontendVersion || ""}`);
42
+ console.log(` Database: ${stack.database || "none"}`);
43
+ console.log(` ORM: ${stack.orm || "none"}`);
44
+ console.log(` PackageMgr: ${stack.packageManager || "none"}\n`);
45
+
46
+ // Phase 2: Structure scan
47
+ console.log(" [Phase 2] Scanning structure...");
48
+ const { domains, backendDomains, frontendDomains, rootPackage, frontend } = await scanStructure(stack, ROOT);
49
+ console.log(` Backend: ${backendDomains.length} domains`);
50
+ console.log(` Frontend: ${frontendDomains.length} domains`);
51
+ console.log(` Total: ${domains.length} domains`);
52
+ if (rootPackage) console.log(` Package: ${rootPackage}`);
53
+ if (frontend.exists) console.log(` Components: ${frontend.components} components, ${frontend.pages} pages, ${frontend.hooks} hooks`);
54
+ if (backendDomains.length === 0 && frontendDomains.length === 0) {
55
+ console.warn("\n ⚠️ No domains detected.");
56
+ console.warn(" Pass 1 will be skipped. Generated output may be minimal.\n");
57
+ }
58
+ console.log();
59
+
60
+ // Phase 3: Template selection
61
+ console.log(" [Phase 3] Selecting templates...");
62
+ const templates = selectTemplates(stack);
63
+ const isMultiStack = !!(templates.backend && templates.frontend);
64
+ if (templates.backend) console.log(` Backend: ${templates.backend}`);
65
+ if (templates.frontend) console.log(` Frontend: ${templates.frontend}`);
66
+ console.log(` Mode: ${isMultiStack ? "🔀 Multi-stack" : "Single-stack"}`);
67
+ console.log();
68
+
69
+ // Phase 4: Domain group splitting
70
+ console.log(" [Phase 4] Splitting domain groups...");
71
+ const allGroups = [];
72
+ if (templates.backend && backendDomains.length > 0) allGroups.push(...splitDomainGroups(backendDomains, "backend", templates.backend));
73
+ if (templates.frontend && frontendDomains.length > 0) allGroups.push(...splitDomainGroups(frontendDomains, "frontend", templates.frontend));
74
+ allGroups.forEach((g, i) => { g.passNum = i + 1; });
75
+ allGroups.forEach((g, i) => {
76
+ const icon = g.type === "backend" ? "⚙️" : "🎨";
77
+ console.log(` ${icon} Group ${i + 1}: [${g.domains.join(", ")}] (${g.type}, ~${g.estimatedFiles} files)`);
78
+ });
79
+ console.log();
80
+
81
+ // Phase 5: Active domains
82
+ console.log(" [Phase 5] Active domains...");
83
+ const active = determineActiveDomains(stack);
84
+ Object.entries(active).forEach(([k, v]) => console.log(` ${v ? "✅" : "⏭️"} ${k}`));
85
+ console.log();
86
+
87
+ // Phase 6: Prompt generation
88
+ const lang = process.env.CLAUDEOS_LANG || "en";
89
+ console.log(` [Phase 6] Generating prompts (lang: ${lang})...`);
90
+ generatePrompts(templates, lang, TEMPLATES_DIR, GENERATED_DIR);
91
+ console.log();
92
+
93
+ // Save outputs
94
+ const defaultPort = (stack.framework === "fastapi" || stack.framework === "django") ? 8000
95
+ : stack.framework === "flask" ? 5000
96
+ : stack.framework === "vite" ? 5173
97
+ : stack.frontend === "angular" ? 4200
98
+ : stack.frontend === "nextjs" ? 3000
99
+ : (stack.framework === "express" || stack.framework === "nestjs" || stack.framework === "fastify") ? 3000 : 8080;
100
+ const analysis = {
101
+ analyzedAt: new Date().toISOString(), lang,
102
+ stack: { ...stack, port: stack.port || defaultPort },
103
+ templates, isMultiStack, rootPackage,
104
+ domains, backendDomains, frontendDomains, frontend,
105
+ activeDomains: active,
106
+ summary: {
107
+ totalDomains: domains.length, backendDomains: backendDomains.length,
108
+ frontendDomains: frontendDomains.length,
109
+ totalFiles: domains.reduce((s, d) => s + d.totalFiles, 0),
110
+ },
111
+ };
112
+ writeFileSafe(path.join(GENERATED_DIR, "project-analysis.json"), JSON.stringify(analysis, null, 2));
113
+ console.log(" 💾 project-analysis.json saved");
114
+
115
+ const domainGroups = {
116
+ generatedAt: new Date().toISOString(), isMultiStack, templates,
117
+ totalDomains: domains.length, totalGroups: allGroups.length,
118
+ maxDomainsPerGroup: 4, maxFilesPerGroup: 40, groups: allGroups,
119
+ };
120
+ writeFileSafe(path.join(GENERATED_DIR, "domain-groups.json"), JSON.stringify(domainGroups, null, 2));
121
+ console.log(" 💾 domain-groups.json saved\n");
122
+ console.log(" ✅ Plan Installer complete\n");
123
+ }
124
+
125
+ main().catch(e => {
126
+ console.error(`\n ❌ Plan Installer failed: ${e.message || e}`);
127
+ if (e.code === "EACCES" || e.code === "EPERM") console.error(" Check file/directory permissions.");
128
+ process.exit(1);
129
+ });