elcrm 1.1.4 → 1.1.5

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.
package/dist/index.js CHANGED
@@ -1538,18 +1538,50 @@ function inspectPkgCss(pkgName, cwd) {
1538
1538
  return null;
1539
1539
  const pkg = readPkgJson(root);
1540
1540
  const exp = pkg?.exports;
1541
- const styleRel = exportPath(exp, "./style.css");
1542
- const lightRel = exportPath(exp, "./light.css");
1543
- const darkRel = exportPath(exp, "./dark.css");
1544
1541
  const abs = (rel2) => rel2 ? join6(root, rel2.replace(/^\.\//, "")) : undefined;
1542
+ const fileIfExists = (key) => {
1543
+ const rel2 = exportPath(exp, key);
1544
+ const a = abs(rel2);
1545
+ return a && existsSync6(a) ? a : undefined;
1546
+ };
1545
1547
  return {
1546
1548
  name: pkgName,
1547
1549
  root,
1548
- style: abs(styleRel) && existsSync6(abs(styleRel)) ? abs(styleRel) : undefined,
1549
- light: abs(lightRel) && existsSync6(abs(lightRel)) ? abs(lightRel) : undefined,
1550
- dark: abs(darkRel) && existsSync6(abs(darkRel)) ? abs(darkRel) : undefined
1550
+ style: fileIfExists("./style.css"),
1551
+ light: fileIfExists("./light.css"),
1552
+ dark: fileIfExists("./dark.css"),
1553
+ tokens: fileIfExists("./tokens.css")
1551
1554
  };
1552
1555
  }
1556
+ function resolveElcrmCssImport(spec, cwd) {
1557
+ const bare = spec.replace(/^["']|["']$/g, "").trim();
1558
+ const m = bare.match(/^(@elcrm\/[^/]+)\/(.+)$/);
1559
+ if (!m)
1560
+ return null;
1561
+ const pkgName = m[1];
1562
+ const sub = m[2];
1563
+ const root = resolvePkgRoot(pkgName, cwd);
1564
+ if (!root)
1565
+ return null;
1566
+ const pkg = readPkgJson(root);
1567
+ const rel2 = exportPath(pkg?.exports, `./${sub}`);
1568
+ if (!rel2)
1569
+ return null;
1570
+ const abs = join6(root, rel2.replace(/^\.\//, ""));
1571
+ return existsSync6(abs) ? abs : null;
1572
+ }
1573
+ function pruneBrokenElcrmImports(css, cwd) {
1574
+ const removed = [];
1575
+ const next = css.replace(/@import\s+["'](@elcrm\/[^"']+)["']\s*;[ \t]*(?:\r?\n)?/g, (full, spec) => {
1576
+ if (resolveElcrmCssImport(spec, cwd))
1577
+ return full;
1578
+ removed.push(spec);
1579
+ return "";
1580
+ });
1581
+ return { css: next.replace(/\n{3,}/g, `
1582
+
1583
+ `), removed };
1584
+ }
1553
1585
  function addDef(acc, seen, pkg, bucket, name, value) {
1554
1586
  const key = `${bucket}:${name}`;
1555
1587
  if (seen.has(key))
@@ -1732,6 +1764,7 @@ function syncElcrmCss(options) {
1732
1764
  "theme-dark.css": []
1733
1765
  };
1734
1766
  const imports = [];
1767
+ let removedImports = [];
1735
1768
  const fileFor = (bucket) => bucket === "geometry" ? paths.geometry : bucket === "light" ? paths.light : paths.dark;
1736
1769
  const labelFor = (bucket) => bucket === "geometry" ? "theme.css" : bucket === "light" ? "theme-light.css" : "theme-dark.css";
1737
1770
  for (const bucket of ["geometry", "light", "dark"]) {
@@ -1764,14 +1797,16 @@ function syncElcrmCss(options) {
1764
1797
  }
1765
1798
  if (existsSync6(paths.elcrm)) {
1766
1799
  let css = readFileSync12(paths.elcrm, "utf8");
1800
+ const pruned = pruneBrokenElcrmImports(css, options.cwd);
1801
+ css = pruned.css;
1802
+ removedImports = pruned.removed;
1767
1803
  for (const exp of cssExports) {
1768
1804
  const specs = [];
1769
1805
  if (exp.light)
1770
1806
  specs.push(`${exp.name}/light.css`);
1771
1807
  if (exp.dark)
1772
1808
  specs.push(`${exp.name}/dark.css`);
1773
- const tokens = join6(exp.root, "dist/tokens.css");
1774
- if (existsSync6(tokens))
1809
+ if (exp.tokens)
1775
1810
  specs.push(`${exp.name}/tokens.css`);
1776
1811
  for (const spec of specs) {
1777
1812
  const r = ensureImport(css, spec);
@@ -1780,10 +1815,11 @@ function syncElcrmCss(options) {
1780
1815
  imports.push(spec);
1781
1816
  }
1782
1817
  }
1783
- if (imports.length && !options.dry)
1818
+ if ((imports.length || removedImports.length) && !options.dry) {
1784
1819
  writeFileSync4(paths.elcrm, css, "utf8");
1820
+ }
1785
1821
  }
1786
- return { styleDir, added, imports, skippedPkgs };
1822
+ return { styleDir, added, imports, removedImports, skippedPkgs };
1787
1823
  }
1788
1824
 
1789
1825
  // src/commands/test.ts
@@ -2861,7 +2897,10 @@ package.json \u043E\u0431\u043D\u043E\u0432\u043B\u0451\u043D (${changed}).`);
2861
2897
  if (css.imports.length) {
2862
2898
  console.log(` ${c.green("+")} elcrm.css @import: ${css.imports.join(", ")}`);
2863
2899
  }
2864
- if (added === 0 && css.imports.length === 0) {
2900
+ if (css.removedImports.length) {
2901
+ console.log(` ${c.red("\u2212")} elcrm.css \u0431\u0438\u0442\u044B\u0435 @import: ${css.removedImports.join(", ")}`);
2902
+ }
2903
+ if (added === 0 && css.imports.length === 0 && css.removedImports.length === 0) {
2865
2904
  console.log(" \u0422\u043E\u043A\u0435\u043D\u044B \u0443\u0436\u0435 \u043D\u0430 \u043C\u0435\u0441\u0442\u0435.");
2866
2905
  }
2867
2906
  const cleaned = await migrateCssSanitize(cwd, false);
@@ -3409,10 +3448,16 @@ async function cmdCss(parsed) {
3409
3448
  for (const spec of result.imports)
3410
3449
  console.log(` ${c.dim(spec)}`);
3411
3450
  }
3451
+ if (result.removedImports.length) {
3452
+ console.log(` ${c.red("\u2212")} elcrm.css \u0431\u0438\u0442\u044B\u0435 @import:`);
3453
+ for (const spec of result.removedImports) {
3454
+ console.log(` ${c.dim(spec)}`);
3455
+ }
3456
+ }
3412
3457
  if (result.skippedPkgs.length) {
3413
3458
  console.log(` ${c.gray("\u0431\u0435\u0437 CSS-\u0442\u043E\u043A\u0435\u043D\u043E\u0432:")} ${result.skippedPkgs.join(", ")}`);
3414
3459
  }
3415
- if (total === 0 && result.imports.length === 0) {
3460
+ if (total === 0 && result.imports.length === 0 && result.removedImports.length === 0) {
3416
3461
  console.log("\u0412\u0441\u0451 \u0443\u0436\u0435 \u043D\u0430 \u043C\u0435\u0441\u0442\u0435.");
3417
3462
  } else if (dry) {
3418
3463
  console.log("\u0417\u0430\u043F\u0438\u0441\u044C \u043D\u0435 \u0432\u044B\u043F\u043E\u043B\u043D\u044F\u043B\u0430\u0441\u044C (--dry).");
@@ -3572,6 +3617,21 @@ function scan(cwd) {
3572
3617
  fix: "elcrm css"
3573
3618
  });
3574
3619
  }
3620
+ if (styleDir && existsSync14(join14(styleDir, "elcrm.css"))) {
3621
+ const elcrmCss = readFileSync19(join14(styleDir, "elcrm.css"), "utf8");
3622
+ for (const m of elcrmCss.matchAll(/@import\s+["'](@elcrm\/[^"']+)["']/g)) {
3623
+ const spec = m[1];
3624
+ if (!resolveElcrmCssImport(spec, cwd)) {
3625
+ out.push({
3626
+ level: "error",
3627
+ code: "elcrm-import-missing",
3628
+ message: `\u0431\u0438\u0442\u044B\u0439 @import "${spec}" \u2014 \u0444\u0430\u0439\u043B\u0430 \u043D\u0435\u0442 \u0432 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D\u043D\u043E\u043C \u043F\u0430\u043A\u0435\u0442\u0435`,
3629
+ file: relative4(cwd, join14(styleDir, "elcrm.css")),
3630
+ fix: "elcrm css"
3631
+ });
3632
+ }
3633
+ }
3634
+ }
3575
3635
  const depsForm = pkg.dependencies?.["@elcrm/form"] || pkg.devDependencies?.["@elcrm/form"];
3576
3636
  if (depsForm && styleDir) {
3577
3637
  const themeFiles = [
@@ -3859,90 +3919,57 @@ function showVersion() {
3859
3919
  function showHelp() {
3860
3920
  console.log(`elcrm \u2014 CLI \u0434\u043B\u044F \u044D\u043A\u043E\u0441\u0438\u0441\u0442\u0435\u043C\u044B @elcrm/*
3861
3921
 
3862
- \u0418\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0435:
3863
- elcrm <\u043A\u043E\u043C\u0430\u043D\u0434\u0430> [\u0430\u0440\u0433\u0443\u043C\u0435\u043D\u0442\u044B] [\u0444\u043B\u0430\u0433\u0438]
3922
+ \u0415\u0436\u0435\u0434\u043D\u0435\u0432\u043D\u044B\u0439 \u0446\u0438\u043A\u043B:
3923
+ elcrm update --fix --test
3924
+ elcrm css
3925
+ elcrm docs
3926
+ elcrm cursor
3864
3927
 
3865
3928
  \u041A\u043E\u043C\u0430\u043D\u0434\u044B:
3866
3929
  update [--dry] [--core] [--no-install] [--fix] [--test]
3867
- CLI (bun i -g elcrm@latest) + \u0432\u0441\u0435 @elcrm/* \u0432 \u043F\u0440\u043E\u0435\u043A\u0442\u0435 \u0434\u043E latest
3868
- --fix = migrate front; --test = elcrm test
3869
- \u0420\u0435\u043A\u043E\u043C\u0435\u043D\u0434\u0443\u0435\u0442\u0441\u044F: elcrm update --fix --test
3930
+ bun i -g elcrm@latest + @elcrm/* \u2192 install
3931
+ --fix = migrate front + sync CSS (\u0442\u043E\u043A\u0435\u043D\u044B, \u2212\u0431\u0438\u0442\u044B\u0435 @import) + css-sanitize
3932
+ --test = elcrm test
3870
3933
 
3871
- create <name> [--template app|lib|panel] [--no-install]
3872
- \u0421\u043E\u0437\u0434\u0430\u0442\u044C \u043F\u0440\u043E\u0435\u043A\u0442 \u0438\u0437 \u0448\u0430\u0431\u043B\u043E\u043D\u0430 (\u043A\u0430\u043A create-react-app)
3873
- panel \u2192 \u043A\u0430\u0442\u0430\u043B\u043E\u0433\u0438 web/ + api/ + bun run dev
3934
+ css [--dry] [--dir=\u2026]
3935
+ \u0422\u043E\u043A\u0435\u043D\u044B \u2192 theme*.css; elcrm.css: +\u0440\u0430\u0431\u043E\u0447\u0438\u0435 @import, \u2212\u0431\u0438\u0442\u044B\u0435 (\u043D\u0435\u0442 \u0444\u0430\u0439\u043B\u0430 \u0432 \u043F\u0430\u043A\u0435\u0442\u0435)
3936
+ \u0417\u0430\u0442\u0435\u043C css-sanitize (\u043E\u0441\u0438\u0440\u043E\u0442\u0435\u0432\u0448\u0438\u0439 color-mix)
3874
3937
 
3875
- init [--template app|lib|panel] [--force] [--no-install]
3876
- \u0418\u043D\u0438\u0446\u0438\u0430\u043B\u0438\u0437\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0442\u0435\u043A\u0443\u0449\u0438\u0439 \u043A\u0430\u0442\u0430\u043B\u043E\u0433 \u0448\u0430\u0431\u043B\u043E\u043D\u043E\u043C
3938
+ docs [--dry] [--keep] [--dir=\u2026] [--lib]
3939
+ docs/*.elCRM.md (\u0448\u043F\u0430\u0440\u0433\u0430\u043B\u043A\u0438 \u043F\u0430\u043A\u0435\u0442\u043E\u0432)
3877
3940
 
3878
- migrate <name> [--dry]
3879
- migrate --list
3880
- \u041C\u0438\u0433\u0440\u0430\u0446\u0438\u0438: front|ui, form-aliases, form-tokens, components, css-sanitize, size-sml, field-border, modal-create, legacy-hacks, socket-server
3941
+ cursor [--dry] [--keep] [--dir=\u2026] [--lib|-lib]
3942
+ .cursor/rules + .cursor/docs + AGENTS.md
3943
+ --lib: \u0447\u0435\u043A\u043B\u0438\u0441\u0442 \u0430\u0432\u0442\u043E\u0440\u0430 @elcrm/*
3881
3944
 
3882
- audit [--fix] [--dry] [--dir=\u2026]
3883
- \u0423\u0441\u0442\u0430\u0440\u0435\u0432\u0448\u0438\u0439 API + CSS-\u0442\u043E\u043A\u0435\u043D\u044B form (padding-\u0430\u043B\u0438\u0430\u0441\u044B, popup-shadow, border shorthand)
3884
- --fix \u0437\u0430\u043F\u0443\u0441\u043A\u0430\u0435\u0442 migrate front
3945
+ migrate <name> [--dry] | migrate --list
3946
+ front|ui = \u043F\u0430\u043A\u0435\u0442 \u043C\u0438\u0433\u0440\u0430\u0446\u0438\u0439 (aliases, tokens, components, css-sanitize, size, \u2026)
3947
+ \u043F\u043E \u043E\u0434\u043D\u043E\u0439: form-aliases, form-tokens, components, css-sanitize, size-sml,
3948
+ field-border, modal-create, legacy-hacks, socket-server
3949
+
3950
+ audit [--fix] [--dry] [--dir=\u2026]
3951
+ \u0421\u0442\u0430\u0440\u044B\u0435 API, \u0431\u0438\u0442\u044B\u0435 @import, orphan color-mix; --fix = migrate front
3952
+ \u041F\u043E\u0441\u043B\u0435 --fix \u0434\u043B\u044F imports: elcrm css
3885
3953
 
3886
3954
  doctor [--fix]
3887
- \u041F\u0440\u043E\u0432\u0435\u0440\u0438\u0442\u044C \u043F\u0440\u043E\u0435\u043A\u0442 \u0438 \u043F\u0440\u0438 \u043D\u0435\u043E\u0431\u0445\u043E\u0434\u0438\u043C\u043E\u0441\u0442\u0438 \u043F\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u043A \u0441\u0442\u0430\u043D\u0434\u0430\u0440\u0442\u0443
3955
+ \u0421\u0442\u0430\u043D\u0434\u0430\u0440\u0442\u044B; \u043D\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 --fix \u2192 bunx elcrm-server update
3888
3956
 
3889
3957
  test [dir] [--front|--server] [--no-scripts]
3890
- \u041F\u0440\u043E\u0432\u0435\u0440\u043A\u0438: @elcrm/server \u0432 package.json \u2192 server, \u0438\u043D\u0430\u0447\u0435 \u2192 front
3891
- (workspaces \u2014 \u043A\u0430\u0436\u0434\u044B\u0439 \u043F\u0430\u043A\u0435\u0442 \u0441\u0432\u043E\u0438\u043C \u0440\u0435\u0436\u0438\u043C\u043E\u043C)
3958
+ \u0421\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043A\u0438\u0439 \u0430\u043D\u0430\u043B\u0438\u0437 + scripts \u043F\u0440\u043E\u0435\u043A\u0442\u0430
3892
3959
 
3960
+ create <name> [--template app|lib|panel] [--no-install]
3961
+ init [--template app|lib|panel] [--force] [--no-install]
3893
3962
  build [--client] [--url=\u2026] [--name=\u2026] [--dir=\u2026] [--folder=\u2026]
3894
- \u0421\u0431\u043E\u0440\u043A\u0430 \u0438 \u0434\u0435\u043F\u043B\u043E\u0439 (\u0438\u0437 @elcrm/deploy)
3895
-
3896
3963
  postbuild [--dir=./dist]
3897
- \u041F\u043E\u0441\u043B\u0435 vite build lib-\u043F\u0430\u043A\u0435\u0442\u0430: \u0441\u043A\u043B\u0435\u0438\u0442\u044C CSS + \u0441\u043F\u043B\u044E\u0449\u0438\u0442\u044C .d.ts
3898
- (package.json: "build": "vite build && elcrm postbuild")
3899
-
3900
- css [--dry] [--dir=\u2026]
3901
- \u0414\u0435\u0444\u043E\u043B\u0442\u043D\u044B\u0435 \u0442\u043E\u043A\u0435\u043D\u044B @elcrm/* \u2192 src/style/theme.css, theme-light/dark, elcrm.css
3902
- \u0423\u0436\u0435 \u0437\u0430\u0434\u0430\u043D\u043D\u044B\u0435 \u043F\u0435\u0440\u0435\u043C\u0435\u043D\u043D\u044B\u0435 \u043D\u0435 \u0437\u0430\u0442\u0438\u0440\u0430\u044E\u0442\u0441\u044F, \u0442\u043E\u043B\u044C\u043A\u043E \u043D\u0435\u0434\u043E\u0441\u0442\u0430\u044E\u0449\u0438\u0435 (\u0433\u0440\u0443\u043F\u043F\u044B \u0447\u0435\u0440\u0435\u0437 \u043F\u0443\u0441\u0442\u0443\u044E \u0441\u0442\u0440\u043E\u043A\u0443)
3903
-
3904
- docs [--dry] [--keep] [--dir=\u2026] [--lib]
3905
- docs/*.elCRM.md \u043F\u043E \u043F\u0430\u043A\u0435\u0442\u0430\u043C (cli, api, alert, button, modal, notice, \u2026)
3906
- \u0441\u0435\u0440\u0432\u0435\u0440-only \u2192 SERVER, CLI, API, SOCKET; --lib \u0438\u043B\u0438 \u043F\u0430\u043A\u0435\u0442 @elcrm/* \u2192 \u0432\u0441\u0435 \u0444\u0430\u0439\u043B\u044B
3907
-
3908
- cursor [--dry] [--keep] [--dir=\u2026] [--lib|-lib]
3909
- .cursor/rules + .cursor/docs + AGENTS.md
3910
- --lib: \u0447\u0435\u043A\u043B\u0438\u0441\u0442 \u0430\u0432\u0442\u043E\u0440\u0430 \u0431\u0438\u0431\u043B\u0438\u043E\u0442\u0435\u043A\u0438 (\u043F\u043E\u0441\u043B\u0435 \u043F\u0440\u0430\u0432\u043E\u043A src \u043E\u0431\u043D\u043E\u0432\u0438\u0442\u044C CLI-\u0448\u043F\u0430\u0440\u0433\u0430\u043B\u043A\u0438)
3911
-
3912
3964
  uuid
3913
- \u0421\u0433\u0435\u043D\u0435\u0440\u0438\u0440\u043E\u0432\u0430\u0442\u044C UUID
3914
-
3915
- help
3916
- \u042D\u0442\u0430 \u0441\u043F\u0440\u0430\u0432\u043A\u0430
3917
3965
 
3918
- \u0424\u043B\u0430\u0433\u0438:
3919
- -v, --version \u0412\u0435\u0440\u0441\u0438\u044F CLI
3920
- -h, --help \u0421\u043F\u0440\u0430\u0432\u043A\u0430
3966
+ \u0424\u043B\u0430\u0433\u0438: -v/--version, -h/--help
3921
3967
 
3922
3968
  \u041F\u0440\u0438\u043C\u0435\u0440\u044B:
3923
- elcrm -v
3924
- elcrm update
3925
- elcrm update --dry
3926
- elcrm update --fix --test
3927
- elcrm migrate form-aliases --dry
3928
- elcrm migrate form-tokens --dry
3929
- elcrm create my-app --template app
3930
- elcrm init --template panel
3931
- elcrm init --template lib
3932
- elcrm migrate front --dry
3933
- elcrm migrate size-sml
3969
+ elcrm update --fix --test && elcrm css && elcrm docs && elcrm cursor
3970
+ elcrm css # ENOENT @elcrm/\u2026/light.css \u2192 \u0441\u043D\u0438\u043C\u0435\u0442 \u0431\u0438\u0442\u044B\u0439 import
3934
3971
  elcrm audit
3935
- elcrm audit --fix
3936
- elcrm doctor --fix
3937
- elcrm test
3938
- elcrm test --server
3939
- elcrm build --client --url=https://example.com/deploy
3940
- elcrm postbuild
3941
- elcrm css
3942
- elcrm css --dry
3943
- elcrm docs
3944
- elcrm cursor
3945
- elcrm cursor --lib
3972
+ elcrm migrate front --dry
3946
3973
  `);
3947
3974
  }
3948
3975
  async function main() {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "elcrm",
3
- "version": "1.1.4",
4
- "description": "CLI @elcrm/*: update, create, migrate front/components/css-sanitize, audit, doctor, test, build, css",
3
+ "version": "1.1.5",
4
+ "description": "CLI @elcrm/*: update --fix --test, css (prune imports), docs, cursor, migrate, audit",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "author": "MaSkal <dev@elcrm.online>",
@@ -1,8 +1,12 @@
1
- <!-- Сгенерировано `elcrm docs`. Пакет: elcrm (CLI). -->
1
+ <!-- Источник: elCRM.cli/templates/elcrm-docs/CLI.elCRM.md. Обновить: elcrm docs. -->
2
2
 
3
3
  # `elcrm` CLI
4
4
 
5
- Глобально: `bun i -g elcrm`. В приложении пакеты и CLI одной командой:
5
+ Глобально: `bun i -g elcrm` (нужна **свежая** версия: `elcrm -v`).
6
+
7
+ ## Ежедневный цикл (запомнить эти 4)
8
+
9
+ После смены `@elcrm/*` или если «что-то сломалось» в UI/CSS:
6
10
 
7
11
  ```bash
8
12
  elcrm update --fix --test
@@ -11,17 +15,102 @@ elcrm docs
11
15
  elcrm cursor
12
16
  ```
13
17
 
14
- | Команда | Зачем |
18
+ | # | Команда | Что делает |
19
+ | --- | --- | --- |
20
+ | 1 | `elcrm update --fix --test` | Обновляет глобальный `elcrm` + все `@elcrm/*` в `package.json` → install → **migrate front** (API/токены/css-sanitize) → внутри `--fix` ещё раз **sync CSS** → `elcrm test` |
21
+ | 2 | `elcrm css` | Недостающие CSS-токены → `theme.css` / `theme-light` / `theme-dark`. В `elcrm.css`: **добавляет** рабочие `@import`, **удаляет битые** (нет export/файла в установленном пакете). Затем css-sanitize |
22
+ | 3 | `elcrm docs` | Перезаписывает `docs/*.elCRM.md` (шпаргалки пакетов) |
23
+ | 4 | `elcrm cursor` | `.cursor/rules` + `.cursor/docs` + `AGENTS.md` для агента |
24
+
25
+ Не чинит само по себе: ручные баги в компонентах, сервер без `elcrm-server`, секреты. Чинит: устаревшие API после миграций, битые `@import` в `elcrm.css`, осиротевший `color-mix`, недостающие токены.
26
+
27
+ ---
28
+
29
+ ## Все команды
30
+
31
+ ### `update` — зависимости
32
+
33
+ ```bash
34
+ elcrm update # latest @elcrm/* + bun i -g elcrm@latest
35
+ elcrm update --dry # только отчёт
36
+ elcrm update --core # версии как в @elcrm/core
37
+ elcrm update --no-install # только package.json
38
+ elcrm update --fix # + migrate front + sync CSS (+ prune битых @import)
39
+ elcrm update --test # + elcrm test (обычно вместе: --fix --test)
40
+ ```
41
+
42
+ ### `css` — стили приложения
43
+
44
+ ```bash
45
+ elcrm css # токены + починка elcrm.css
46
+ elcrm css --dry
47
+ elcrm css --dir=./web # panel: web/
48
+ ```
49
+
50
+ Почему Vite ругался на `@elcrm/search/light.css`: в `elcrm.css` остался `@import`, а в **установленном** `@elcrm/search@0.1.4` нет export `./light.css`. Раньше `css` только добавлял imports — теперь **снимает** такие строки. Лечение: `elcrm css` (или `update --fix`).
51
+
52
+ ### `docs` / `cursor` — шпаргалки
53
+
54
+ ```bash
55
+ elcrm docs # docs/*.elCRM.md
56
+ elcrm docs --dry | --keep | --lib | --dir=…
57
+ elcrm cursor # .cursor/rules + .cursor/docs + AGENTS.md
58
+ elcrm cursor --lib # + чеклист автора @elcrm/* (правило elcrm-lib)
59
+ ```
60
+
61
+ ### `migrate` — точечные правки кода
62
+
63
+ ```bash
64
+ elcrm migrate --list
65
+ elcrm migrate front # пакет (то же, что update/audit/doctor --fix):
66
+ # form-aliases → form-tokens → components →
67
+ # css-sanitize → size-sml → field-border →
68
+ # modal-create → socket-server
69
+ elcrm migrate css-sanitize # осиротевшие in srgb / transparent);
70
+ elcrm migrate components # Block/Row → Stack, --page-* → --shell-*
71
+ elcrm migrate form-tokens
72
+ elcrm migrate form-aliases
73
+ elcrm migrate size-sml # size sm|md → s|m|l
74
+ elcrm migrate field-border
75
+ elcrm migrate modal-create # Modal.Add → Create
76
+ elcrm migrate legacy-hacks # только по имени, не в front
77
+ elcrm migrate socket-server
78
+ ```
79
+
80
+ Флаг у всех: `--dry`.
81
+
82
+ ### `audit` / `doctor` / `test` — проверки
83
+
84
+ ```bash
85
+ elcrm audit # старые API, битые @import, orphan color-mix, …
86
+ elcrm audit --fix # = migrate front (+ css не вызывает — после: elcrm css)
87
+ elcrm doctor # стандарты проекта
88
+ elcrm doctor --fix # type/engines + migrate front
89
+ elcrm test # статический анализ + scripts проекта
90
+ elcrm test --front|--server|--no-scripts
91
+ ```
92
+
93
+ ### Прочее
94
+
95
+ ```bash
96
+ elcrm create <name> [--template app|lib|panel] [--no-install]
97
+ elcrm init [--template …] [--force] [--no-install]
98
+ elcrm build --client [--url=…] [--name=…] [--dir=…] [--folder=…]
99
+ elcrm postbuild [--dir=./dist] # lib: склейка CSS после vite build
100
+ elcrm uuid
101
+ elcrm -v / --help
102
+ ```
103
+
104
+ ---
105
+
106
+ ## Когда что запускать
107
+
108
+ | Ситуация | Команды |
15
109
  | --- | --- |
16
- | `update [--dry] [--core] [--fix] [--test]` | `bun i -g elcrm@latest` + `@elcrm/*` в проекте; `--fix` = migrate front + css; `--test` = elcrm test |
17
- | `create` / `init` | шаблоны `app` \| `lib` \| `panel` |
18
- | `migrate <name> [--dry]` | `front` (пакет), `form-aliases`, `form-tokens`, `components`, `size-sml`, `field-border`, `modal-create`, `legacy-hacks`, `socket-server` |
19
- | `audit [--fix]` | старые API; `--fix` = migrate front |
20
- | `doctor [--fix]` | стандарты; сервер --fix `bunx elcrm-server update` |
21
- | `test [--front\|--server] [--no-scripts]` | статический анализ + scripts |
22
- | `css [--dry]` | недостающие токены theme*.css |
23
- | `docs` / `cursor` | шпаргалки и правила агента |
24
- | `cursor --lib` / `-lib` | правила автора `@elcrm/*` lib (чеклист после правок src) |
25
- | `build` / `postbuild` / `uuid` | деплой клиента/api; склейка CSS lib |
26
-
27
- Не выдумывать флаги — `elcrm --help` и `COMMANDS.md`.
110
+ | Обновили пакеты / «после elcrm update всё красное» | полный цикл из 4 команд сверху |
111
+ | Vite: `ENOENT @elcrm/…/light.css` | `elcrm css` при необходимости `elcrm audit` |
112
+ | Битый theme (`in srgb` без свойства) | `elcrm migrate css-sanitize` или `update --fix` |
113
+ | Агент врёт API | `elcrm docs && elcrm cursor` |
114
+ | Автор правит `@elcrm/*` src | чеклист: `elcrm cursor --lib`; шпаргалки править в **elCRM.cli** |
115
+
116
+ Не выдумывать флаги — `elcrm --help` и `COMMANDS.md` в репо CLI.