claudeos-core 2.3.1 → 2.4.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 (43) hide show
  1. package/CHANGELOG.md +1460 -73
  2. package/CODE_OF_CONDUCT.md +15 -0
  3. package/README.de.md +321 -883
  4. package/README.es.md +322 -883
  5. package/README.fr.md +322 -883
  6. package/README.hi.md +322 -883
  7. package/README.ja.md +322 -883
  8. package/README.ko.md +322 -882
  9. package/README.md +321 -883
  10. package/README.ru.md +322 -885
  11. package/README.vi.md +322 -883
  12. package/README.zh-CN.md +321 -881
  13. package/SECURITY.md +51 -0
  14. package/bin/commands/init.js +570 -264
  15. package/content-validator/index.js +185 -12
  16. package/health-checker/index.js +44 -10
  17. package/package.json +92 -90
  18. package/pass-json-validator/index.js +58 -7
  19. package/pass-prompts/templates/angular/pass3.md +15 -14
  20. package/pass-prompts/templates/common/claude-md-scaffold.md +203 -20
  21. package/pass-prompts/templates/common/pass3-footer.md +297 -56
  22. package/pass-prompts/templates/common/pass3a-facts.md +48 -3
  23. package/pass-prompts/templates/common/pass4.md +78 -40
  24. package/pass-prompts/templates/java-spring/pass1.md +54 -0
  25. package/pass-prompts/templates/java-spring/pass3.md +20 -19
  26. package/pass-prompts/templates/kotlin-spring/pass1.md +45 -0
  27. package/pass-prompts/templates/kotlin-spring/pass3.md +24 -23
  28. package/pass-prompts/templates/node-express/pass3.md +18 -17
  29. package/pass-prompts/templates/node-fastify/pass3.md +11 -10
  30. package/pass-prompts/templates/node-nestjs/pass3.md +11 -10
  31. package/pass-prompts/templates/node-nextjs/pass3.md +18 -17
  32. package/pass-prompts/templates/node-vite/pass3.md +11 -10
  33. package/pass-prompts/templates/python-django/pass3.md +18 -17
  34. package/pass-prompts/templates/python-fastapi/pass3.md +18 -17
  35. package/pass-prompts/templates/python-flask/pass3.md +9 -8
  36. package/pass-prompts/templates/vue-nuxt/pass3.md +9 -8
  37. package/plan-installer/domain-grouper.js +45 -5
  38. package/plan-installer/index.js +34 -1
  39. package/plan-installer/pass3-context-builder.js +14 -0
  40. package/plan-installer/scanners/scan-frontend.js +2 -1
  41. package/plan-installer/scanners/scan-java.js +98 -2
  42. package/plan-installer/source-paths.js +242 -0
  43. package/plan-installer/stack-detector.js +522 -42
@@ -409,7 +409,7 @@ async function main() {
409
409
  }
410
410
 
411
411
  // ─── 10. Path-claim verification ──────────────────────────
412
- // Catches two dogfood-surfaced failure classes:
412
+ // Catches two failure classes:
413
413
  // (a) Pass 3 hallucinations: rules/standard files reference
414
414
  // src/... paths the LLM fabricated from directory context
415
415
  // (e.g., `src/feature/routers/featureRoutePath.ts` when the actual
