claudeos-core 1.7.0 → 2.0.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.
Files changed (39) hide show
  1. package/CHANGELOG.md +138 -0
  2. package/CONTRIBUTING.md +92 -59
  3. package/README.de.md +465 -240
  4. package/README.es.md +446 -223
  5. package/README.fr.md +461 -238
  6. package/README.hi.md +485 -261
  7. package/README.ja.md +440 -235
  8. package/README.ko.md +244 -56
  9. package/README.md +215 -47
  10. package/README.ru.md +462 -238
  11. package/README.vi.md +454 -230
  12. package/README.zh-CN.md +476 -252
  13. package/bin/cli.js +144 -140
  14. package/bin/commands/init.js +550 -46
  15. package/bin/commands/memory.js +426 -0
  16. package/bin/lib/cli-utils.js +206 -143
  17. package/bootstrap.sh +81 -390
  18. package/content-validator/index.js +436 -340
  19. package/lib/expected-guides.js +23 -0
  20. package/lib/expected-outputs.js +91 -0
  21. package/lib/language-config.js +35 -0
  22. package/lib/memory-scaffold.js +1014 -0
  23. package/lib/plan-parser.js +153 -149
  24. package/lib/staged-rules.js +118 -0
  25. package/manifest-generator/index.js +176 -171
  26. package/package.json +1 -1
  27. package/pass-json-validator/index.js +337 -299
  28. package/pass-prompts/templates/common/pass3-footer.md +16 -0
  29. package/pass-prompts/templates/common/pass4.md +317 -0
  30. package/pass-prompts/templates/common/staging-override.md +26 -0
  31. package/pass-prompts/templates/python-flask/pass1.md +119 -0
  32. package/pass-prompts/templates/python-flask/pass2.md +85 -0
  33. package/pass-prompts/templates/python-flask/pass3.md +103 -0
  34. package/plan-installer/domain-grouper.js +2 -1
  35. package/plan-installer/prompt-generator.js +120 -96
  36. package/plan-installer/scanners/scan-frontend.js +219 -10
  37. package/plan-installer/scanners/scan-java.js +226 -223
  38. package/plan-installer/scanners/scan-python.js +21 -0
  39. package/sync-checker/index.js +133 -132
