claudeos-core 2.2.0 → 2.3.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.
Files changed (49) hide show
  1. package/CHANGELOG.md +1664 -907
  2. package/CONTRIBUTING.md +92 -92
  3. package/README.de.md +28 -0
  4. package/README.es.md +28 -0
  5. package/README.fr.md +28 -0
  6. package/README.hi.md +28 -0
  7. package/README.ja.md +28 -0
  8. package/README.ko.md +1014 -986
  9. package/README.md +1016 -987
  10. package/README.ru.md +28 -0
  11. package/README.vi.md +1015 -987
  12. package/README.zh-CN.md +28 -0
  13. package/bin/cli.js +152 -148
  14. package/bin/commands/init.js +1673 -1554
  15. package/bin/commands/lint.js +62 -0
  16. package/bin/commands/memory.js +438 -438
  17. package/bin/lib/cli-utils.js +206 -206
  18. package/claude-md-validator/index.js +184 -0
  19. package/claude-md-validator/reporter.js +66 -0
  20. package/claude-md-validator/structural-checks.js +528 -0
  21. package/content-validator/index.js +666 -441
  22. package/lib/expected-guides.js +23 -23
  23. package/lib/expected-outputs.js +90 -90
  24. package/lib/language-config.js +35 -35
  25. package/lib/memory-scaffold.js +1058 -1054
  26. package/lib/plan-parser.js +165 -165
  27. package/lib/staged-rules.js +118 -118
  28. package/manifest-generator/index.js +174 -174
  29. package/package.json +90 -87
  30. package/pass-json-validator/index.js +337 -337
  31. package/pass-prompts/templates/common/claude-md-scaffold.md +52 -10
  32. package/pass-prompts/templates/common/pass3-footer.md +402 -224
  33. package/pass-prompts/templates/common/pass3b-core-header.md +43 -0
  34. package/pass-prompts/templates/common/pass4.md +375 -305
  35. package/pass-prompts/templates/common/staging-override.md +26 -26
  36. package/pass-prompts/templates/node-vite/pass1.md +117 -117
  37. package/pass-prompts/templates/node-vite/pass2.md +78 -78
  38. package/pass-prompts/templates/python-flask/pass1.md +119 -119
  39. package/pass-prompts/templates/python-flask/pass2.md +85 -85
  40. package/plan-installer/domain-grouper.js +76 -76
  41. package/plan-installer/index.js +137 -137
  42. package/plan-installer/prompt-generator.js +188 -145
  43. package/plan-installer/scanners/scan-frontend.js +505 -473
  44. package/plan-installer/scanners/scan-java.js +226 -226
  45. package/plan-installer/scanners/scan-node.js +57 -57
  46. package/plan-installer/scanners/scan-python.js +85 -85
  47. package/plan-installer/stack-detector.js +482 -482
  48. package/plan-installer/structure-scanner.js +65 -65
  49. package/sync-checker/index.js +177 -177