@@ -427,9 +427,118 @@ async function main() {
427
427
  // inline code already fenced. We still strip fenced blocks first so
428
428
  // example blocks inside ```...``` don't produce false positives.
429
429
  const SRC_PATH_RE = /\bsrc\/[\w\-./]+\.(?:ts|tsx|js|jsx)\b/g;
430
- // Placeholder paths like `src/{domain}/...` are scaffold templates,
431
- // not real path claims. Skip them.
432
- const hasPlaceholder = (p) => /\{[^}]+\}/.test(p);
430
+
431
+ // Placeholder paths are scaffold templates / teaching examples, not
432
+ // real path claims. We skip them. Three patterns qualify:
433
+ // 1. Curly-brace placeholder — `src/{domain}/api/{Entity}.ts`
434
+ // (the original v2.3.0 form).
435
+ // 2. Xxx-style placeholder — `src/hooks/useXxx.ts` or
436
+ // `src/pages/PageXxx.tsx` (LLMs commonly use `Xxx`/`XXX` as
437
+ // "insert-your-name-here"; this form has been observed in
438
+ // `naming-conventions-rules.md`). We match any segment
439
+ // containing `Xxx` or `XXX` as a distinctive token.
440
+ // 3. Glob-star placeholder — `src/test/*.setup.ts` or
441
+ // `src/*/mocks/handlers.ts` (conventional glob syntax that an
442
+ // LLM may use to describe a *class* of files rather than one
443
+ // specific file).
444
+ // Literal paths that happen to contain `x`/`X` as part of a real
445
+ // identifier (e.g., `src/utils/xyzParser.ts`) do NOT match these
446
+ // patterns — the placeholder regex requires the `Xxx` pattern
447
+ // (capital-lower-lower, a distinctive convention) OR three or more
448
+ // consecutive uppercase X's. The uppercase-XXX rule has NO word-
449
+ // boundary anchor because placeholder tokens commonly appear in
450
+ // the middle of a compound identifier (`useXXX`, `useXXX_CONFIG`,
451
+ // `nameXXXvalue`, `XXXParser`) — requiring a boundary would skip
452
+ // those cases. Three consecutive uppercase X's in a row is a
453
+ // distinctive signal that essentially never appears in ordinary
454
+ // identifiers (lowercase `xxx` CAN appear in words like `taxXxxRate`,
455
+ // but three uppercase X's do not occur outside placeholder convention).
456
+ // v2.4.0 — Ellipsis (`...`) added as a placeholder marker.
457
+ //
458
+ // LLMs commonly use `...` to denote "any subdirectory" in illustrative
459
+ // path examples, e.g. `src/app/api/.../route.ts` to mean "any API
460
+ // route under app/api/". Treating these as STALE_PATH false-positives
461
+ // because `...` doesn't match the literal directory regex `[^/]+\.`,
462
+ // and because `...` can never be a real directory name (filesystems
463
+ // refuse it on most platforms — `.` and `..` are the only legal
464
+ // dot-only directory names). Three consecutive dots in a path segment
465
+ // are unambiguous placeholder signal.
466
+ const hasPlaceholder = (p) =>
467
+ /\{[^}]+\}/.test(p) || // {domain} style
468
+ /X{3,}/.test(p) || /Xxx/.test(p) || // XXX+ anywhere, or Xxx token
469
+ /\*/.test(p) || // glob star
470
+ /\/\.\.\.\//.test(p); // /.../ ellipsis path segment (v2.4.0)
471
+
472
+ // File-level exclusion: some generated rule files are DESIGNED to cite
473
+ // convention-trap paths as teaching examples — they tell the reader
474
+ // "don't invent paths like these". `content-validator`'s path-claim
475
+ // check is content-blind, so literal example paths inside such a file
476
+ // would be flagged as STALE_PATH even though the author intentionally
477
+ // listed them as cautionary illustrations.
478
+ //
479
+ // The exclusion is strictly opt-in, named by relative path, and
480
+ // limited to files whose purpose is educational-about-paths. Adding a
481
+ // file here is a deliberate design choice — the alternative is for
482
+ // the LLM to rewrite those examples as placeholders (Xxx / glob /
483
+ // prose), which the prompt now nudges toward but cannot strictly
484
+ // enforce.
485
+ //
486
+ // Current exclusions:
487
+ // - 00.core/52.ai-work-rules.md — the canonical "AI work rules"
488
+ // file, which by design lists convention-trap paths as warnings
489
+ // to future AI sessions. This file has been observed to
490
+ // accumulate STALE_PATH false positives when a prompt-level
491
+ // denylist primed the LLM to cite those exact paths as
492
+ // educational examples (the denylist has since been removed;
493
+ // this exclusion is the validator-side defense-in-depth).
494
+ // - 00.core/51.doc-writing-rules.md — the documentation writing
495
+ // rules file (v2.4.0). Same meta-doc class as 52.ai-work-rules.md:
496
+ // it teaches "verify file paths before writing them in documents"
497
+ // and naturally cites example paths (`src/middleware.ts`,
498
+ // `src/app/api/<route>/route.ts`) as illustrations of the rule.
499
+ // Those examples are NOT path claims — they are the lesson. The
500
+ // content-blind validator would otherwise flag every cited example
501
+ // as STALE_PATH on every project that doesn't happen to contain
502
+ // all the cited illustrative files. Excluded for the same reason
503
+ // and via the same mechanism as 52.ai-work-rules.md.
504
+ const PATH_CLAIM_EXCLUDE_FILES = new Set([
505
+ "00.core/52.ai-work-rules.md",
506
+ "00.core/51.doc-writing-rules.md",
507
+ ]);
508
+
509
+ // v2.4.0 — Resolve a `src/...` path claim against monorepo workspaces.
510
+ //
511
+ // Pre-v2.4.0 the validator only checked `<ROOT>/<claimed>` directly,
512
+ // which produced false-positive STALE_PATH advisories on Turborepo /
513
+ // pnpm-workspace projects where source files live under
514
+ // `apps/<app-name>/src/...` or `packages/<pkg-name>/src/...`. A rule
515
+ // citing `src/app/layout.tsx` is the natural single-app shorthand
516
+ // even when the actual file is at `apps/<app-name>/src/app/layout.tsx`.
517
+ //
518
+ // Resolution order (first match wins):
519
+ // 1. Direct: `<ROOT>/<claimed>` (single-app project)
520
+ // 2. Monorepo apps: `<ROOT>/apps/*/<claimed>`
521
+ // 3. Monorepo packages: `<ROOT>/packages/*/<claimed>`
522
+ //
523
+ // Returns true on first match, false if no match found anywhere.
524
+ // The monorepo fallback only fires for paths starting with `src/`,
525
+ // which is the conventional workspace-relative form. Non-`src/` paths
526
+ // (e.g., `claudeos-core/skills/...`) are checked direct-only.
527
+ function resolvePathClaim(ROOT, claimed) {
528
+ if (fs.existsSync(path.join(ROOT, claimed))) return true;
529
+ if (!claimed.startsWith("src/")) return false;
530
+ for (const workspace of ["apps", "packages"]) {
531
+ const wsDir = path.join(ROOT, workspace);
532
+ let entries;
533
+ try { entries = fs.readdirSync(wsDir, { withFileTypes: true }); }
534
+ catch (_e) { continue; }
535
+ for (const entry of entries) {
536
+ if (!entry.isDirectory()) continue;
537
+ if (fs.existsSync(path.join(wsDir, entry.name, claimed))) return true;
538
+ }
539
+ }
540
+ return false;
541
+ }
433
542
 
