@donotdev/cli 0.0.9 → 0.0.12

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 (33) hide show
  1. package/dependencies-matrix.json +24 -7
  2. package/dist/bin/commands/build.js +2 -2
  3. package/dist/bin/commands/bump.js +586 -95
  4. package/dist/bin/commands/cacheout.js +2 -2
  5. package/dist/bin/commands/create-app.js +23 -3
  6. package/dist/bin/commands/create-project.js +23 -3
  7. package/dist/bin/commands/deploy.js +3 -3
  8. package/dist/bin/commands/dev.js +2 -2
  9. package/dist/bin/commands/emu.js +2 -2
  10. package/dist/bin/commands/format.js +2 -2
  11. package/dist/bin/commands/lint.js +2 -2
  12. package/dist/bin/commands/preview.js +2 -2
  13. package/dist/bin/commands/sync-secrets.js +2 -2
  14. package/dist/index.js +23 -3
  15. package/package.json +2 -2
  16. package/templates/app-next/src/pages/HomePage.tsx.example +1 -1
  17. package/templates/root-consumer/.claude/agents/architect.md.example +313 -0
  18. package/templates/root-consumer/.claude/agents/builder.md.example +329 -0
  19. package/templates/root-consumer/.claude/agents/coder.md.example +87 -0
  20. package/templates/root-consumer/.claude/agents/extractor.md.example +235 -0
  21. package/templates/root-consumer/.claude/agents/polisher.md.example +359 -0
  22. package/templates/root-consumer/.claude/agents/prompt-engineer.md.example +85 -0
  23. package/templates/root-consumer/.claude/commands/brainstorm.md.example +133 -0
  24. package/templates/root-consumer/.claude/commands/build.md.example +109 -0
  25. package/templates/root-consumer/.claude/commands/design.md.example +136 -0
  26. package/templates/root-consumer/.claude/commands/polish.md.example +145 -0
  27. package/templates/root-consumer/.cursor/mcp.json.example +8 -0
  28. package/templates/root-consumer/.mcp.json.example +8 -0
  29. package/templates/root-consumer/CLAUDE.md.example +146 -0
  30. package/templates/root-consumer/guides/dndev/AGENT_START_HERE.md.example +15 -12
  31. package/templates/root-consumer/guides/dndev/COMPONENT_API.md.example +195 -0
  32. package/templates/root-consumer/guides/dndev/INDEX.md.example +3 -1
  33. package/templates/root-consumer/guides/dndev/SETUP_CRUD.md.example +157 -1
@@ -163,7 +163,7 @@ var require_picocolors = __commonJS({
163
163
  }
164
164
  });
165
165
 
166
- // node_modules/.bun/@clack+core@0.5.0/node_modules/@clack/core/dist/index.mjs
166
+ // node_modules/.bun/@clack+prompts@0.11.0/node_modules/@clack/prompts/node_modules/@clack/core/dist/index.mjs
167
167
  import { stdin as j, stdout as M } from "node:process";
168
168
  import O from "node:readline";
169
169
  import { Writable as X } from "node:stream";
@@ -255,9 +255,9 @@ function m(e2, u2) {
255
255
  const t = e2;
256
256
  t.isTTY && t.setRawMode(u2);
257
257
  }