@@ -1,85 +1,85 @@
1
- /**
2
- * ClaudeOS-Core — Python Structure Scanner
3
- *
4
- * Scans Python (Django/FastAPI/Flask) project structure to discover domains.
5
- */
6
-
7
- const path = require("path");
8
- const { glob } = require("glob");
9
-
10
- async function scanPythonDomains(stack, ROOT) {
11
- const backendDomains = [];
12
-
13
- // ── Django ──
14
- if (stack.framework === "django") {
15
- const candidates = await glob("**/models.py", { cwd: ROOT, ignore: ["**/node_modules/**", "**/venv/**", "**/.venv/**", "**/env/**", "**/migrations/**"] });
16
- for (const f of candidates) {
17
- const dir = path.dirname(f);
18
- if (dir === "." || dir.includes("venv")) continue;
19
- const name = path.basename(dir);
20
- const appFiles = await glob(`${dir.replace(/\\/g, "/")}/*.py`, { cwd: ROOT });
21
- const views = appFiles.filter(x => x.includes("views")).length;
22
- const models = appFiles.filter(x => x.includes("models")).length;
23
- const serializers = appFiles.filter(x => x.includes("serializers")).length;
24
- const admin = appFiles.filter(x => x.includes("admin")).length;
25
- const forms = appFiles.filter(x => x.includes("forms")).length;
26
- const urls = appFiles.filter(x => x.includes("urls")).length;
27
- const tasks = appFiles.filter(x => x.includes("tasks")).length;
28
- const domain = { name, type: "backend", views, models, serializers, totalFiles: appFiles.length };
29
- if (admin > 0) domain.admin = admin;
30
- if (forms > 0) domain.forms = forms;
31
- if (urls > 0) domain.urls = urls;
32
- if (tasks > 0) domain.tasks = tasks;
33
- backendDomains.push(domain);
34
- }
35
- }
36
-
37
- // ── FastAPI / Flask / generic Python ──
38
- if (stack.framework === "fastapi" || stack.framework === "flask" || (stack.language === "python" && stack.framework !== "django")) {
39
- const routerFiles = await glob("**/{router,routes,endpoints}*.py", { cwd: ROOT, ignore: ["**/venv/**", "**/.venv/**"] });
40
- const seen = new Set();
41
- for (const f of routerFiles) {
42
- const dir = path.dirname(f);
43
- const name = path.basename(dir);
44
- if (name === "." || seen.has(name) || ["venv", ".venv", "__pycache__"].includes(name)) continue;
45
- seen.add(name);
46
- const appFiles = await glob(`${dir.replace(/\\/g, "/")}/*.py`, { cwd: ROOT });
47
- backendDomains.push({ name, type: "backend", totalFiles: appFiles.length });
48
- }
49
- if (backendDomains.filter(d => d.type === "backend").length === 0) {
50
- const appDirs = await glob("{app,src/app}/*/", { cwd: ROOT });
51
- for (let dir of appDirs) {
52
- if (!dir.endsWith("/")) dir += "/";
53
- const name = path.basename(dir.replace(/\/$/, ""));
54
- if (["core", "common", "utils", "__pycache__"].includes(name)) continue;
55
- const files = await glob(`${dir.replace(/\\/g, "/")}*.py`, { cwd: ROOT });
56
- if (files.length > 0) backendDomains.push({ name, type: "backend", totalFiles: files.length });
57
- }
58
- }
59
- // Flat project fallback: main.py or app.py at root or in app/ directory with no subdomain structure
60
- if (backendDomains.filter(d => d.type === "backend").length === 0) {
61
- const flatEntries = await glob("{main,app}.py", { cwd: ROOT, ignore: ["**/venv/**", "**/.venv/**"] });
62
- if (flatEntries.length > 0) {
63
- const allPy = await glob("*.py", { cwd: ROOT, ignore: ["**/venv/**", "**/.venv/**", "setup.py", "conftest.py"] });
64
- if (allPy.length > 0) {
65
- backendDomains.push({ name: "app", type: "backend", totalFiles: allPy.length, flat: true });
66
- }
67
- }
68
- // Also check app/ directory with main.py but no subdirectories
69
- if (backendDomains.filter(d => d.type === "backend").length === 0) {
70
- const appMain = await glob("{app,src/app}/{main,app}.py", { cwd: ROOT, ignore: ["**/venv/**", "**/.venv/**"] });
71
- if (appMain.length > 0) {
72
- const dir = path.dirname(appMain[0]).replace(/\\/g, "/");
73
- const appPy = await glob(`${dir}/*.py`, { cwd: ROOT });
74
- if (appPy.length > 0) {
75
- backendDomains.push({ name: path.basename(dir), type: "backend", totalFiles: appPy.length, flat: true });
76
- }
77
- }
78
- }
79
- }
80
- }
81
-
82
- return { backendDomains };
83
- }
84
-
85
- module.exports = { scanPythonDomains };
1
+ /**
2
+ * ClaudeOS-Core — Python Structure Scanner
3
+ *
4
+ * Scans Python (Django/FastAPI/Flask) project structure to discover domains.
5
+ */
6
+
7
+ const path = require("path");
8
+ const { glob } = require("glob");
9
+
10
+ async function scanPythonDomains(stack, ROOT) {
11
+ const backendDomains = [];
12
+
13
+ // ── Django ──
14
+ if (stack.framework === "django") {
15
+ const candidates = await glob("**/models.py", { cwd: ROOT, ignore: ["**/node_modules/**", "**/venv/**", "**/.venv/**", "**/env/**", "**/migrations/**"] });
16
+ for (const f of candidates) {
17
+ const dir = path.dirname(f);
18
+ if (dir === "." || dir.includes("venv")) continue;
19
+ const name = path.basename(dir);
20
+ const appFiles = await glob(`${dir.replace(/\\/g, "/")}/*.py`, { cwd: ROOT });
21
+ const views = appFiles.filter(x => x.includes("views")).length;
22
+ const models = appFiles.filter(x => x.includes("models")).length;
23
+ const serializers = appFiles.filter(x => x.includes("serializers")).length;
24
+ const admin = appFiles.filter(x => x.includes("admin")).length;
25
+ const forms = appFiles.filter(x => x.includes("forms")).length;
26
+ const urls = appFiles.filter(x => x.includes("urls")).length;
27
+ const tasks = appFiles.filter(x => x.includes("tasks")).length;
28
+ const domain = { name, type: "backend", views, models, serializers, totalFiles: appFiles.length };
29
+ if (admin > 0) domain.admin = admin;
30
+ if (forms > 0) domain.forms = forms;
31
+ if (urls > 0) domain.urls = urls;
32
+ if (tasks > 0) domain.tasks = tasks;
33
+ backendDomains.push(domain);
34
+ }
35
+ }
36
+
37
+ // ── FastAPI / Flask / generic Python ──
38
+ if (stack.framework === "fastapi" || stack.framework === "flask" || (stack.language === "python" && stack.framework !== "django")) {
39
+ const routerFiles = await glob("**/{router,routes,endpoints}*.py", { cwd: ROOT, ignore: ["**/venv/**", "**/.venv/**"] });
40
+ const seen = new Set();
41
+ for (const f of routerFiles) {
42
+ const dir = path.dirname(f);
43
+ const name = path.basename(dir);
44
+ if (name === "." || seen.has(name) || ["venv", ".venv", "__pycache__"].includes(name)) continue;
45
+ seen.add(name);
46
+ const appFiles = await glob(`${dir.replace(/\\/g, "/")}/*.py`, { cwd: ROOT });
47
+ backendDomains.push({ name, type: "backend", totalFiles: appFiles.length });
48
+ }
49
+ if (backendDomains.filter(d => d.type === "backend").length === 0) {
50
+ const appDirs = await glob("{app,src/app}/*/", { cwd: ROOT });
51
+ for (let dir of appDirs) {
52
+ if (!dir.endsWith("/")) dir += "/";
53
+ const name = path.basename(dir.replace(/\/$/, ""));
54
+ if (["core", "common", "utils", "__pycache__"].includes(name)) continue;
55
+ const files = await glob(`${dir.replace(/\\/g, "/")}*.py`, { cwd: ROOT });
56
+ if (files.length > 0) backendDomains.push({ name, type: "backend", totalFiles: files.length });
57
+ }
58
+ }
59
+ // Flat project fallback: main.py or app.py at root or in app/ directory with no subdomain structure
60
+ if (backendDomains.filter(d => d.type === "backend").length === 0) {
61
+ const flatEntries = await glob("{main,app}.py", { cwd: ROOT, ignore: ["**/venv/**", "**/.venv/**"] });
62
+ if (flatEntries.length > 0) {
63
+ const allPy = await glob("*.py", { cwd: ROOT, ignore: ["**/venv/**", "**/.venv/**", "setup.py", "conftest.py"] });
64
+ if (allPy.length > 0) {
65
+ backendDomains.push({ name: "app", type: "backend", totalFiles: allPy.length, flat: true });
66
+ }
67
+ }
68
+ // Also check app/ directory with main.py but no subdirectories
69
+ if (backendDomains.filter(d => d.type === "backend").length === 0) {
70
+ const appMain = await glob("{app,src/app}/{main,app}.py", { cwd: ROOT, ignore: ["**/venv/**", "**/.venv/**"] });
71
+ if (appMain.length > 0) {
72
+ const dir = path.dirname(appMain[0]).replace(/\\/g, "/");
73
+ const appPy = await glob(`${dir}/*.py`, { cwd: ROOT });
74
+ if (appPy.length > 0) {
75
+ backendDomains.push({ name: path.basename(dir), type: "backend", totalFiles: appPy.length, flat: true });
76
+ }
77
+ }
78
+ }
79
+ }
80
+ }
81
+
82
+ return { backendDomains };
83
+ }
84
+
85
+ module.exports = { scanPythonDomains };