434
543
  // Strip fenced code blocks (``` and ~~~) so examples inside code
435
544
  // blocks don't trigger the check — they're illustrations, not claims.
@@ -459,10 +568,19 @@ async function main() {
459
568
  ];
460
569
  let pathClaimsChecked = 0;
461
570
  let pathClaimErrors = 0;
571
+ let pathClaimFilesExcluded = 0;
462
572
  for (const target of pathClaimTargets) {
463
573
  if (!fs.existsSync(target.dir)) continue;
464
574
  const files = await glob(target.glob, { cwd: target.dir, absolute: true });
465
575
  for (const file of files) {
576
+ // File-level exclusion: the path is relative to the target dir
577
+ // (e.g., "00.core/52.ai-work-rules.md" inside .claude/rules/).
578
+ // Normalize to forward slashes for cross-platform match.
579
+ const relToTargetDir = path.relative(target.dir, file).split(path.sep).join("/");
580
+ if (PATH_CLAIM_EXCLUDE_FILES.has(relToTargetDir)) {
581
+ pathClaimFilesExcluded++;
582
+ continue;
583
+ }
466
584
  const raw = fs.readFileSync(file, "utf-8");
467
585
  const stripped = stripFences(raw);
468
586
  const seen = new Set(); // dedupe within a single file
@@ -474,8 +592,7 @@ async function main() {
474
592
  seen.add(claimed);
475
593
  if (hasPlaceholder(claimed)) continue;
476
594
  pathClaimsChecked++;
477
- const absolutePath = path.join(ROOT, claimed);
478
- if (!fs.existsSync(absolutePath)) {
595
+ if (!resolvePathClaim(ROOT, claimed)) {
479
596
  pathClaimErrors++;
480
597
  errors.push({
481
598
  file: rel(file),
@@ -488,7 +605,8 @@ async function main() {
488
605
  }
489
606
  }
490
607
  }
491
- console.log(` ${pathClaimsChecked} path claim(s) checked, ${pathClaimErrors} stale`);
608
+ console.log(` ${pathClaimsChecked} path claim(s) checked, ${pathClaimErrors} stale` +
609
+ (pathClaimFilesExcluded > 0 ? ` (${pathClaimFilesExcluded} file(s) excluded by design)` : ""));
492
610
 
493
611
  // MANIFEST ↔ CLAUDE.md §6 Skills drift check.
494
612
  // MANIFEST registers skills in a 4-column table; each row's second
@@ -583,8 +701,13 @@ async function main() {
583
701
  // file of the form `skills/{category}/*{parent}*.md` (excluding
584
702
  // the sub-skill itself) counts as a plausible orchestrator.
585
703
  function orchestratorFor(subSkillPath) {
704
+ // Sub-skill path forms accepted (v2.4.0 generalization):
705
+ // skills/{category}/{parent-stem}/NN.{name}.md (legacy NN. prefix)
706
+ // skills/{category}/{parent-stem}/SKILL.md (v2.4.0 SKILL.md convention)
707
+ // skills/{category}/{parent-stem}/{name}.md (no NN. prefix)
708
+ // Captures `parent-stem` and the category directory.
586
709
  const m = subSkillPath.match(
587
- /^(claudeos-core\/skills\/[^/]+\/)([^/]+)\/\d+\.[^/]+\.md$/
710
+ /^(claudeos-core\/skills\/[^/]+\/)([^/]+)\/(?:\d+\.)?[^/]+\.md$/
588
711
  );
589
712
  if (!m) return null;
590
713
  return { categoryDir: m[1], stem: m[2] };
@@ -594,15 +717,47 @@ async function main() {
594
717
  // basename (minus leading number + dot) matches the sub-skill
595
718
  // parent stem. This accepts `01.scaffold-crud-feature.md`,
596
719
  // `scaffold-crud-feature.md`, etc.
720
+ // v2.4.0: a category-level `SKILL.md` (the orchestrator file
721
+ // colocated with `{category}/SKILL.md`) is treated as the
722
+ // orchestrator for ALL sub-skills under that category — this
723
+ // matches the new generator convention where each category has
724
+ // a single top-level orchestrator at `{category}/SKILL.md`.
597
725
  if (!ref.startsWith(categoryDir)) return false;
598
726
  const tail = ref.slice(categoryDir.length);
599
727
  // Must be a sibling file, not a nested path.
600
728
  if (tail.includes("/")) return false;
729
+ // v2.4.0 SKILL.md convention: a category-level SKILL.md covers
730
+ // every sub-skill in that category.
731
+ if (tail === "SKILL.md") return true;
601
732
  // Strip leading "NN." if present, then compare stem.
602
733
  const base = tail.replace(/^\d+\./, "").replace(/\.md$/, "");
603
734
  return base === stem;
604
735
  }
605
736
 
737
+ // Pre-compute: is any MANIFEST.md (the global skill registry)
738
+ // referenced anywhere in CLAUDE.md? Used as an additional
739
+ // sub-skill coverage rule below.
740
+ //
741
+ // Observed scenario: Pass 3c sometimes invents new sub-skill
742
+ // folder structures (e.g. `{category}/domains/{domain}.md` for
743
+ // per-domain notes) that weren't anticipated by the orchestrator
744
+ // pattern (which expects `{category}/{parent-stem}/{name}.md` paired
745
+ // with `{category}/{parent-stem}.md`). When this happens, every new
746
+ // sub-skill registration drifts because no sibling orchestrator exists.
747
+ //
748
+ // The architectural intent is that MANIFEST.md IS the registry — if
749
+ // CLAUDE.md §6 tells the reader "see MANIFEST.md for the full list",
750
+ // the reader can navigate to find every sub-skill. So mentioning
751
+ // MANIFEST.md anywhere in CLAUDE.md covers ALL sub-skill paths
752
+ // transitively. Top-level skills (direct `{category}/{file}.md`
753
+ // entries — those that don't match `orchestratorFor`) still require
754
+ // direct mention; this exception only applies to deep paths.
755
+ //
756
+ // Note: `referenced` Set above filters out MANIFEST.md entries (line
757
+ // 666), so we must scan the raw mdStripped text directly to detect
758
+ // MANIFEST.md mention.
759
+ const manifestReferencedGlobally = /`claudeos-core\/skills\/[\w\-./]*MANIFEST\.md`/.test(mdStripped);
760
+
606
761
  for (const p of registered) {
607
762
  if (referenced.has(p)) continue; // direct mention → OK
608
763
 
@@ -613,6 +768,7 @@ async function main() {
613
768
  isOrchestratorReferenced(ref, oc)
614
769
  );
615
770
  if (orchestratorMentioned) continue; // covered via orchestrator
771
+ if (manifestReferencedGlobally) continue; // covered via global MANIFEST
616
772
  }
617
773
 
618
774
  manifestErrors++;
@@ -634,14 +790,26 @@ async function main() {
634
790
  }
635
791
 
636
792
  // ─── Output results ─────────────────────────────────────────
793
+ //
794
+ // Terminology note (v2.3.3): the internal arrays stay named `errors` and
795
+ // `warnings` because they encode *severity* for programmatic consumers
796
+ // (health-checker's pass/fail gate, stale-report.json's schema, CI
797
+ // pipelines). The user-visible labels, however, are "advisories" and
798
+ // "notes" — because these are quality observations about LLM-generated
799
+ // documents, not test failures. A STALE_PATH doesn't mean `init` crashed;
800
+ // it means "AI guessed a filename that doesn't exist on disk — worth
801
+ // reviewing". Calling that an "error" made users think generation had
802
+ // actually failed. The exit code behavior is unchanged — this tool still
803
+ // returns 1 when advisories exist so `npx claudeos-core health` remains
804
+ // a real gate for CI.
637
805
  console.log(`\n Checked ${checked} files\n`);
638
806
  if (errors.length) {
639
- console.log(` ERRORS (${errors.length}):`);
807
+ console.log(` ℹ️ ADVISORIES (${errors.length}):`);
640
808
  errors.forEach(e => console.log(` [${e.type}] ${e.file}: ${e.msg}`));
641
809
  console.log();
642
810
  }
643
811
  if (warnings.length) {
644
- console.log(` ⚠️ WARNINGS (${warnings.length}):`);
812
+ console.log(` ⚠️ NOTES (${warnings.length}):`);
645
813
  warnings.forEach(w => console.log(` [${w.type}] ${w.file}: ${w.msg}`));
646
814
  console.log();
647
815
  }
@@ -649,13 +817,18 @@ async function main() {
649
817
  console.log(" ✅ All content validation passed\n");
650
818
  }
651
819
 
652
- // Record in stale-report
820
+ // Record in stale-report. Field names (`contentErrors`, `contentWarnings`)
821
+ // stay stable because they are part of stale-report.json's public schema
822
+ // that health-checker and external CI consumers read.
653
823
  updateStaleReport(GEN_DIR, "contentValidation",
654
824
  { checkedAt: new Date().toISOString(), checked, errors: errors.length, warnings: warnings.length, details: { errors, warnings } },
655
825
  { contentErrors: errors.length, contentWarnings: warnings.length }
656
826
  );
657
827
 
658
- console.log(` Total: ${errors.length} errors, ${warnings.length} warnings\n`);
828
+ console.log(` Total: ${errors.length} advisories, ${warnings.length} notes\n`);
829
+ // Exit code preserved (advisories → 1) so health-checker can still gate
830
+ // on this tool. The `init` orchestrator displays the result as a soft
831
+ // advisory regardless (see runContentValidator in bin/commands/init.js).
659
832
  process.exit(errors.length > 0 ? 1 : 0);
660
833
  }
661
834
 
@@ -61,11 +61,29 @@ function main() {
61
61
  console.log();
62
62
 
63
63
  // ─── [1-4] Run verification tools sequentially ────────────────────
64
+ //
65
+ // Tool status tiers (3-way):
66
+ // - default : non-zero exit → "fail" (❌, sets hasErr, blocks `health` exit code)
67
+ // - warnOnly:true : non-zero exit → "warn" (⚠️, does not set hasErr)
68
+ // - softFail:true : non-zero exit → "advisory" (ℹ️, does not set hasErr)
69
+ //
70
+ // The `softFail` tier (v2.4.0) was added for `content-validator` after
71
+ // user feedback: its findings are documentation quality notes
72
+ // (STALE_PATH suggestions, MANIFEST_DRIFT, NO_BAD_EXAMPLE) not generation
73
+ // failures, but pre-fix it surfaced as "❌ fail" alongside the
74
+ // "non-fatal" message — a confusing dual signal. `ℹ️ advisory` separates
75
+ // the visual from real structural failures (plan-validator,
76
+ // sync-checker, manifest-generator).
77
+ //
78
+ // `warnOnly` (existing) and `softFail` (new) are functionally similar at
79
+ // the gate level; the tier name encodes intent: warn = "watch this",
80
+ // advisory = "review when convenient". Both keep the health-check gate
81
+ // green.
64
82
  const tools = [
65
- { name: "plan-validator", script: path.join(TOOLS, "plan-validator/index.js"), desc: "Plan consistency" },
66
- { name: "sync-checker", script: path.join(TOOLS, "sync-checker/index.js"), desc: "Sync status" },
67
- { name: "content-validator", script: path.join(TOOLS, "content-validator/index.js"), desc: "Content quality" },
68
- { name: "pass-json-validator", script: path.join(TOOLS, "pass-json-validator/index.js"), desc: "JSON format", warnOnly: true },
83
+ { name: "plan-validator", script: path.join(TOOLS, "plan-validator/index.js"), desc: "Plan consistency" },
84
+ { name: "sync-checker", script: path.join(TOOLS, "sync-checker/index.js"), desc: "Sync status" },
85
+ { name: "content-validator", script: path.join(TOOLS, "content-validator/index.js"), desc: "Content quality", softFail: true },
86
+ { name: "pass-json-validator", script: path.join(TOOLS, "pass-json-validator/index.js"), desc: "JSON format", warnOnly: true },
69
87
  ];
70
88
 
71
89
  const results = [];
@@ -88,6 +106,9 @@ function main() {
88
106
  if (r.ok) {
89
107
  console.log(" ✅");
90
108
  results.push({ name: t.name, status: "pass" });
109
+ } else if (t.softFail) {
110
+ console.log(" ℹ️");
111
+ results.push({ name: t.name, status: "advisory" });
91
112
  } else if (t.warnOnly) {
92
113
  console.log(" ⚠️");
93
114
  results.push({ name: t.name, status: "warn" });
@@ -101,15 +122,28 @@ function main() {
101
122
  // ─── Results summary ──────────────────────────────────────────
102
123
  console.log("\n ══════════════════════════════");
103
124
  results.forEach((r) => {
104
- const icon = r.status === "pass" ? "✅" : r.status === "fail" ? "❌" : r.status === "warn" ? "⚠️" : "⏭️";
125
+ const icon = r.status === "pass" ? "✅"
126
+ : r.status === "fail" ? "❌"
127
+ : r.status === "warn" ? "⚠️"
128
+ : r.status === "advisory" ? "ℹ️"
129
+ : "⏭️";
105
130
  console.log(` ${icon} ${r.name.padEnd(22)} ${r.status}`);
106
131
  });
107
132
  console.log(" ──────────────────────────────");
108
- console.log(
109
- hasErr
110
- ? ` ⚠️ ${results.filter((r) => r.status === "fail").length} failed`
111
- : " All systems operational"
112
- );
133
+ // Summary line: distinguish real failures (block the gate) from
134
+ // advisory/warn results (informational, gate stays green).
135
+ const failCount = results.filter((r) => r.status === "fail").length;
136
+ const advisoryCount = results.filter((r) => r.status === "advisory").length;
137
+ const warnCount = results.filter((r) => r.status === "warn").length;
138
+ if (hasErr) {
139
+ console.log(` ⚠️ ${failCount} failed`);
140
+ } else {
141
+ const tail = [];
142
+ if (advisoryCount) tail.push(`${advisoryCount} advisory`);
143
+ if (warnCount) tail.push(`${warnCount} warning`);
144
+ const suffix = tail.length ? ` (${tail.join(", ")})` : "";
145
+ console.log(` ✅ All systems operational${suffix}`);
146
+ }
113
147
  console.log(" ══════════════════════════════\n");
114
148
 
115
149
  // ─── Update stale-report.json ────────────────────────────
package/package.json CHANGED
@@ -1,90 +1,92 @@
1
- {
2
- "name": "claudeos-core",
3
- "version": "2.3.1",
4
- "description": "Auto-generate Claude Code documentation from your actual source code — Standards, Rules, Skills, and Guides tailored to your project",
5
- "main": "bin/cli.js",
6
- "bin": {
7
- "claudeos-core": "bin/cli.js"
8
- },
9
- "files": [
10
- "bin/",
11
- "lib/",
12
- "claude-md-validator/",
13
- "content-validator/",
14
- "health-checker/",
15
- "manifest-generator/",
16
- "pass-json-validator/",
17
- "pass-prompts/",
18
- "plan-installer/",
19
- "plan-validator/",
20
- "sync-checker/",
21
- "bootstrap.sh",
22
- "README.md",
23
- "README.ko.md",
24
- "LICENSE",
25
- "CHANGELOG.md",
26
- "CONTRIBUTING.md",
27
- "README.zh-CN.md",
28
- "README.ja.md",
29
- "README.es.md",
30
- "README.vi.md",
31
- "README.hi.md",
32
- "README.ru.md",
33
- "README.fr.md",
34
- "README.de.md"
35
- ],
36
- "scripts": {
37
- "init": "node bin/cli.js init",
38
- "lint": "node bin/cli.js lint",
39
- "health": "node bin/cli.js health",
40
- "validate": "node bin/cli.js validate",
41
- "refresh": "node bin/cli.js refresh",
42
- "restore": "node bin/cli.js restore",
43
- "pretest": "node -e \"try{require('glob')}catch(e){process.exit(1)}\" || npm install",
44
- "test": "node scripts/run-tests.js",
45
- "test:health": "node health-checker/index.js"
46
- },
47
- "keywords": [
48
- "claude-code",
49
- "automation",
50
- "code-analysis",
51
- "CLAUDE.md",
52
- "standards",
53
- "rules",
54
- "skills",
55
- "scaffolding",
56
- "i18n",
57
- "multi-language",
58
- "spring-boot",
59
- "kotlin",
60
- "exposed",
61
- "jooq",
62
- "cqrs",
63
- "bff",
64
- "multi-module",
65
- "monorepo",
66
- "nextjs",
67
- "express",
68
- "fastify",
69
- "angular",
70
- "django",
71
- "fastapi"
72
- ],
73
- "author": "claudeos-core <claudeoscore@gmail.com> (https://github.com/claudeos-core)",
74
- "license": "ISC",
75
- "repository": {
76
- "type": "git",
77
- "url": "git+https://github.com/claudeos-core/claudeos-core.git"
78
- },
79
- "homepage": "https://github.com/claudeos-core/claudeos-core#readme",
80
- "bugs": {
81
- "url": "https://github.com/claudeos-core/claudeos-core/issues"
82
- },
83
- "engines": {
84
- "node": ">=18.0.0"
85
- },
86
- "dependencies": {
87
- "glob": "^13.0.6",
88
- "gray-matter": "^4.0.3"
89
- }
90
- }
1
+ {
2
+ "name": "claudeos-core",
3
+ "version": "2.4.0",
4
+ "description": "Auto-generate Claude Code documentation from your actual source code — Standards, Rules, Skills, and Guides tailored to your project",
5
+ "main": "bin/cli.js",
6
+ "bin": {
7
+ "claudeos-core": "bin/cli.js"
8
+ },
9
+ "files": [
10
+ "bin/",
11
+ "lib/",
12
+ "claude-md-validator/",
13
+ "content-validator/",
14
+ "health-checker/",
15
+ "manifest-generator/",
16
+ "pass-json-validator/",
17
+ "pass-prompts/",
18
+ "plan-installer/",
19
+ "plan-validator/",
20
+ "sync-checker/",
21
+ "bootstrap.sh",
22
+ "README.md",
23
+ "README.ko.md",
24
+ "LICENSE",
25
+ "CHANGELOG.md",
26
+ "CONTRIBUTING.md",
27
+ "CODE_OF_CONDUCT.md",
28
+ "SECURITY.md",
29
+ "README.zh-CN.md",
30
+ "README.ja.md",
31
+ "README.es.md",
32
+ "README.vi.md",
33
+ "README.hi.md",
34
+ "README.ru.md",
35
+ "README.fr.md",
36
+ "README.de.md"
37
+ ],
38
+ "scripts": {
39
+ "init": "node bin/cli.js init",
40
+ "lint": "node bin/cli.js lint",
41
+ "health": "node bin/cli.js health",
42
+ "validate": "node bin/cli.js validate",
43
+ "refresh": "node bin/cli.js refresh",
44
+ "restore": "node bin/cli.js restore",
45
+ "pretest": "node -e \"try{require('glob')}catch(e){process.exit(1)}\" || npm install",
46
+ "test": "node scripts/run-tests.js",
47
+ "test:health": "node health-checker/index.js"
48
+ },
49
+ "keywords": [
50
+ "claude-code",
51
+ "automation",
52
+ "code-analysis",
53
+ "CLAUDE.md",
54
+ "standards",
55
+ "rules",
56
+ "skills",
57
+ "scaffolding",
58
+ "i18n",
59
+ "multi-language",
60
+ "spring-boot",
61
+ "kotlin",
62
+ "exposed",
63
+ "jooq",
64
+ "cqrs",
65
+ "bff",
66
+ "multi-module",
67
+ "monorepo",
68
+ "nextjs",
69
+ "express",
70
+ "fastify",
71
+ "angular",
72
+ "django",
73
+ "fastapi"
74
+ ],
75
+ "author": "claudeos-core <claudeoscore@gmail.com> (https://github.com/claudeos-core)",
76
+ "license": "ISC",
77
+ "repository": {
78
+ "type": "git",
79
+ "url": "git+https://github.com/claudeos-core/claudeos-core.git"
80
+ },
81
+ "homepage": "https://github.com/claudeos-core/claudeos-core#readme",
82
+ "bugs": {
83
+ "url": "https://github.com/claudeos-core/claudeos-core/issues"
84
+ },
85
+ "engines": {
86
+ "node": ">=18.0.0"
87
+ },
88
+ "dependencies": {
89
+ "glob": "^13.0.6",
90
+ "gray-matter": "^4.0.3"
91
+ }
92
+ }