258
- var import_sisteransi, uD, W, tD, eD, FD, sD, w, N, I, R, r, iD, CD, ED, d, oD, y, V, nD, G, _, z, K, aD, k, hD, lD, xD, B, AD, S, gD, vD, h, x, dD, A;
258
+ var import_sisteransi, uD, W, tD, eD, FD, sD, w, N, I, R, r, iD, CD, ED, d, oD, y, V, nD, G, _, z, K, aD, k, hD, lD, xD, B, AD, S, gD, vD, h, x, dD, A, OD, PD, J, LD;
259
259
  var init_dist = __esm({
260
- "node_modules/.bun/@clack+core@0.5.0/node_modules/@clack/core/dist/index.mjs"() {
260
+ "node_modules/.bun/@clack+prompts@0.11.0/node_modules/@clack/prompts/node_modules/@clack/core/dist/index.mjs"() {
261
261
  init_utils();
262
262
  import_sisteransi = __toESM(require_src(), 1);
263
263
  uD = DD();
@@ -492,6 +492,32 @@ var init_dist = __esm({
492
492
  }
493
493
  };
494
494
  A = /* @__PURE__ */ new WeakMap();
495
+ OD = Object.defineProperty;
496
+ PD = (e2, u2, t) => u2 in e2 ? OD(e2, u2, { enumerable: true, configurable: true, writable: true, value: t }) : e2[u2] = t;
497
+ J = (e2, u2, t) => (PD(e2, typeof u2 != "symbol" ? u2 + "" : u2, t), t);
498
+ LD = class extends x {
499
+ constructor(u2) {
500
+ super(u2, false), J(this, "options"), J(this, "cursor", 0), this.options = u2.options, this.cursor = this.options.findIndex(({ value: t }) => t === u2.initialValue), this.cursor === -1 && (this.cursor = 0), this.changeValue(), this.on("cursor", (t) => {
501
+ switch (t) {
502
+ case "left":
503
+ case "up":
504
+ this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
505
+ break;
506
+ case "down":
507
+ case "right":
508
+ this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
509
+ break;
510
+ }
511
+ this.changeValue();
512
+ });
513
+ }
514
+ get _value() {
515
+ return this.options[this.cursor];
516
+ }
517
+ changeValue() {
518
+ this.value = this._value.value;
519
+ }
520
+ };
495
521
  }
496
522
  });
497
523
 
@@ -501,7 +527,7 @@ import y2 from "node:process";
501
527
  function ce() {
502
528
  return y2.platform !== "win32" ? y2.env.TERM !== "linux" : !!y2.env.CI || !!y2.env.WT_SESSION || !!y2.env.TERMINUS_SUBLIME || y2.env.ConEmuTask === "{cmd::Cmder}" || y2.env.TERM_PROGRAM === "Terminus-Sublime" || y2.env.TERM_PROGRAM === "vscode" || y2.env.TERM === "xterm-256color" || y2.env.TERM === "alacritty" || y2.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
503
529
  }
504
- var import_picocolors, import_sisteransi2, V2, u, le, L2, W2, C, ue, o, d2, k2, P2, A2, T, F, $e, _2, me, de, pe, q, D, U, K2, b2, ye, xe, Ie, Se, M2, J;
530
+ var import_picocolors, import_sisteransi2, V2, u, le, L2, W2, C, ue, o, d2, k2, P2, A2, T, F, $e, _2, me, de, pe, q, D, U, K2, b2, G2, ye, ve, xe, Ie, Se, M2, J2;
505
531
  var init_dist2 = __esm({
506
532
  "node_modules/.bun/@clack+prompts@0.11.0/node_modules/@clack/prompts/dist/index.mjs"() {
507
533
  init_utils();
@@ -545,6 +571,16 @@ var init_dist2 = __esm({
545
571
  return import_picocolors.default.green(C);
546
572
  }
547
573
  };
574
+ G2 = (t) => {
575
+ const { cursor: n, options: r2, style: i } = t, s = t.maxItems ?? Number.POSITIVE_INFINITY, c = Math.max(process.stdout.rows - 4, 0), a = Math.min(c, Math.max(s, 5));
576
+ let l2 = 0;
577
+ n >= l2 + a - 3 ? l2 = Math.max(Math.min(n - a + 3, r2.length - a), 0) : n < l2 + 2 && (l2 = Math.max(n - 2, 0));
578
+ const $2 = a < r2.length && l2 > 0, g = a < r2.length && l2 + a < r2.length;
579
+ return r2.slice(l2, l2 + a).map((p2, v, f) => {
580
+ const j2 = v === 0 && $2, E = v === f.length - 1 && g;
581
+ return j2 || E ? import_picocolors.default.dim("...") : i(p2, v + l2 === n);
582
+ });
583
+ };
548
584
  ye = (t) => {
549
585
  const n = t.active ?? "Yes", r2 = t.inactive ?? "No";
550
586
  return new dD({ active: n, inactive: r2, initialValue: t.initialValue ?? true, render() {
@@ -560,6 +596,38 @@ ${import_picocolors.default.gray(o)}`;
560
596
  default:
561
597
  return `${i}${import_picocolors.default.cyan(o)} ${this.value ? `${import_picocolors.default.green(k2)} ${n}` : `${import_picocolors.default.dim(P2)} ${import_picocolors.default.dim(n)}`} ${import_picocolors.default.dim("/")} ${this.value ? `${import_picocolors.default.dim(P2)} ${import_picocolors.default.dim(r2)}` : `${import_picocolors.default.green(k2)} ${r2}`}
562
598
  ${import_picocolors.default.cyan(d2)}
599
+ `;
600
+ }
601
+ } }).prompt();
602
+ };
603
+ ve = (t) => {
604
+ const n = (r2, i) => {
605
+ const s = r2.label ?? String(r2.value);
606
+ switch (i) {
607
+ case "selected":
608
+ return `${import_picocolors.default.dim(s)}`;
609
+ case "active":
610
+ return `${import_picocolors.default.green(k2)} ${s} ${r2.hint ? import_picocolors.default.dim(`(${r2.hint})`) : ""}`;
611
+ case "cancelled":
612
+ return `${import_picocolors.default.strikethrough(import_picocolors.default.dim(s))}`;
613
+ default:
614
+ return `${import_picocolors.default.dim(P2)} ${import_picocolors.default.dim(s)}`;
615
+ }
616
+ };
617
+ return new LD({ options: t.options, initialValue: t.initialValue, render() {
618
+ const r2 = `${import_picocolors.default.gray(o)}
619
+ ${b2(this.state)} ${t.message}
620
+ `;
621
+ switch (this.state) {
622
+ case "submit":
623
+ return `${r2}${import_picocolors.default.gray(o)} ${n(this.options[this.cursor], "selected")}`;
624
+ case "cancel":
625
+ return `${r2}${import_picocolors.default.gray(o)} ${n(this.options[this.cursor], "cancelled")}
626
+ ${import_picocolors.default.gray(o)}`;
627
+ default:
628
+ return `${r2}${import_picocolors.default.cyan(o)} ${G2({ cursor: this.cursor, options: this.options, maxItems: t.maxItems, style: (i, s) => n(i, s ? "active" : "inactive") }).join(`
629
+ ${import_picocolors.default.cyan(o)} `)}
630
+ ${import_picocolors.default.cyan(d2)}
563
631
  `;
564
632
  }
565
633
  } }).prompt();
@@ -602,7 +670,7 @@ ${import_picocolors.default.gray(d2)} ${t}
602
670
  }, error: (t) => {
603
671
  M2.message(t, { symbol: import_picocolors.default.red(K2) });
604
672
  } };
605
- J = `${import_picocolors.default.gray(o)} `;
673
+ J2 = `${import_picocolors.default.gray(o)} `;
606
674
  }
607
675
  });
608
676
 
@@ -2651,7 +2719,7 @@ var require_scan = __commonJS({
2651
2719
  }
2652
2720
  let base = str;
2653
2721
  let prefix = "";
2654
- let glob = "";
2722
+ let glob2 = "";
2655
2723
  if (start > 0) {
2656
2724
  prefix = str.slice(0, start);
2657
2725
  str = str.slice(start);
@@ -2659,10 +2727,10 @@ var require_scan = __commonJS({
2659
2727
  }
2660
2728
  if (base && isGlob === true && lastIndex > 0) {
2661
2729
  base = str.slice(0, lastIndex);
2662
- glob = str.slice(lastIndex);
2730
+ glob2 = str.slice(lastIndex);
2663
2731
  } else if (isGlob === true) {
2664
2732
  base = "";
2665
- glob = str;
2733
+ glob2 = str;
2666
2734
  } else {
2667
2735
  base = str;
2668
2736
  }
@@ -2672,7 +2740,7 @@ var require_scan = __commonJS({
2672
2740
  }
2673
2741
  }
2674
2742
  if (opts.unescape === true) {
2675
- if (glob) glob = utils.removeBackslashes(glob);
2743
+ if (glob2) glob2 = utils.removeBackslashes(glob2);
2676
2744
  if (base && backslashes === true) {
2677
2745
  base = utils.removeBackslashes(base);
2678
2746
  }
@@ -2682,7 +2750,7 @@ var require_scan = __commonJS({
2682
2750
  input,
2683
2751
  start,
2684
2752
  base,
2685
- glob,
2753
+ glob: glob2,
2686
2754
  isBrace,
2687
2755
  isBracket,
2688
2756
  isGlob,
@@ -3522,9 +3590,9 @@ var require_picomatch = __commonJS({
3522
3590
  var utils = require_utils2();
3523
3591
  var constants2 = require_constants2();
3524
3592
  var isObject = (val) => val && typeof val === "object" && !Array.isArray(val);
3525
- var picomatch = (glob, options, returnState = false) => {
3526
- if (Array.isArray(glob)) {
3527
- const fns = glob.map((input) => picomatch(input, options, returnState));
3593
+ var picomatch = (glob2, options, returnState = false) => {
3594
+ if (Array.isArray(glob2)) {
3595
+ const fns = glob2.map((input) => picomatch(input, options, returnState));
3528
3596
  const arrayMatcher = (str) => {
3529
3597
  for (const isMatch of fns) {
3530
3598
  const state2 = isMatch(str);
@@ -3534,13 +3602,13 @@ var require_picomatch = __commonJS({
3534
3602
  };
3535
3603
  return arrayMatcher;
3536
3604
  }
3537
- const isState = isObject(glob) && glob.tokens && glob.input;
3538
- if (glob === "" || typeof glob !== "string" && !isState) {
3605
+ const isState = isObject(glob2) && glob2.tokens && glob2.input;
3606
+ if (glob2 === "" || typeof glob2 !== "string" && !isState) {
3539
3607
  throw new TypeError("Expected pattern to be a non-empty string");
3540
3608
  }
3541
3609
  const opts = options || {};
3542
3610
  const posix = utils.isWindows(options);
3543
- const regex = isState ? picomatch.compileRe(glob, options) : picomatch.makeRe(glob, options, false, true);
3611
+ const regex = isState ? picomatch.compileRe(glob2, options) : picomatch.makeRe(glob2, options, false, true);
3544
3612
  const state = regex.state;
3545
3613
  delete regex.state;
3546
3614
  let isIgnored = () => false;
@@ -3549,8 +3617,8 @@ var require_picomatch = __commonJS({
3549
3617
  isIgnored = picomatch(opts.ignore, ignoreOpts, returnState);
3550
3618
  }
3551
3619
  const matcher = (input, returnObject = false) => {
3552
- const { isMatch, match, output } = picomatch.test(input, regex, options, { glob, posix });
3553
- const result = { glob, state, regex, posix, input, output, match, isMatch };
3620
+ const { isMatch, match, output } = picomatch.test(input, regex, options, { glob: glob2, posix });
3621
+ const result = { glob: glob2, state, regex, posix, input, output, match, isMatch };
3554
3622
  if (typeof opts.onResult === "function") {
3555
3623
  opts.onResult(result);
3556
3624
  }
@@ -3575,7 +3643,7 @@ var require_picomatch = __commonJS({
3575
3643
  }
3576
3644
  return matcher;
3577
3645
  };
3578
- picomatch.test = (input, regex, options, { glob, posix } = {}) => {
3646
+ picomatch.test = (input, regex, options, { glob: glob2, posix } = {}) => {
3579
3647
  if (typeof input !== "string") {
3580
3648
  throw new TypeError("Expected input to be a string");
3581
3649
  }
@@ -3584,11 +3652,11 @@ var require_picomatch = __commonJS({
3584
3652
  }
3585
3653
  const opts = options || {};
3586
3654
  const format = opts.format || (posix ? utils.toPosixSlashes : null);
3587
- let match = input === glob;
3655
+ let match = input === glob2;
3588
3656
  let output = match && format ? format(input) : input;
3589
3657
  if (match === false) {
3590
3658
  output = format ? format(input) : input;
3591
- match = output === glob;
3659
+ match = output === glob2;
3592
3660
  }
3593
3661
  if (match === false || opts.capture === true) {
3594
3662
  if (opts.matchBase === true || opts.basename === true) {
@@ -3599,8 +3667,8 @@ var require_picomatch = __commonJS({
3599
3667
  }
3600
3668
  return { isMatch: Boolean(match), match, output };
3601
3669
  };
3602
- picomatch.matchBase = (input, glob, options, posix = utils.isWindows(options)) => {
3603
- const regex = glob instanceof RegExp ? glob : picomatch.makeRe(glob, options);
3670
+ picomatch.matchBase = (input, glob2, options, posix = utils.isWindows(options)) => {
3671
+ const regex = glob2 instanceof RegExp ? glob2 : picomatch.makeRe(glob2, options);
3604
3672
  return regex.test(path.basename(input));
3605
3673
  };
3606
3674
  picomatch.isMatch = (str, patterns, options) => picomatch(patterns, options)(str);
@@ -3789,9 +3857,9 @@ var require_micromatch = __commonJS({
3789
3857
  }
3790
3858
  return [].concat(patterns).every((p2) => picomatch(p2, options)(str));
3791
3859
  };
3792
- micromatch.capture = (glob, input, options) => {
3860
+ micromatch.capture = (glob2, input, options) => {
3793
3861
  let posix = utils.isWindows(options);
3794
- let regex = picomatch.makeRe(String(glob), { ...options, capture: true });
3862
+ let regex = picomatch.makeRe(String(glob2), { ...options, capture: true });
3795
3863
  let match = regex.exec(posix ? utils.toPosixSlashes(input) : input);
3796
3864
  if (match) {
3797
3865
  return match.slice(1).map((v) => v === void 0 ? "" : v);
@@ -4280,7 +4348,7 @@ var require_async = __commonJS({
4280
4348
  init_utils();
4281
4349
  Object.defineProperty(exports, "__esModule", { value: true });
4282
4350
  exports.read = void 0;
4283
- function read(path, settings, callback) {
4351
+ function read2(path, settings, callback) {
4284
4352
  settings.fs.lstat(path, (lstatError, lstat) => {
4285
4353
  if (lstatError !== null) {
4286
4354
  callFailureCallback(callback, lstatError);
@@ -4306,7 +4374,7 @@ var require_async = __commonJS({
4306
4374
  });
4307
4375
  });
4308
4376
  }
4309
- exports.read = read;
4377
+ exports.read = read2;
4310
4378
  function callFailureCallback(callback, error2) {
4311
4379
  callback(error2);
4312
4380
  }
@@ -4323,7 +4391,7 @@ var require_sync = __commonJS({
4323
4391
  init_utils();
4324
4392
  Object.defineProperty(exports, "__esModule", { value: true });
4325
4393
  exports.read = void 0;
4326
- function read(path, settings) {
4394
+ function read2(path, settings) {
4327
4395
  const lstat = settings.fs.lstatSync(path);
4328
4396
  if (!lstat.isSymbolicLink() || !settings.followSymbolicLink) {
4329
4397
  return lstat;
@@ -4341,7 +4409,7 @@ var require_sync = __commonJS({
4341
4409
  throw error2;
4342
4410
  }
4343
4411
  }
4344
- exports.read = read;
4412
+ exports.read = read2;
4345
4413
  }
4346
4414
  });
4347
4415
 
@@ -4575,14 +4643,14 @@ var require_async2 = __commonJS({
4575
4643
  var constants_1 = require_constants3();
4576
4644
  var utils = require_utils4();
4577
4645
  var common = require_common();
4578
- function read(directory, settings, callback) {
4646
+ function read2(directory, settings, callback) {
4579
4647
  if (!settings.stats && constants_1.IS_SUPPORT_READDIR_WITH_FILE_TYPES) {
4580
4648
  readdirWithFileTypes(directory, settings, callback);
4581
4649
  return;
4582
4650
  }
4583
4651
  readdir(directory, settings, callback);
4584
4652
  }
4585
- exports.read = read;
4653
+ exports.read = read2;
4586
4654
  function readdirWithFileTypes(directory, settings, callback) {
4587
4655
  settings.fs.readdir(directory, { withFileTypes: true }, (readdirError, dirents) => {
4588
4656
  if (readdirError !== null) {
@@ -4685,13 +4753,13 @@ var require_sync2 = __commonJS({
4685
4753
  var constants_1 = require_constants3();
4686
4754
  var utils = require_utils4();
4687
4755
  var common = require_common();
4688
- function read(directory, settings) {
4756
+ function read2(directory, settings) {
4689
4757
  if (!settings.stats && constants_1.IS_SUPPORT_READDIR_WITH_FILE_TYPES) {
4690
4758
  return readdirWithFileTypes(directory, settings);
4691
4759
  }
4692
4760
  return readdir(directory, settings);
4693
4761
  }
4694
- exports.read = read;
4762
+ exports.read = read2;
4695
4763
  function readdirWithFileTypes(directory, settings) {
4696
4764
  const dirents = settings.fs.readdirSync(directory, { withFileTypes: true });
4697
4765
  return dirents.map((dirent) => {
@@ -7496,6 +7564,119 @@ var init_PathResolver = __esm({
7496
7564
  }
7497
7565
  });
7498
7566
 
7567
+ // packages/tooling/src/utils/errors.ts
7568
+ var DoNotDevError;
7569
+ var init_errors = __esm({
7570
+ "packages/tooling/src/utils/errors.ts"() {
7571
+ "use strict";
7572
+ init_utils();
7573
+ DoNotDevError = class _DoNotDevError extends Error {
7574
+ /** The error code categorizing this error */
7575
+ code;
7576
+ /** Original error if this is wrapping another error */
7577
+ originalError;
7578
+ /** Additional context for the error */
7579
+ context;
7580
+ /** Whether this error should be displayed to the user */
7581
+ displayable;
7582
+ /**
7583
+ * Creates a new DoNotDev error
7584
+ *
7585
+ * @param {string} message - Error message
7586
+ * @param {DoNotDevErrorCode} code - Error code
7587
+ * @param {object} [options] - Additional error options
7588
+ * @param {Error} [options.originalError] - Original error if wrapping
7589
+ * @param {Record<string, any>} [options.context] - Additional context data
7590
+ * @param {boolean} [options.displayable=true] - Whether this error should be displayed to the user
7591
+ */
7592
+ constructor(message, code = "unknown-error", options) {
7593
+ super(message);
7594
+ this.name = "DoNotDevError";
7595
+ this.code = code;
7596
+ this.originalError = options?.originalError;
7597
+ this.context = options?.context;
7598
+ this.displayable = options?.displayable !== false;
7599
+ Object.setPrototypeOf(this, _DoNotDevError.prototype);
7600
+ if (Error.captureStackTrace) {
7601
+ Error.captureStackTrace(this, _DoNotDevError);
7602
+ }
7603
+ }
7604
+ /**
7605
+ * Formats the error for logging or display
7606
+ *
7607
+ * @returns {string} Formatted error message with code
7608
+ */
7609
+ format() {
7610
+ return `[${this.code}] ${this.message}`;
7611
+ }
7612
+ /**
7613
+ * Creates a wrapped error from another error
7614
+ *
7615
+ * @param {Error} error - Original error to wrap
7616
+ * @param {string} [context] - Additional context for the error
7617
+ * @param {DoNotDevErrorCode} [code='unknown-error'] - Error code
7618
+ * @param {object} [options] - Additional error options
7619
+ * @param {Record<string, any>} [options.context] - Additional context data
7620
+ * @param {boolean} [options.displayable=true] - Whether this error should be displayed to the user
7621
+ * @returns {DoNotDevError} New DoNotDev error wrapping the original
7622
+ */
7623
+ static from(error2, context, code = "unknown-error", options) {
7624
+ if (!(error2 instanceof Error)) {
7625
+ return new _DoNotDevError(
7626
+ `Unknown error: ${String(error2)}`,
7627
+ code,
7628
+ options
7629
+ );
7630
+ }
7631
+ if (error2 instanceof _DoNotDevError) {
7632
+ if (!context) {
7633
+ return error2;
7634
+ }
7635
+ return new _DoNotDevError(`${context}: ${error2.message}`, error2.code, {
7636
+ originalError: error2.originalError || error2,
7637
+ context: { ...error2.context, ...options?.context || {} },
7638
+ displayable: options?.displayable ?? error2.displayable
7639
+ });
7640
+ }
7641
+ const message = context ? `${context}: ${error2.message}` : error2.message;
7642
+ return new _DoNotDevError(message, code, {
7643
+ originalError: error2,
7644
+ context: options?.context,
7645
+ displayable: options?.displayable
7646
+ });
7647
+ }
7648
+ /**
7649
+ * Maps common error types to DoNotDevErrorCode
7650
+ *
7651
+ * @param {Error} error - Error to analyze
7652
+ * @returns {DoNotDevErrorCode} Mapped error code
7653
+ */
7654
+ static getErrorCodeFromError(error2) {
7655
+ if (error2 instanceof _DoNotDevError) {
7656
+ return error2.code;
7657
+ }
7658
+ const message = error2.message.toLowerCase();
7659
+ if (error2.name === "ValidationError" || message.includes("validation")) {
7660
+ return "validation-error";
7661
+ }
7662
+ if (message.includes("not found") || message.includes("no such file")) {
7663
+ return "file-not-found";
7664
+ }
7665
+ if (message.includes("permission") || message.includes("access denied")) {
7666
+ return "permission-denied";
7667
+ }
7668
+ if (message.includes("timeout") || message.includes("timed out")) {
7669
+ return "timeout-error";
7670
+ }
7671
+ if (message.includes("dependency") || message.includes("module not found")) {
7672
+ return "dependency-error";
7673
+ }
7674
+ return "unknown-error";
7675
+ }
7676
+ };
7677
+ }
7678
+ });
7679
+
7499
7680
  // packages/tooling/src/utils/pathResolver.ts
7500
7681
  import { createRequire as createRequire2 } from "node:module";
7501
7682
  import {
@@ -7508,6 +7689,9 @@ import {
7508
7689
  isAbsolute as pathIsAbsolute
7509
7690
  } from "node:path";
7510
7691
  import { fileURLToPath as fileURLToPath2 } from "node:url";
7692
+ function getDirnameFromUrl(importMetaUrl) {
7693
+ return dirname2(fileURLToPath2(importMetaUrl));
7694
+ }
7511
7695
  function detectExecutionMode() {
7512
7696
  const currentDir = process.cwd();
7513
7697
  const toolingPath = joinPath(currentDir, PACKAGE_PATHS.TOOLING);
@@ -7520,6 +7704,67 @@ function detectExecutionMode() {
7520
7704
  }
7521
7705
  return "published";
7522
7706
  }
7707
+ function getTemplatesRoot() {
7708
+ const mode = detectExecutionMode();
7709
+ if (mode === "development") {
7710
+ const repoRoot = getRepoRoot();
7711
+ return normalizePath(repoRoot, PACKAGE_PATHS.CLI, "templates");
7712
+ } else {
7713
+ try {
7714
+ const cliRoot2 = resolveFrameworkPackage("@donotdev/cli");
7715
+ if (cliRoot2) {
7716
+ const templatesPath = normalizePath(cliRoot2, "templates");
7717
+ if (pathExists(templatesPath)) {
7718
+ return templatesPath;
7719
+ }
7720
+ }
7721
+ } catch {
7722
+ }
7723
+ try {
7724
+ const req = createRequire2(import.meta.url);
7725
+ const cliPackageJsonPath = req.resolve("@donotdev/cli/package.json");
7726
+ const cliRoot2 = normalizePath(dirname2(cliPackageJsonPath));
7727
+ const templatesPath = normalizePath(cliRoot2, "templates");
7728
+ if (pathExists(templatesPath)) {
7729
+ return templatesPath;
7730
+ }
7731
+ } catch {
7732
+ }
7733
+ const cliRoot = getCliRootFromBundle();
7734
+ return normalizePath(cliRoot, "templates");
7735
+ }
7736
+ }
7737
+ function getCliRootFromBundle() {
7738
+ const currentDir = getDirnameFromUrl(import.meta.url);
7739
+ return normalizePath(currentDir, "..", "..", "..");
7740
+ }
7741
+ async function glob(pattern, options = {}) {
7742
+ const patterns = Array.isArray(pattern) ? pattern : [pattern];
7743
+ const cwd = options.cwd || pathResolverInstance.getAppRoot() || process.cwd();
7744
+ const normalizeCwd = pathResolverInstance.normalizePath(cwd);
7745
+ const relativePatterns = patterns.map((p2) => {
7746
+ const normalizedPattern = pathResolverInstance.normalizePath(p2);
7747
+ if (normalizedPattern.startsWith(normalizeCwd)) {
7748
+ return normalizedPattern.slice(normalizeCwd.length + 1);
7749
+ }
7750
+ if (normalizedPattern.startsWith("/") || /^[A-Z]:/.test(normalizedPattern)) {
7751
+ return normalizedPattern;
7752
+ }
7753
+ return normalizedPattern;
7754
+ });
7755
+ const shouldReturnAbsolute = options.absolute === true;
7756
+ return await pathResolverInstance._globWithNormalization(relativePatterns, {
7757
+ cwd,
7758
+ absolute: shouldReturnAbsolute,
7759
+ onlyFiles: options.nodir !== false && options.onlyDirectories !== true,
7760
+ onlyDirectories: options.onlyDirectories,
7761
+ ignore: options.ignore,
7762
+ dot: options.dot,
7763
+ braceExpansion: true,
7764
+ extglob: true,
7765
+ globstar: true
7766
+ });
7767
+ }
7523
7768
  function globSync(pattern, options = {}) {
7524
7769
  const patterns = Array.isArray(pattern) ? pattern : [pattern];
7525
7770
  const cwd = options.cwd || pathResolverInstance.getAppRoot() || process.cwd();
@@ -7551,7 +7796,7 @@ function globSync(pattern, options = {}) {
7551
7796
  });
7552
7797
  return results.map((p2) => pathResolverInstance.normalizePath(p2));
7553
7798
  }
7554
- var pathResolverInstance, getRepoRoot, getAppRoot, normalizePath, pathExists, readSync, writeSync, getRelativePathBetween, joinPath;
7799
+ var pathResolverInstance, getRepoRoot, getAppRoot, resolveFrameworkPackage, normalizePath, pathExists, read, readSync, write, writeSync, ensureDir, getRelativePathBetween, getDirname, joinPath;
7555
7800
  var init_pathResolver = __esm({
7556
7801
  "packages/tooling/src/utils/pathResolver.ts"() {
7557
7802
  "use strict";
@@ -7560,15 +7805,22 @@ var init_pathResolver = __esm({
7560
7805
  pathResolverInstance = PathResolver.getInstance({ debug: false });
7561
7806
  getRepoRoot = () => pathResolverInstance.getRepoRoot();
7562
7807
  getAppRoot = () => pathResolverInstance.getAppRoot();
7808
+ resolveFrameworkPackage = (name, from) => pathResolverInstance.resolveFrameworkPackage(name, from || null);
7563
7809
  normalizePath = (...pathSegments) => {
7564
7810
  return pathResolverInstance.normalizePath(join2(...pathSegments));
7565
7811
  };
7566
7812
  pathExists = (filePath, silent = false) => pathResolverInstance.pathExists(filePath, silent);
7813
+ read = async (filePath, options) => pathResolverInstance.read(filePath, options);
7567
7814
  readSync = (filePath, options) => pathResolverInstance.readSync(filePath, options);
7815
+ write = async (filePath, content, options) => pathResolverInstance.write(filePath, content, options);
7568
7816
  writeSync = (filePath, content, options) => pathResolverInstance.writeSync(filePath, content, options);
7817
+ ensureDir = async (dirPath) => pathResolverInstance.ensureDir(dirPath);
7569
7818
  getRelativePathBetween = (from, to) => {
7570
7819
  return normalizePath(relative2(from, to));
7571
7820
  };
7821
+ getDirname = (filePath) => {
7822
+ return normalizePath(dirname2(filePath));
7823
+ };
7572
7824
  joinPath = (...pathSegments) => {
7573
7825
  return normalizePath(...pathSegments);
7574
7826
  };
@@ -7625,6 +7877,23 @@ async function askForConfirmation(message, defaultValue = false) {
7625
7877
  }
7626
7878
  return result;
7627
7879
  }
7880
+ async function askForSelection(message, choices, defaultValue = 0) {
7881
+ const options = choices.map((choice) => ({
7882
+ value: choice.value,
7883
+ label: choice.title,
7884
+ hint: choice.hint
7885
+ }));
7886
+ const result = await ve({
7887
+ message,
7888
+ options,
7889
+ initialValue: choices[defaultValue]?.value
7890
+ });
7891
+ if (pD(result)) {
7892
+ xe("Operation cancelled.");
7893
+ process.exit(0);
7894
+ }
7895
+ return result;
7896
+ }
7628
7897
 
7629
7898
  // packages/tooling/src/utils/matrix.ts
7630
7899
  init_utils();
@@ -7773,6 +8042,191 @@ function compareVersions(current, expected) {
7773
8042
  init_utils();
7774
8043
  init_cli_output();
7775
8044
  init_pathResolver();
8045
+
8046
+ // packages/tooling/src/maintenance/sync-docs.ts
8047
+ init_utils();
8048
+ init_cli_output();
8049
+ init_errors();
8050
+ init_pathResolver();
8051
+ var SYNC_PATHS = [
8052
+ // Documentation
8053
+ "guides/**/*.md.example",
8054
+ "guides/**/*.json.example",
8055
+ // Commands
8056
+ ".claude/commands/**/*.md.example",
8057
+ // Agents
8058
+ ".claude/agents/**/*.md.example",
8059
+ // Config files
8060
+ ".claude/mcp.json.example",
8061
+ "CLAUDE.md.example",
8062
+ // MCP config
8063
+ ".cursor/mcp.json.example",
8064
+ ".mcp.json.example"
8065
+ ];
8066
+ var PRESERVE_IF_EXISTS = [
8067
+ "CLAUDE.md"
8068
+ // User may have customized
8069
+ ];
8070
+ function getSourceTemplatesPath() {
8071
+ try {
8072
+ const templatesRoot = getTemplatesRoot();
8073
+ const rootConsumerPath = joinPath(templatesRoot, "root-consumer");
8074
+ if (pathExists(rootConsumerPath)) {
8075
+ return normalizePath(rootConsumerPath);
8076
+ }
8077
+ return null;
8078
+ } catch (error2) {
8079
+ return null;
8080
+ }
8081
+ }
8082
+ async function syncFile(sourcePath, destPath, preserveIfExists, appRoot) {
8083
+ const destPathWithoutExample = destPath.endsWith(".example") ? destPath.slice(0, -8) : destPath;
8084
+ if (preserveIfExists && pathExists(destPathWithoutExample)) {
8085
+ const relativePath = getRelativePathBetween(appRoot, destPathWithoutExample);
8086
+ log.info(`Preserving user-customized file: ${relativePath}`);
8087
+ return false;
8088
+ }
8089
+ if (!pathExists(sourcePath)) {
8090
+ log.warn(`Source file not found: ${sourcePath}`);
8091
+ return false;
8092
+ }
8093
+ const content = await read(sourcePath, { format: "text" });
8094
+ if (!content) {
8095
+ log.warn(`Source file is empty: ${sourcePath}`);
8096
+ return false;
8097
+ }
8098
+ if (pathExists(destPathWithoutExample)) {
8099
+ const existingContent = await read(destPathWithoutExample, {
8100
+ format: "text"
8101
+ });
8102
+ if (existingContent === content) {
8103
+ return false;
8104
+ }
8105
+ }
8106
+ await ensureDir(getDirname(destPathWithoutExample));
8107
+ await write(destPathWithoutExample, content, { format: "text" });
8108
+ return true;
8109
+ }
8110
+ async function syncTemplates(sourceRoot, destRoot, dryRun) {
8111
+ let synced = 0;
8112
+ let preserved = 0;
8113
+ let errors = 0;
8114
+ const normalizedSourceRoot = normalizePath(sourceRoot);
8115
+ const normalizedDestRoot = normalizePath(destRoot);
8116
+ for (const pattern of SYNC_PATHS) {
8117
+ try {
8118
+ const sourceFiles = await glob(pattern, {
8119
+ cwd: normalizedSourceRoot,
8120
+ absolute: true,
8121
+ onlyFiles: true
8122
+ });
8123
+ for (const sourceFile of sourceFiles) {
8124
+ const relativePath = normalizePath(sourceFile).replace(
8125
+ normalizedSourceRoot + "/",
8126
+ ""
8127
+ );
8128
+ const destFile = joinPath(normalizedDestRoot, relativePath);
8129
+ const destWithoutExample = destFile.endsWith(".example") ? destFile.slice(0, -8) : destFile;
8130
+ const shouldPreserve = PRESERVE_IF_EXISTS.some(
8131
+ (preserve) => relativePath.includes(preserve.replace(".example", ""))
8132
+ );
8133
+ if (dryRun) {
8134
+ if (shouldPreserve && pathExists(destWithoutExample)) {
8135
+ const relativeDest = getRelativePathBetween(
8136
+ normalizedDestRoot,
8137
+ destWithoutExample
8138
+ );
8139
+ log.info(`[DRY RUN] Would preserve: ${relativeDest}`);
8140
+ preserved++;
8141
+ } else {
8142
+ const relativeDest = getRelativePathBetween(
8143
+ normalizedDestRoot,
8144
+ destWithoutExample
8145
+ );
8146
+ log.info(`[DRY RUN] Would sync: ${relativeDest}`);
8147
+ synced++;
8148
+ }
8149
+ } else {
8150
+ const wasSynced = await syncFile(
8151
+ sourceFile,
8152
+ destFile,
8153
+ shouldPreserve,
8154
+ normalizedDestRoot
8155
+ );
8156
+ if (wasSynced) {
8157
+ synced++;
8158
+ const relativeDest = getRelativePathBetween(
8159
+ normalizedDestRoot,
8160
+ destWithoutExample
8161
+ );
8162
+ log.info(`Synced: ${relativeDest}`);
8163
+ } else if (shouldPreserve && pathExists(destWithoutExample)) {
8164
+ preserved++;
8165
+ }
8166
+ }
8167
+ }
8168
+ } catch (error2) {
8169
+ errors++;
8170
+ log.error(
8171
+ `Error syncing pattern ${pattern}:`,
8172
+ DoNotDevError.from(error2, `Failed to sync ${pattern}`, "file-operation-error")
8173
+ );
8174
+ }
8175
+ }
8176
+ return { synced, preserved, errors };
8177
+ }
8178
+ async function syncDocumentation(options = {}) {
8179
+ const { dryRun } = options;
8180
+ if (dryRun) {
8181
+ log.info("\u{1F50D} DRY RUN MODE - No files will be modified");
8182
+ }
8183
+ const appRoot = getAppRoot();
8184
+ if (!appRoot) {
8185
+ log.error("Could not determine project root");
8186
+ return 1;
8187
+ }
8188
+ const sourceRoot = getSourceTemplatesPath();
8189
+ if (!sourceRoot) {
8190
+ log.warn("Could not find framework templates. Documentation sync skipped.");
8191
+ log.info("");
8192
+ log.info(" Templates are looked up the same way as create-project:");
8193
+ log.info(" \u2022 Published mode: node_modules/@donotdev/cli/templates");
8194
+ log.info(" \u2022 Dev mode: packages/cli/templates (from monorepo)");
8195
+ log.info("");
8196
+ log.info(" To enable docs sync:");
8197
+ log.info(" \u2022 Install @donotdev/cli: bun add -D @donotdev/cli");
8198
+ log.info(" \u2022 Or run from framework monorepo (dev mode)");
8199
+ return 0;
8200
+ }
8201
+ log.info(`Source templates: ${sourceRoot}`);
8202
+ log.info(`Destination: ${appRoot}`);
8203
+ const result = await syncTemplates(sourceRoot, appRoot, dryRun || false);
8204
+ if (dryRun) {
8205
+ log.info(`
8206
+ [DRY RUN] Would sync ${result.synced} file(s)`);
8207
+ if (result.preserved > 0) {
8208
+ log.info(`[DRY RUN] Would preserve ${result.preserved} user-customized file(s)`);
8209
+ }
8210
+ log.info("[DRY RUN] No files modified");
8211
+ } else {
8212
+ if (result.synced > 0) {
8213
+ log.success(`
8214
+ \u2705 Synced ${result.synced} file(s) from framework`);
8215
+ } else {
8216
+ log.info("\n\u2705 All documentation up to date");
8217
+ }
8218
+ if (result.preserved > 0) {
8219
+ log.info(`\u2139\uFE0F Preserved ${result.preserved} user-customized file(s)`);
8220
+ }
8221
+ if (result.errors > 0) {
8222
+ log.warn(`\u26A0\uFE0F ${result.errors} error(s) occurred during sync`);
8223
+ return 1;
8224
+ }
8225
+ }
8226
+ return 0;
8227
+ }
8228
+
8229
+ // packages/tooling/src/maintenance/bump.ts
7776
8230
  async function queryNpmLatest(packageName) {
7777
8231
  try {
7778
8232
  const res = await fetch(`https://registry.npmjs.org/${packageName}/latest`);
@@ -7823,81 +8277,120 @@ function detectProjectDeps(files) {
7823
8277
  }
7824
8278
  async function main(options = {}) {
7825
8279
  const { dryRun } = options;
7826
- Ie("\u{1F504} Bump - Update framework packages");
8280
+ Ie("\u{1F504} Bump - Update framework packages and documentation");
7827
8281
  if (dryRun) log.info("DRY RUN MODE");
7828
8282
  const appRoot = getAppRoot();
7829
8283
  if (!appRoot) {
7830
8284
  log.error("Could not determine project root");
7831
8285
  return 1;
7832
8286
  }
7833
- const files = globSync("**/package.json", {
7834
- cwd: appRoot,
7835
- ignore: ["**/node_modules/**", "**/dist/**", "**/.next/**"],
7836
- absolute: true
7837
- });
7838
- if (files.length === 0) {
7839
- log.warn("No package.json files found");
7840
- return 0;
7841
- }
7842
- log.info(`Found ${files.length} package.json file(s)`);
7843
- const { frameworkPkgs, externalDeps, packageOccurrences } = detectProjectDeps(files);
7844
- log.info(`Found ${frameworkPkgs.size} @donotdev/* package(s)`);
7845
- log.info(`Found ${externalDeps.size} external dep(s)`);
7846
- log.info("Querying npm...");
7847
- const npmVersions = await queryNpmVersions(Array.from(frameworkPkgs));
7848
- const matrixResult = loadMatrix();
7849
- const matrixVersions = matrixResult ? flattenGroups(matrixResult.matrix.groups) : {};
7850
- if (!matrixResult && externalDeps.size > 0) {
7851
- log.info(
7852
- "Matrix not found - only updating @donotdev/* packages (external deps skipped)"
8287
+ let updatePackages = false;
8288
+ let updateDocs = false;
8289
+ if (dryRun) {
8290
+ updatePackages = true;
8291
+ updateDocs = true;
8292
+ } else {
8293
+ const choices = [
8294
+ { title: "Update packages", value: "packages", hint: "Update @donotdev/* packages and dependencies" },
8295
+ { title: "Sync documentation", value: "docs", hint: "Sync guides, commands, and agents from framework" },
8296
+ { title: "Both", value: "both", hint: "Update packages and sync documentation" }
8297
+ ];
8298
+ const selection = await askForSelection(
8299
+ "What would you like to update?",
8300
+ choices,
8301
+ 2
8302
+ // Default to "Both"
7853
8303
  );
8304
+ if (selection === "packages") {
8305
+ updatePackages = true;
8306
+ } else if (selection === "docs") {
8307
+ updateDocs = true;
8308
+ } else if (selection === "both") {
8309
+ updatePackages = true;
8310
+ updateDocs = true;
8311
+ }
7854
8312
  }
7855
- const updates = [];
7856
- const majorUpdates = [];
7857
- for (const [key, occurrences] of packageOccurrences) {
7858
- const [name, field] = key.split(":");
7859
- if (name === "@donotdev/templates") continue;
7860
- let latest;
7861
- if (name.startsWith("@donotdev/")) {
7862
- latest = npmVersions[name];
8313
+ if (updatePackages) {
8314
+ const files = globSync("**/package.json", {
8315
+ cwd: appRoot,
8316
+ ignore: ["**/node_modules/**", "**/dist/**", "**/.next/**"],
8317
+ absolute: true
8318
+ });
8319
+ if (files.length === 0) {
8320
+ log.warn("No package.json files found");
7863
8321
  } else {
7864
- latest = matrixVersions[name];
7865
- }
7866
- if (!latest) continue;
7867
- for (const occurrence of occurrences) {
7868
- const normalizedCurrent = normalizeVersion(occurrence.version);
7869
- const normalizedLatest = normalizeVersion(latest);
7870
- const cmp = compareVersions(normalizedCurrent, normalizedLatest);
7871
- if (cmp.equal || cmp.ahead) continue;
7872
- const update = {
7873
- pkg: name,
7874
- field,
7875
- current: occurrence.version,
7876
- latest,
7877
- file: occurrence.file,
7878
- isMajor: cmp.isMajor
7879
- };
7880
- if (cmp.isMajor) {
7881
- const currentMajor = Number(normalizedCurrent.split(".")[0]);
7882
- const latestMajor = Number(normalizedLatest.split(".")[0]);
7883
- if (matrixResult) {
7884
- const guide = getMigrationGuide(currentMajor, latestMajor);
7885
- if (guide) {
7886
- update.migrationPath = guide.path;
7887
- update.breakingChanges = guide.breakingChanges;
8322
+ log.info(`Found ${files.length} package.json file(s)`);
8323
+ const { frameworkPkgs, externalDeps, packageOccurrences } = detectProjectDeps(files);
8324
+ log.info(`Found ${frameworkPkgs.size} @donotdev/* package(s)`);
8325
+ log.info(`Found ${externalDeps.size} external dep(s)`);
8326
+ log.info("Querying npm...");
8327
+ const npmVersions = await queryNpmVersions(Array.from(frameworkPkgs));
8328
+ const matrixResult = loadMatrix();
8329
+ const matrixVersions = matrixResult ? flattenGroups(matrixResult.matrix.groups) : {};
8330
+ if (!matrixResult && externalDeps.size > 0) {
8331
+ log.info(
8332
+ "Matrix not found - only updating @donotdev/* packages (external deps skipped)"
8333
+ );
8334
+ }
8335
+ const updates = [];
8336
+ const majorUpdates = [];
8337
+ for (const [key, occurrences] of packageOccurrences) {
8338
+ const [name, field] = key.split(":");
8339
+ if (name === "@donotdev/templates") continue;
8340
+ let latest;
8341
+ if (name.startsWith("@donotdev/")) {
8342
+ latest = npmVersions[name];
8343
+ } else {
8344
+ latest = matrixVersions[name];
8345
+ }
8346
+ if (!latest) continue;
8347
+ for (const occurrence of occurrences) {
8348
+ const normalizedCurrent = normalizeVersion(occurrence.version);
8349
+ const normalizedLatest = normalizeVersion(latest);
8350
+ const cmp = compareVersions(normalizedCurrent, normalizedLatest);
8351
+ if (cmp.equal || cmp.ahead) continue;
8352
+ const update = {
8353
+ pkg: name,
8354
+ field,
8355
+ current: occurrence.version,
8356
+ latest,
8357
+ file: occurrence.file,
8358
+ isMajor: cmp.isMajor
8359
+ };
8360
+ if (cmp.isMajor) {
8361
+ const currentMajor = Number(normalizedCurrent.split(".")[0]);
8362
+ const latestMajor = Number(normalizedLatest.split(".")[0]);
8363
+ if (matrixResult) {
8364
+ const guide = getMigrationGuide(currentMajor, latestMajor);
8365
+ if (guide) {
8366
+ update.migrationPath = guide.path;
8367
+ update.breakingChanges = guide.breakingChanges;
8368
+ }
8369
+ }
8370
+ majorUpdates.push(update);
8371
+ } else {
8372
+ updates.push(update);
7888
8373
  }
7889
8374
  }
7890
- majorUpdates.push(update);
8375
+ }
8376
+ if (updates.length === 0 && majorUpdates.length === 0) {
8377
+ log.success("All packages up to date!");
7891
8378
  } else {
7892
- updates.push(update);
8379
+ await handlePackageUpdates(updates, majorUpdates, appRoot, dryRun || false);
7893
8380
  }
7894
8381
  }
7895
8382
  }
7896
- if (updates.length === 0 && majorUpdates.length === 0) {
7897
- log.success("All packages up to date!");
7898
- Se("");
7899
- return 0;
8383
+ if (updateDocs) {
8384
+ log.info("\n\u{1F4DA} Syncing framework documentation...");
8385
+ const syncResult = await syncDocumentation({ dryRun });
8386
+ if (syncResult !== 0 && !dryRun) {
8387
+ log.warn("Some documentation files could not be synced");
8388
+ }
7900
8389
  }
8390
+ Se("");
8391
+ return 0;
8392
+ }
8393
+ async function handlePackageUpdates(updates, majorUpdates, appRoot, dryRun) {
7901
8394
  if (updates.length > 0) {
7902
8395
  log.info(`
7903
8396
  ${updates.length} update(s) available:`);
@@ -7992,8 +8485,6 @@ Done. Updated ${updatedFiles.size} file(s). Run "bun install" to apply.`
7992
8485
  }
7993
8486
  }
7994
8487
  }
7995
- Se("");
7996
- return 0;
7997
8488
  }
7998
8489
  export {
7999
8490
  main