@@ -1,132 +1,133 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * ClaudeOS-Core — Sync Checker
5
- *
6
- * Role: Check disk ↔ Master Plan sync status based on sync-map.json
7
- * Detection items:
8
- * - Unregistered: file exists on disk but not registered in any plan
9
- * - Orphaned: registered in plan but missing from disk
10
- *
11
- * Usage: npx claudeos-core <cmd> or node claudeos-core-tools/sync-checker/index.js
12
- * Depends: manifest-generator must run first (sync-map.json)
13
- */
14
-
15
- const fs = require("fs");
16
- const path = require("path");
17
- const { glob } = require("glob");
18
- const { updateStaleReport } = require("../lib/stale-report");
19
-
20
- const ROOT = process.env.CLAUDEOS_ROOT || path.resolve(__dirname, "../..");
21
- const GEN = path.join(ROOT, "claudeos-core/generated");
22
- const SMP = path.join(GEN, "sync-map.json");
23
-
24
- const TRACKED = [
25
- { dir: ".claude/rules", pfx: "rules" },
26
- { dir: "claudeos-core/standard", pfx: "standard" },
27
- { dir: "claudeos-core/skills", pfx: "skills" },
28
- { dir: "claudeos-core/guide", pfx: "guide" },
29
- { dir: "claudeos-core/database", pfx: "database" },
30
- { dir: "claudeos-core/mcp-guide", pfx: "mcp-guide" },
31
- ];
32
-
33
- function rel(p) {
34
- return path.relative(ROOT, p).replace(/\\/g, "/");
35
- }
36
-
37
- function isWithinRoot(absPath) {
38
- let resolved = path.resolve(absPath);
39
- let root = path.resolve(ROOT);
40
- if (process.platform === "win32") {
41
- resolved = resolved.toLowerCase();
42
- root = root.toLowerCase();
43
- }
44
- return resolved === root || resolved.startsWith(root + path.sep);
45
- }
46
-
47
- async function main() {
48
- console.log("\n╔═══════════════════════════════════════╗");
49
- console.log("║ ClaudeOS-Core — Sync Checker ║");
50
- console.log("╚═══════════════════════════════════════╝\n");
51
-
52
- if (!fs.existsSync(SMP)) {
53
- console.log(" sync-map.json not found. Run manifest-generator first.\n");
54
- process.exit(1);
55
- }
56
-
57
- let sm;
58
- try {
59
- sm = JSON.parse(fs.readFileSync(SMP, "utf-8"));
60
- } catch (e) {
61
- console.log(` sync-map.json is malformed: ${e.message}\n`);
62
- process.exit(1);
63
- }
64
- if (!Array.isArray(sm.mappings)) {
65
- console.log(" sync-map.json has no mappings array.\n");
66
- process.exit(1);
67
- }
68
- const reg = new Set(sm.mappings.map((m) => m.sourcePath).filter(Boolean));
69
- const issues = { unreg: [], orphan: [] };
70
-
71
- // ─── [1/2] Disk → Plan: detect unregistered files ───────
72
- console.log(" [1/2] Disk → Plan...");
73
- for (const t of TRACKED) {
74
- const abs = path.join(ROOT, t.dir);
75
- if (!fs.existsSync(abs)) continue;
76
-
77
- for (const f of await glob("**/*.md", { cwd: abs, absolute: true })) {
78
- const r = rel(f);
79
- if (path.basename(f) === "README.md") continue;
80
- if (!reg.has(r)) {
81
- issues.unreg.push({ path: r, domain: t.pfx });
82
- }
83
- }
84
- }
85
-
86
- // Check CLAUDE.md separately
87
- if (fs.existsSync(path.join(ROOT, "CLAUDE.md")) && !reg.has("CLAUDE.md")) {
88
- issues.unreg.push({ path: "CLAUDE.md", domain: "root" });
89
- }
90
-
91
- // ─── [2/2] Plan → Disk: detect orphaned files ───────────────
92
- console.log(" [2/2] Plan → Disk...");
93
- for (const m of sm.mappings) {
94
- if (!m.sourcePath) continue;
95
- const abs = path.join(ROOT, m.sourcePath);
96
- // Skip path traversal attempts (allow files at ROOT level and below)
97
- if (!isWithinRoot(abs)) continue;
98
- if (!fs.existsSync(abs)) {
99
- issues.orphan.push({ path: m.sourcePath, plan: m.planFile });
100
- }
101
- }
102
-
103
- // ─── Output results ─────────────────────────────────────────
104
- if (issues.unreg.length) {
105
- console.log(`\n ⚠️ Unregistered (${issues.unreg.length}):`);
106
- issues.unreg.forEach((i) => console.log(` + ${i.path}`));
107
- }
108
- if (issues.orphan.length) {
109
- console.log(`\n ⚠️ Orphaned (${issues.orphan.length}):`);
110
- issues.orphan.forEach((i) => console.log(` - ${i.path}`));
111
- }
112
-
113
- const total = issues.unreg.length + issues.orphan.length;
114
- console.log(`\n Registered: ${reg.size} | Unregistered: ${issues.unreg.length} | Orphaned: ${issues.orphan.length}`);
115
- console.log(total === 0 ? " ✅ All in sync\n" : ` ⚠️ ${total} issues\n`);
116
-
117
- // ─── Update stale-report.json ────────────────────────────
118
- updateStaleReport(GEN, "syncMisses",
119
- { checkedAt: new Date().toISOString(), unregistered: issues.unreg, orphaned: issues.orphan },
120
- { syncIssues: total, status: total === 0 ? "ok" : "warning" }
121
- );
122
-
123
- // Exit 1 only for orphaned files (actual breakage), not for unregistered (informational)
124
- const orphanCount = issues.orphan.length;
125
- process.exit(orphanCount > 0 ? 1 : 0);
126
- }
127
-
128
- if (require.main === module) {
129
- main().catch(e => { console.error(`\n ❌ Unexpected error: ${e.message || e}`); process.exit(1); });
130
- }
131
-
132
- module.exports = { main };
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * ClaudeOS-Core — Sync Checker
5
+ *
6
+ * Role: Check disk ↔ Master Plan sync status based on sync-map.json
7
+ * Detection items:
8
+ * - Unregistered: file exists on disk but not registered in any plan
9
+ * - Orphaned: registered in plan but missing from disk
10
+ *
11
+ * Usage: npx claudeos-core <cmd> or node claudeos-core-tools/sync-checker/index.js
12
+ * Depends: manifest-generator must run first (sync-map.json)
13
+ */
14
+
15
+ const fs = require("fs");
16
+ const path = require("path");
17
+ const { glob } = require("glob");
18
+ const { updateStaleReport } = require("../lib/stale-report");
19
+
20
+ const ROOT = process.env.CLAUDEOS_ROOT || path.resolve(__dirname, "../..");
21
+ const GEN = path.join(ROOT, "claudeos-core/generated");
22
+ const SMP = path.join(GEN, "sync-map.json");
23
+
24
+ const TRACKED = [
25
+ { dir: ".claude/rules", pfx: "rules" },
26
+ { dir: "claudeos-core/standard", pfx: "standard" },
27
+ { dir: "claudeos-core/skills", pfx: "skills" },
28
+ { dir: "claudeos-core/guide", pfx: "guide" },
29
+ { dir: "claudeos-core/database", pfx: "database" },
30
+ { dir: "claudeos-core/mcp-guide", pfx: "mcp-guide" },
31
+ { dir: "claudeos-core/memory", pfx: "memory" },
32
+ ];
33
+
34
+ function rel(p) {
35
+ return path.relative(ROOT, p).replace(/\\/g, "/");
36
+ }
37
+
38
+ function isWithinRoot(absPath) {
39
+ let resolved = path.resolve(absPath);
40
+ let root = path.resolve(ROOT);
41
+ if (process.platform === "win32") {
42
+ resolved = resolved.toLowerCase();
43
+ root = root.toLowerCase();
44
+ }
45
+ return resolved === root || resolved.startsWith(root + path.sep);
46
+ }
47
+
48
+ async function main() {
49
+ console.log("\n╔═══════════════════════════════════════╗");
50
+ console.log("║ ClaudeOS-Core — Sync Checker ║");
51
+ console.log("╚═══════════════════════════════════════╝\n");
52
+
53
+ if (!fs.existsSync(SMP)) {
54
+ console.log(" ❌ sync-map.json not found. Run manifest-generator first.\n");
55
+ process.exit(1);
56
+ }
57
+
58
+ let sm;
59
+ try {
60
+ sm = JSON.parse(fs.readFileSync(SMP, "utf-8"));
61
+ } catch (e) {
62
+ console.log(` ❌ sync-map.json is malformed: ${e.message}\n`);
63
+ process.exit(1);
64
+ }
65
+ if (!Array.isArray(sm.mappings)) {
66
+ console.log(" ❌ sync-map.json has no mappings array.\n");
67
+ process.exit(1);
68
+ }
69
+ const reg = new Set(sm.mappings.map((m) => m.sourcePath).filter(Boolean));
70
+ const issues = { unreg: [], orphan: [] };
71
+
72
+ // ─── [1/2] Disk → Plan: detect unregistered files ───────
73
+ console.log(" [1/2] Disk Plan...");
74
+ for (const t of TRACKED) {
75
+ const abs = path.join(ROOT, t.dir);
76
+ if (!fs.existsSync(abs)) continue;
77
+
78
+ for (const f of await glob("**/*.md", { cwd: abs, absolute: true })) {
79
+ const r = rel(f);
80
+ if (path.basename(f) === "README.md") continue;
81
+ if (!reg.has(r)) {
82
+ issues.unreg.push({ path: r, domain: t.pfx });
83
+ }
84
+ }
85
+ }
86
+
87
+ // Check CLAUDE.md separately
88
+ if (fs.existsSync(path.join(ROOT, "CLAUDE.md")) && !reg.has("CLAUDE.md")) {
89
+ issues.unreg.push({ path: "CLAUDE.md", domain: "root" });
90
+ }
91
+
92
+ // ─── [2/2] Plan → Disk: detect orphaned files ───────────────
93
+ console.log(" [2/2] Plan Disk...");
94
+ for (const m of sm.mappings) {
95
+ if (!m.sourcePath) continue;
96
+ const abs = path.join(ROOT, m.sourcePath);
97
+ // Skip path traversal attempts (allow files at ROOT level and below)
98
+ if (!isWithinRoot(abs)) continue;
99
+ if (!fs.existsSync(abs)) {
100
+ issues.orphan.push({ path: m.sourcePath, plan: m.planFile });
101
+ }
102
+ }
103
+
104
+ // ─── Output results ─────────────────────────────────────────
105
+ if (issues.unreg.length) {
106
+ console.log(`\n ⚠️ Unregistered (${issues.unreg.length}):`);
107
+ issues.unreg.forEach((i) => console.log(` + ${i.path}`));
108
+ }
109
+ if (issues.orphan.length) {
110
+ console.log(`\n ⚠️ Orphaned (${issues.orphan.length}):`);
111
+ issues.orphan.forEach((i) => console.log(` - ${i.path}`));
112
+ }
113
+
114
+ const total = issues.unreg.length + issues.orphan.length;
115
+ console.log(`\n Registered: ${reg.size} | Unregistered: ${issues.unreg.length} | Orphaned: ${issues.orphan.length}`);
116
+ console.log(total === 0 ? " ✅ All in sync\n" : ` ⚠️ ${total} issues\n`);
117
+
118
+ // ─── Update stale-report.json ────────────────────────────
119
+ updateStaleReport(GEN, "syncMisses",
120
+ { checkedAt: new Date().toISOString(), unregistered: issues.unreg, orphaned: issues.orphan },
121
+ { syncIssues: total, status: total === 0 ? "ok" : "warning" }
122
+ );
123
+
124
+ // Exit 1 only for orphaned files (actual breakage), not for unregistered (informational)
125
+ const orphanCount = issues.orphan.length;
126
+ process.exit(orphanCount > 0 ? 1 : 0);
127
+ }
128
+
129
+ if (require.main === module) {
130
+ main().catch(e => { console.error(`\n ❌ Unexpected error: ${e.message || e}`); process.exit(1); });
131
+ }
132
+
133
+ module.exports = { main };