@deepstorm/cli 0.4.0 → 0.5.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.
package/dist/cli.js CHANGED
@@ -1187,13 +1187,13 @@ var require_ast = __commonJS({
1187
1187
  helperExpression: function helperExpression(node) {
1188
1188
  return node.type === "SubExpression" || (node.type === "MustacheStatement" || node.type === "BlockStatement") && !!(node.params && node.params.length || node.hash);
1189
1189
  },
1190
- scopedId: function scopedId(path23) {
1191
- return /^\.|this\b/.test(path23.original);
1190
+ scopedId: function scopedId(path24) {
1191
+ return /^\.|this\b/.test(path24.original);
1192
1192
  },
1193
1193
  // an ID is simple if it only has one part, and that part is not
1194
1194
  // `..` or `this`.
1195
- simpleId: function simpleId(path23) {
1196
- return path23.parts.length === 1 && !AST.helpers.scopedId(path23) && !path23.depth;
1195
+ simpleId: function simpleId(path24) {
1196
+ return path24.parts.length === 1 && !AST.helpers.scopedId(path24) && !path24.depth;
1197
1197
  }
1198
1198
  }
1199
1199
  };
@@ -2263,12 +2263,12 @@ var require_helpers2 = __commonJS({
2263
2263
  loc
2264
2264
  };
2265
2265
  }
2266
- function prepareMustache(path23, params, hash, open, strip, locInfo) {
2266
+ function prepareMustache(path24, params, hash, open, strip, locInfo) {
2267
2267
  var escapeFlag = open.charAt(3) || open.charAt(2), escaped = escapeFlag !== "{" && escapeFlag !== "&";
2268
2268
  var decorator = /\*/.test(open);
2269
2269
  return {
2270
2270
  type: decorator ? "Decorator" : "MustacheStatement",
2271
- path: path23,
2271
+ path: path24,
2272
2272
  params,
2273
2273
  hash,
2274
2274
  escaped,
@@ -2586,9 +2586,9 @@ var require_compiler = __commonJS({
2586
2586
  },
2587
2587
  DecoratorBlock: function DecoratorBlock(decorator) {
2588
2588
  var program2 = decorator.program && this.compileProgram(decorator.program);
2589
- var params = this.setupFullMustacheParams(decorator, program2, void 0), path23 = decorator.path;
2589
+ var params = this.setupFullMustacheParams(decorator, program2, void 0), path24 = decorator.path;
2590
2590
  this.useDecorators = true;
2591
- this.opcode("registerDecorator", params.length, path23.original);
2591
+ this.opcode("registerDecorator", params.length, path24.original);
2592
2592
  },
2593
2593
  PartialStatement: function PartialStatement(partial) {
2594
2594
  this.usePartial = true;
@@ -2652,46 +2652,46 @@ var require_compiler = __commonJS({
2652
2652
  }
2653
2653
  },
2654
2654
  ambiguousSexpr: function ambiguousSexpr(sexpr, program2, inverse) {
2655
- var path23 = sexpr.path, name = path23.parts[0], isBlock = program2 != null || inverse != null;
2656
- this.opcode("getContext", path23.depth);
2655
+ var path24 = sexpr.path, name = path24.parts[0], isBlock = program2 != null || inverse != null;
2656
+ this.opcode("getContext", path24.depth);
2657
2657
  this.opcode("pushProgram", program2);
2658
2658
  this.opcode("pushProgram", inverse);
2659
- path23.strict = true;
2660
- this.accept(path23);
2659
+ path24.strict = true;
2660
+ this.accept(path24);
2661
2661
  this.opcode("invokeAmbiguous", name, isBlock);
2662
2662
  },
2663
2663
  simpleSexpr: function simpleSexpr(sexpr) {
2664
- var path23 = sexpr.path;
2665
- path23.strict = true;
2666
- this.accept(path23);
2664
+ var path24 = sexpr.path;
2665
+ path24.strict = true;
2666
+ this.accept(path24);
2667
2667
  this.opcode("resolvePossibleLambda");
2668
2668
  },
2669
2669
  helperSexpr: function helperSexpr(sexpr, program2, inverse) {
2670
- var params = this.setupFullMustacheParams(sexpr, program2, inverse), path23 = sexpr.path, name = path23.parts[0];
2670
+ var params = this.setupFullMustacheParams(sexpr, program2, inverse), path24 = sexpr.path, name = path24.parts[0];
2671
2671
  if (this.options.knownHelpers[name]) {
2672
2672
  this.opcode("invokeKnownHelper", params.length, name);
2673
2673
  } else if (this.options.knownHelpersOnly) {
2674
2674
  throw new _exception2["default"]("You specified knownHelpersOnly, but used the unknown helper " + name, sexpr);
2675
2675
  } else {
2676
- path23.strict = true;
2677
- path23.falsy = true;
2678
- this.accept(path23);
2679
- this.opcode("invokeHelper", params.length, path23.original, _ast2["default"].helpers.simpleId(path23));
2676
+ path24.strict = true;
2677
+ path24.falsy = true;
2678
+ this.accept(path24);
2679
+ this.opcode("invokeHelper", params.length, path24.original, _ast2["default"].helpers.simpleId(path24));
2680
2680
  }
2681
2681
  },
2682
- PathExpression: function PathExpression(path23) {
2683
- this.addDepth(path23.depth);
2684
- this.opcode("getContext", path23.depth);
2685
- var name = path23.parts[0], scoped = _ast2["default"].helpers.scopedId(path23), blockParamId = !path23.depth && !scoped && this.blockParamIndex(name);
2682
+ PathExpression: function PathExpression(path24) {
2683
+ this.addDepth(path24.depth);
2684
+ this.opcode("getContext", path24.depth);
2685
+ var name = path24.parts[0], scoped = _ast2["default"].helpers.scopedId(path24), blockParamId = !path24.depth && !scoped && this.blockParamIndex(name);
2686
2686
  if (blockParamId) {
2687
- this.opcode("lookupBlockParam", blockParamId, path23.parts);
2687
+ this.opcode("lookupBlockParam", blockParamId, path24.parts);
2688
2688
  } else if (!name) {
2689
2689
  this.opcode("pushContext");
2690
- } else if (path23.data) {
2690
+ } else if (path24.data) {
2691
2691
  this.options.data = true;
2692
- this.opcode("lookupData", path23.depth, path23.parts, path23.strict);
2692
+ this.opcode("lookupData", path24.depth, path24.parts, path24.strict);
2693
2693
  } else {
2694
- this.opcode("lookupOnContext", path23.parts, path23.falsy, path23.strict, scoped);
2694
+ this.opcode("lookupOnContext", path24.parts, path24.falsy, path24.strict, scoped);
2695
2695
  }
2696
2696
  },
2697
2697
  StringLiteral: function StringLiteral(string) {
@@ -3041,16 +3041,16 @@ var require_util = __commonJS({
3041
3041
  }
3042
3042
  exports2.urlGenerate = urlGenerate;
3043
3043
  function normalize(aPath) {
3044
- var path23 = aPath;
3044
+ var path24 = aPath;
3045
3045
  var url = urlParse(aPath);
3046
3046
  if (url) {
3047
3047
  if (!url.path) {
3048
3048
  return aPath;
3049
3049
  }
3050
- path23 = url.path;
3050
+ path24 = url.path;
3051
3051
  }
3052
- var isAbsolute = exports2.isAbsolute(path23);
3053
- var parts = path23.split(/\/+/);
3052
+ var isAbsolute = exports2.isAbsolute(path24);
3053
+ var parts = path24.split(/\/+/);
3054
3054
  for (var part, up = 0, i = parts.length - 1; i >= 0; i--) {
3055
3055
  part = parts[i];
3056
3056
  if (part === ".") {
@@ -3067,18 +3067,18 @@ var require_util = __commonJS({
3067
3067
  }
3068
3068
  }
3069
3069
  }
3070
- path23 = parts.join("/");
3071
- if (path23 === "") {
3072
- path23 = isAbsolute ? "/" : ".";
3070
+ path24 = parts.join("/");
3071
+ if (path24 === "") {
3072
+ path24 = isAbsolute ? "/" : ".";
3073
3073
  }
3074
3074
  if (url) {
3075
- url.path = path23;
3075
+ url.path = path24;
3076
3076
  return urlGenerate(url);
3077
3077
  }
3078
- return path23;
3078
+ return path24;
3079
3079
  }
3080
3080
  exports2.normalize = normalize;
3081
- function join21(aRoot, aPath) {
3081
+ function join22(aRoot, aPath) {
3082
3082
  if (aRoot === "") {
3083
3083
  aRoot = ".";
3084
3084
  }
@@ -3110,7 +3110,7 @@ var require_util = __commonJS({
3110
3110
  }
3111
3111
  return joined;
3112
3112
  }
3113
- exports2.join = join21;
3113
+ exports2.join = join22;
3114
3114
  exports2.isAbsolute = function(aPath) {
3115
3115
  return aPath.charAt(0) === "/" || urlRegexp.test(aPath);
3116
3116
  };
@@ -3283,7 +3283,7 @@ var require_util = __commonJS({
3283
3283
  parsed.path = parsed.path.substring(0, index + 1);
3284
3284
  }
3285
3285
  }
3286
- sourceURL = join21(urlGenerate(parsed), sourceURL);
3286
+ sourceURL = join22(urlGenerate(parsed), sourceURL);
3287
3287
  }
3288
3288
  return normalize(sourceURL);
3289
3289
  }
@@ -5858,8 +5858,8 @@ var require_printer = __commonJS({
5858
5858
  return this.accept(sexpr.path) + " " + params + hash;
5859
5859
  };
5860
5860
  PrintVisitor.prototype.PathExpression = function(id) {
5861
- var path23 = id.parts.join("/");
5862
- return (id.data ? "@" : "") + "PATH:" + path23;
5861
+ var path24 = id.parts.join("/");
5862
+ return (id.data ? "@" : "") + "PATH:" + path24;
5863
5863
  };
5864
5864
  PrintVisitor.prototype.StringLiteral = function(string) {
5865
5865
  return '"' + string.value + '"';
@@ -5898,8 +5898,8 @@ var require_lib = __commonJS({
5898
5898
  handlebars.print = printer.print;
5899
5899
  module2.exports = handlebars;
5900
5900
  function extension(module3, filename) {
5901
- var fs25 = require("fs");
5902
- var templateString = fs25.readFileSync(filename, "utf8");
5901
+ var fs26 = require("fs");
5902
+ var templateString = fs26.readFileSync(filename, "utf8");
5903
5903
  module3.exports = handlebars.compile(templateString);
5904
5904
  }
5905
5905
  if (typeof require !== "undefined" && require.extensions) {
@@ -5911,8 +5911,8 @@ var require_lib = __commonJS({
5911
5911
 
5912
5912
  // src/index.ts
5913
5913
  var import_commander = require("commander");
5914
- var fs24 = __toESM(require("node:fs"));
5915
- var path22 = __toESM(require("node:path"));
5914
+ var fs25 = __toESM(require("node:fs"));
5915
+ var path23 = __toESM(require("node:path"));
5916
5916
 
5917
5917
  // src/commands/setup.ts
5918
5918
  var path6 = __toESM(require("node:path"));
@@ -7449,23 +7449,815 @@ function readExistingEnvKeys(envPath) {
7449
7449
  return keys;
7450
7450
  }
7451
7451
 
7452
+ // src/commands/init.ts
7453
+ var fs11 = __toESM(require("node:fs"));
7454
+ var path7 = __toESM(require("node:path"));
7455
+ var VALID_PROJECT_NAME = /^[a-zA-Z0-9_-]+$/;
7456
+ function parseInitArgs(raw) {
7457
+ const opts = {};
7458
+ if (raw.name && typeof raw.name === "string") opts.projectName = raw.name;
7459
+ if (raw.frontend && typeof raw.frontend === "string") opts.frontend = raw.frontend;
7460
+ if (raw.backend && typeof raw.backend === "string") opts.backend = raw.backend;
7461
+ if (raw.output && typeof raw.output === "string") opts.output = raw.output;
7462
+ if (raw.uiLib && typeof raw.uiLib === "string") opts.uiLib = raw.uiLib;
7463
+ if (raw.cssFramework && typeof raw.cssFramework === "string") opts.cssFramework = raw.cssFramework;
7464
+ if (raw.orm && typeof raw.orm === "string") opts.orm = raw.orm;
7465
+ if (raw.migration && typeof raw.migration === "string") opts.migration = raw.migration;
7466
+ if (raw.ai && typeof raw.ai === "string") opts.ai = raw.ai;
7467
+ if (raw["ui-lib"] && typeof raw["ui-lib"] === "string") opts.uiLib = raw["ui-lib"];
7468
+ if (raw["css"] && typeof raw["css"] === "string") opts.cssFramework = raw["css"];
7469
+ return opts;
7470
+ }
7471
+ function registerInitCommand(program2) {
7472
+ program2.command("init").description("\u521D\u59CB\u5316\u9879\u76EE\u811A\u624B\u67B6 \u2014 \u9009\u62E9\u6280\u672F\u6808\uFF0C\u751F\u6210\u9879\u76EE\u9AA8\u67B6").option("--name <name>", "\u9879\u76EE\u540D\u79F0").option("--frontend <framework>", "\u524D\u7AEF\u6846\u67B6\uFF08angular\uFF09").option("--backend <language>", "\u540E\u7AEF\u8BED\u8A00\uFF08java\uFF09").option("--output <dir>", "\u8F93\u51FA\u76EE\u5F55\uFF08\u9ED8\u8BA4\u4E3A\u5F53\u524D\u76EE\u5F55\uFF09").option("--ui-lib <lib>", "UI \u5E93\uFF08primeng\uFF09").option("--css <framework>", "CSS \u6846\u67B6\uFF08tailwind\uFF09").option("--orm <orm>", "ORM \u6846\u67B6\uFF08hibernate\uFF09").option("--migration <tool>", "\u6570\u636E\u5E93\u8FC1\u79FB\u5DE5\u5177\uFF08liquibase\uFF09").option("--ai <framework>", "AI \u6846\u67B6\uFF08spring-ai\uFF09").action(async (options) => {
7473
+ const args = parseInitArgs(options);
7474
+ const targetDir = options.output || process.cwd();
7475
+ if (args.projectName && (args.frontend || args.backend)) {
7476
+ await runInit(targetDir, args);
7477
+ } else {
7478
+ await runInteractiveMode(targetDir);
7479
+ }
7480
+ });
7481
+ }
7482
+ function buildContext(opts) {
7483
+ return {
7484
+ projectName: opts.projectName,
7485
+ packageName: opts.projectName.replace(/[_-]/g, "").toLowerCase(),
7486
+ groupId: "com.example",
7487
+ frontend: opts.frontend || false,
7488
+ backend: opts.backend || false,
7489
+ uiLib: opts.uiLib || false,
7490
+ cssFramework: opts.cssFramework || false,
7491
+ orm: opts.orm || false,
7492
+ migration: opts.migration || false,
7493
+ ai: opts.ai || false
7494
+ };
7495
+ }
7496
+ async function runInteractiveMode(targetDir) {
7497
+ const { intro: intro2, outro: outro2, text: text2, select: select2, isCancel: isCancel8, confirm: confirm6 } = await import("@clack/prompts");
7498
+ intro2("\u{1F680} DeepStorm Init \u2014 \u9879\u76EE\u811A\u624B\u67B6\u521D\u59CB\u5316");
7499
+ const projectName = await text2({
7500
+ message: "\u9879\u76EE\u540D\u79F0\uFF1A",
7501
+ placeholder: "my-project",
7502
+ validate: (value) => {
7503
+ if (!value) return "\u8BF7\u8F93\u5165\u9879\u76EE\u540D\u79F0";
7504
+ if (!VALID_PROJECT_NAME.test(value)) return "\u9879\u76EE\u540D\u4EC5\u652F\u6301\u5B57\u6BCD\u3001\u6570\u5B57\u3001\u4E0B\u5212\u7EBF\u548C\u77ED\u6A2A\u7EBF";
7505
+ return void 0;
7506
+ }
7507
+ });
7508
+ if (isCancel8(projectName) || typeof projectName !== "string") {
7509
+ outro2("\u5DF2\u53D6\u6D88");
7510
+ return;
7511
+ }
7512
+ const frontendChoice = await select2({
7513
+ message: "\u9009\u62E9\u524D\u7AEF\u6846\u67B6\uFF1A",
7514
+ options: [
7515
+ { value: "angular", label: "Angular" },
7516
+ { value: "none", label: "\u4E0D\u9700\u8981\u524D\u7AEF" }
7517
+ ]
7518
+ });
7519
+ if (isCancel8(frontendChoice)) {
7520
+ outro2("\u5DF2\u53D6\u6D88");
7521
+ return;
7522
+ }
7523
+ let uiLib;
7524
+ let cssFramework;
7525
+ if (frontendChoice === "angular") {
7526
+ uiLib = await select2({
7527
+ message: "\u9009\u62E9 UI \u5E93\uFF1A",
7528
+ options: [
7529
+ { value: "primeng", label: "PrimeNG" },
7530
+ { value: "none", label: "\u65E0\uFF08\u4EC5 Angular \u6838\u5FC3\uFF09" }
7531
+ ]
7532
+ });
7533
+ if (isCancel8(uiLib)) {
7534
+ outro2("\u5DF2\u53D6\u6D88");
7535
+ return;
7536
+ }
7537
+ cssFramework = await select2({
7538
+ message: "\u9009\u62E9 CSS \u65B9\u6848\uFF1A",
7539
+ options: [
7540
+ { value: "tailwind", label: "Tailwind CSS" },
7541
+ { value: "none", label: "\u6807\u51C6 CSS" }
7542
+ ]
7543
+ });
7544
+ if (isCancel8(cssFramework)) {
7545
+ outro2("\u5DF2\u53D6\u6D88");
7546
+ return;
7547
+ }
7548
+ }
7549
+ const backendChoice = await select2({
7550
+ message: "\u9009\u62E9\u540E\u7AEF\u6846\u67B6\uFF1A",
7551
+ options: [
7552
+ { value: "java", label: "Java (Spring Boot)" },
7553
+ { value: "none", label: "\u4E0D\u9700\u8981\u540E\u7AEF" }
7554
+ ]
7555
+ });
7556
+ if (isCancel8(backendChoice)) {
7557
+ outro2("\u5DF2\u53D6\u6D88");
7558
+ return;
7559
+ }
7560
+ let orm;
7561
+ let migration;
7562
+ let aiChoice;
7563
+ if (backendChoice === "java") {
7564
+ orm = await select2({
7565
+ message: "\u9009\u62E9 ORM \u6846\u67B6\uFF1A",
7566
+ options: [
7567
+ { value: "hibernate", label: "Hibernate" },
7568
+ { value: "none", label: "\u65E0" }
7569
+ ]
7570
+ });
7571
+ if (isCancel8(orm)) {
7572
+ outro2("\u5DF2\u53D6\u6D88");
7573
+ return;
7574
+ }
7575
+ migration = await select2({
7576
+ message: "\u9009\u62E9\u6570\u636E\u5E93\u8FC1\u79FB\u5DE5\u5177\uFF1A",
7577
+ options: [
7578
+ { value: "liquibase", label: "Liquibase" },
7579
+ { value: "none", label: "\u65E0" }
7580
+ ]
7581
+ });
7582
+ if (isCancel8(migration)) {
7583
+ outro2("\u5DF2\u53D6\u6D88");
7584
+ return;
7585
+ }
7586
+ aiChoice = await select2({
7587
+ message: "\u9009\u62E9 AI \u6846\u67B6\uFF1A",
7588
+ options: [
7589
+ { value: "spring-ai", label: "Spring AI" },
7590
+ { value: "none", label: "\u65E0" }
7591
+ ]
7592
+ });
7593
+ if (isCancel8(aiChoice)) {
7594
+ outro2("\u5DF2\u53D6\u6D88");
7595
+ return;
7596
+ }
7597
+ }
7598
+ if ((!frontendChoice || frontendChoice === "none") && (!backendChoice || backendChoice === "none")) {
7599
+ console.error("\u274C \u81F3\u5C11\u9700\u8981\u9009\u62E9\u524D\u7AEF\u6216\u540E\u7AEF\u4E4B\u4E00");
7600
+ outro2("\u521D\u59CB\u5316\u5931\u8D25");
7601
+ return;
7602
+ }
7603
+ await runInit(targetDir, {
7604
+ projectName,
7605
+ frontend: frontendChoice === "none" ? void 0 : frontendChoice,
7606
+ backend: backendChoice === "none" ? void 0 : backendChoice,
7607
+ uiLib: uiLib && uiLib !== "none" ? uiLib : void 0,
7608
+ cssFramework: cssFramework && cssFramework !== "none" ? cssFramework : void 0,
7609
+ orm: orm && orm !== "none" ? orm : void 0,
7610
+ migration: migration && migration !== "none" ? migration : void 0,
7611
+ ai: aiChoice && aiChoice !== "none" ? aiChoice : void 0
7612
+ });
7613
+ outro2("\u2705 \u9879\u76EE\u5DF2\u751F\u6210\uFF01");
7614
+ }
7615
+ async function runInit(baseDir, opts) {
7616
+ if (!opts.projectName) {
7617
+ throw new Error("\u9879\u76EE\u540D\u79F0\u4E3A\u5FC5\u586B\u9879");
7618
+ }
7619
+ if (!VALID_PROJECT_NAME.test(opts.projectName)) {
7620
+ throw new Error(`\u9879\u76EE\u540D "${opts.projectName}" \u5305\u542B\u975E\u6CD5\u5B57\u7B26\u3002\u4EC5\u652F\u6301\u5B57\u6BCD\u3001\u6570\u5B57\u3001\u4E0B\u5212\u7EBF\u548C\u77ED\u6A2A\u7EBF\u3002`);
7621
+ }
7622
+ const projectDir = path7.join(baseDir, opts.projectName);
7623
+ if (fs11.existsSync(projectDir)) {
7624
+ throw new Error(`\u76EE\u6807\u76EE\u5F55 ${projectDir} \u5DF2\u5B58\u5728\u3002\u8BF7\u5220\u9664\u540E\u91CD\u8BD5\u6216\u4F7F\u7528\u5176\u4ED6\u9879\u76EE\u540D\u3002`);
7625
+ }
7626
+ const ctx = buildContext(opts);
7627
+ fs11.mkdirSync(projectDir, { recursive: true });
7628
+ const hasFrontend = opts.frontend === "angular";
7629
+ const hasBackend = opts.backend === "java";
7630
+ try {
7631
+ if (hasFrontend) {
7632
+ renderAngularTemplate(projectDir, ctx);
7633
+ }
7634
+ if (hasBackend) {
7635
+ renderJavaTemplate(projectDir, ctx);
7636
+ }
7637
+ renderCommonFiles(projectDir, ctx);
7638
+ console.log(`
7639
+ \u2714 \u9879\u76EE\u5DF2\u521B\u5EFA: ${projectDir}`);
7640
+ console.log("\n\u4E0B\u4E00\u6B65:");
7641
+ console.log(` cd ${opts.projectName}`);
7642
+ if (opts.frontend) console.log(` pnpm install # \u5B89\u88C5\u524D\u7AEF\u4F9D\u8D56`);
7643
+ if (opts.backend) console.log(` ./gradlew build # \u6784\u5EFA\u540E\u7AEF`);
7644
+ console.log();
7645
+ printProjectTree(projectDir, hasFrontend, hasBackend);
7646
+ } catch (err) {
7647
+ if (fs11.existsSync(projectDir)) {
7648
+ fs11.rmSync(projectDir, { recursive: true, force: true });
7649
+ }
7650
+ throw err;
7651
+ }
7652
+ }
7653
+ function renderAngularTemplate(projectDir, ctx) {
7654
+ const hasPrimeng = ctx.uiLib === "primeng";
7655
+ const hasTailwind = ctx.cssFramework === "tailwind";
7656
+ writeTemplate(projectDir, "angular.json", JSON.stringify({
7657
+ $schema: "./node_modules/@angular/cli/lib/config/schema.json",
7658
+ version: 1,
7659
+ newProjectRoot: "projects",
7660
+ projects: {
7661
+ [ctx.packageName]: {
7662
+ projectType: "application",
7663
+ root: "",
7664
+ sourceRoot: "src/main/web",
7665
+ prefix: "app",
7666
+ architect: {
7667
+ build: {
7668
+ builder: "@angular-devkit/build-angular:application",
7669
+ options: {
7670
+ outputPath: "build",
7671
+ index: "src/main/web/index.html",
7672
+ browser: "src/main/web/main.ts",
7673
+ polyfills: ["zone.js"],
7674
+ tsConfig: "tsconfig.app.json",
7675
+ assets: [{ glob: "**/*", input: "public" }],
7676
+ styles: getAngularStyles(hasPrimeng),
7677
+ scripts: []
7678
+ },
7679
+ configurations: {
7680
+ production: { budgets: [], outputHashing: "all" },
7681
+ development: { optimization: false, extractLicenses: false, sourceMap: true }
7682
+ },
7683
+ defaultConfiguration: "production"
7684
+ },
7685
+ serve: {
7686
+ builder: "@angular-devkit/build-angular:dev-server",
7687
+ configurations: { production: { buildTarget: `${ctx.packageName}:build:production` }, development: { buildTarget: `${ctx.packageName}:build:development` } },
7688
+ defaultConfiguration: "development",
7689
+ options: { proxyConfig: "proxy.conf.json" }
7690
+ },
7691
+ test: {
7692
+ builder: "@angular-devkit/build-angular:karma",
7693
+ options: { polyfills: ["zone.js", "zone.js/testing"], tsConfig: "tsconfig.spec.json", assets: [{ glob: "**/*", input: "public" }], styles: getAngularStyles(hasPrimeng), scripts: [] }
7694
+ }
7695
+ }
7696
+ }
7697
+ }
7698
+ }, null, 2));
7699
+ writeTemplate(projectDir, "tsconfig.json", JSON.stringify({
7700
+ compileOnSave: false,
7701
+ compilerOptions: {
7702
+ baseUrl: "./",
7703
+ outDir: "./dist",
7704
+ forceConsistentCasingInFileNames: true,
7705
+ strict: true,
7706
+ noImplicitOverride: true,
7707
+ noPropertyAccessFromIndexSignature: true,
7708
+ noImplicitReturns: true,
7709
+ noFallthroughCasesInSwitch: true,
7710
+ sourceMap: true,
7711
+ declaration: false,
7712
+ downlevelIteration: true,
7713
+ experimentalDecorators: true,
7714
+ moduleResolution: "bundler",
7715
+ importHelpers: true,
7716
+ target: "ES2022",
7717
+ module: "ES2022",
7718
+ lib: ["ES2022", "dom"],
7719
+ skipLibCheck: true
7720
+ },
7721
+ angularCompilerOptions: {
7722
+ enableI18nLegacyMessageIdFormat: false,
7723
+ strictInjectionParameters: true,
7724
+ strictInputAccessModifiers: true,
7725
+ strictTemplates: true
7726
+ }
7727
+ }, null, 2));
7728
+ writeTemplate(projectDir, "tsconfig.app.json", JSON.stringify({
7729
+ extends: "./tsconfig.json",
7730
+ compilerOptions: { outDir: "./out-tsc/app", types: [] },
7731
+ files: ["src/main/web/main.ts"],
7732
+ include: ["src/**/*.d.ts"]
7733
+ }, null, 2));
7734
+ writeTemplate(projectDir, "tsconfig.spec.json", JSON.stringify({
7735
+ extends: "./tsconfig.json",
7736
+ compilerOptions: { outDir: "./out-tsc/spec", types: ["jasmine"] },
7737
+ include: ["src/**/*.spec.ts", "src/**/*.d.ts"]
7738
+ }, null, 2));
7739
+ const pkgDeps = {
7740
+ "@angular/animations": "^21.0.0",
7741
+ "@angular/common": "^21.0.0",
7742
+ "@angular/compiler": "^21.0.0",
7743
+ "@angular/core": "^21.0.0",
7744
+ "@angular/forms": "^21.0.0",
7745
+ "@angular/platform-browser": "^21.0.0",
7746
+ "@angular/router": "^21.0.0",
7747
+ "rxjs": "~7.8.0",
7748
+ "tslib": "^2.3.0",
7749
+ "zone.js": "~0.15.0"
7750
+ };
7751
+ const devDeps = {
7752
+ "@angular-devkit/build-angular": "^21.0.0",
7753
+ "@angular/cli": "^21.0.0",
7754
+ "@angular/compiler-cli": "^21.0.0",
7755
+ "typescript": "~5.7.0"
7756
+ };
7757
+ if (hasPrimeng) {
7758
+ pkgDeps["primeng"] = "^21.0.0";
7759
+ pkgDeps["@primeng/themes"] = "^21.0.0";
7760
+ pkgDeps["@primeuix/themes"] = "^2.0.0";
7761
+ }
7762
+ writeTemplate(projectDir, "package.json", JSON.stringify({
7763
+ name: ctx.packageName,
7764
+ version: "1.0.0-dev",
7765
+ private: true,
7766
+ packageManager: "pnpm@10.0.0",
7767
+ scripts: {
7768
+ ng: "ng",
7769
+ start: "ng serve",
7770
+ build: "ng build",
7771
+ watch: "ng build --watch --configuration development",
7772
+ test: "ng test",
7773
+ lint: "ng lint",
7774
+ typecheck: "tsc --build --noEmit"
7775
+ },
7776
+ dependencies: pkgDeps,
7777
+ devDependencies: devDeps
7778
+ }, null, 2));
7779
+ writeTemplate(projectDir, "proxy.conf.json", JSON.stringify({
7780
+ "/api": {
7781
+ target: "http://localhost:8080",
7782
+ secure: false
7783
+ }
7784
+ }, null, 2));
7785
+ writeTemplate(projectDir, "eslint.config.mjs", `import globals from "globals";
7786
+ import pluginJs from "@eslint/js";
7787
+ import tseslint from "typescript-eslint";
7788
+
7789
+ export default [
7790
+ { files: ["**/*.{js,mjs,cjs,ts}"] },
7791
+ { languageOptions: { globals: globals.browser } },
7792
+ pluginJs.configs.recommended,
7793
+ ...tseslint.configs.recommended,
7794
+ ];
7795
+ `);
7796
+ ensureDir2(path7.join(projectDir, "public"));
7797
+ ensureDir2(path7.join(projectDir, "src/main/web/app"));
7798
+ writeTemplate(projectDir, "src/main/web/index.html", `<!doctype html>
7799
+ <html lang="zh-CN">
7800
+ <head>
7801
+ <meta charset="utf-8">
7802
+ <title>${ctx.projectName}</title>
7803
+ <base href="/">
7804
+ <meta name="viewport" content="width=device-width, initial-scale=1">
7805
+ <link rel="icon" type="image/x-icon" href="favicon.ico">
7806
+ </head>
7807
+ <body>
7808
+ <app-root></app-root>
7809
+ </body>
7810
+ </html>
7811
+ `);
7812
+ writeTemplate(projectDir, "src/main/web/main.ts", `import { bootstrapApplication } from '@angular/platform-browser';
7813
+ import { appConfig } from './app/app.config';
7814
+ import { App } from './app/app';
7815
+
7816
+ bootstrapApplication(App, appConfig).catch((err) => console.error(err));
7817
+ `);
7818
+ const stylesContent = hasTailwind ? `@import "tailwindcss";
7819
+
7820
+ /* \u5168\u5C40\u6837\u5F0F */
7821
+ ` : `/* \u5168\u5C40\u6837\u5F0F */
7822
+ `;
7823
+ writeTemplate(projectDir, "src/main/web/styles.css", stylesContent);
7824
+ writeTemplate(projectDir, "src/main/web/app/app.ts", `import { Component } from '@angular/core';
7825
+ import { RouterOutlet } from '@angular/router';
7826
+
7827
+ @Component({
7828
+ selector: 'app-root',
7829
+ standalone: true,
7830
+ imports: [RouterOutlet],
7831
+ template: \`<router-outlet></router-outlet>\`,
7832
+ })
7833
+ export class App {}
7834
+ `);
7835
+ writeTemplate(projectDir, "src/main/web/app/app.config.ts", `import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
7836
+ import { provideRouter } from '@angular/router';
7837
+ import { routes } from './app.routes';
7838
+
7839
+ export const appConfig: ApplicationConfig = {
7840
+ providers: [
7841
+ provideZoneChangeDetection({ eventCoalescing: true }),
7842
+ provideRouter(routes),
7843
+ ],
7844
+ };
7845
+ `);
7846
+ writeTemplate(projectDir, "src/main/web/app/app.routes.ts", `import { Routes } from '@angular/router';
7847
+
7848
+ export const routes: Routes = [];
7849
+ `);
7850
+ if (hasTailwind) {
7851
+ writeTemplate(projectDir, "postcss.config.json", JSON.stringify({
7852
+ plugins: { "@tailwindcss/postcss": {} }
7853
+ }, null, 2));
7854
+ }
7855
+ }
7856
+ function getAngularStyles(hasPrimeng) {
7857
+ const styles = [];
7858
+ if (hasPrimeng) {
7859
+ styles.push("@primeng/themes/aura/aura.css");
7860
+ }
7861
+ styles.push("src/main/web/styles.css");
7862
+ return styles;
7863
+ }
7864
+ function renderJavaTemplate(projectDir, ctx) {
7865
+ const hasOrm = ctx.orm === "hibernate";
7866
+ const hasLiquibase = ctx.migration === "liquibase";
7867
+ const hasSpringAi = ctx.ai === "spring-ai";
7868
+ writeTemplate(projectDir, "settings.gradle.kts", `rootProject.name = "${ctx.packageName}"
7869
+ `);
7870
+ writeTemplate(projectDir, "gradle.properties", `# Gradle JVM \u53C2\u6570
7871
+ org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
7872
+ # \u5E76\u884C\u6784\u5EFA
7873
+ org.gradle.parallel=true
7874
+ `);
7875
+ const plugins = [
7876
+ "java",
7877
+ "org.springframework.boot",
7878
+ "io.spring.dependency-management"
7879
+ ];
7880
+ const gradleDeps = [
7881
+ 'implementation("org.springframework.boot:spring-boot-starter-web")',
7882
+ 'implementation("org.springframework.boot:spring-boot-starter-validation")',
7883
+ 'compileOnly("org.jetbrains:annotations:26.0.2")'
7884
+ ];
7885
+ if (hasOrm) {
7886
+ gradleDeps.push('implementation("org.springframework.boot:spring-boot-starter-data-jpa")');
7887
+ }
7888
+ if (hasLiquibase) {
7889
+ gradleDeps.unshift('id("org.liquibase.gradle") version "2.2.2"');
7890
+ gradleDeps.push('implementation("org.liquibase:liquibase-core")');
7891
+ }
7892
+ if (hasSpringAi) {
7893
+ gradleDeps.push('implementation("org.springframework.ai:spring-ai-openai-spring-boot-starter")');
7894
+ }
7895
+ const reposExtra = hasSpringAi ? '\n maven { url = uri("https://repo.spring.io/milestone") }' : "";
7896
+ writeTemplate(projectDir, "build.gradle.kts", `plugins {
7897
+ ${plugins.map((p7) => `id("${p7}") version "3.4.0"`).join("\n ")}${hasLiquibase ? `
7898
+ id("org.liquibase.gradle") version "2.2.2"` : ""}
7899
+ }
7900
+
7901
+ group = "${ctx.groupId}"
7902
+ version = "1.0.0-SNAPSHOT"
7903
+ description = "${ctx.projectName}"
7904
+
7905
+ java {
7906
+ toolchain {
7907
+ languageVersion = JavaLanguageVersion.of(21)
7908
+ }
7909
+ }
7910
+
7911
+ repositories {
7912
+ mavenCentral()${reposExtra}
7913
+ }
7914
+
7915
+ dependencies {
7916
+ ${gradleDeps.join("\n ")}
7917
+
7918
+ testImplementation("org.springframework.boot:spring-boot-starter-test")
7919
+ testRuntimeOnly("org.junit.platform:junit-platform-launcher")
7920
+ }
7921
+
7922
+ tasks.withType<Test> {
7923
+ useJUnitPlatform()
7924
+ }
7925
+ `);
7926
+ const appPackage = `${ctx.groupId}.${ctx.packageName}`.replace(/[.-]/g, ".");
7927
+ const appDir = `src/main/java/${appPackage.replace(/\./g, "/")}`;
7928
+ ensureDir2(path7.join(projectDir, appDir));
7929
+ writeTemplate(projectDir, `${appDir}/Application.java`, `package ${appPackage};
7930
+
7931
+ import org.springframework.boot.SpringApplication;
7932
+ import org.springframework.boot.autoconfigure.SpringBootApplication;
7933
+
7934
+ @SpringBootApplication
7935
+ public class Application {
7936
+
7937
+ public static void main(String[] args) {
7938
+ SpringApplication.run(Application.class, args);
7939
+ }
7940
+ }
7941
+ `);
7942
+ const controllerDir = `${appDir}/controller`;
7943
+ ensureDir2(path7.join(projectDir, controllerDir));
7944
+ writeTemplate(projectDir, `${controllerDir}/HealthController.java`, `package ${appPackage}.controller;
7945
+
7946
+ import org.springframework.web.bind.annotation.GetMapping;
7947
+ import org.springframework.web.bind.annotation.RestController;
7948
+
7949
+ @RestController
7950
+ public class HealthController {
7951
+
7952
+ @GetMapping("/api/health")
7953
+ public String health() {
7954
+ return "OK";
7955
+ }
7956
+ }
7957
+ `);
7958
+ const serviceDir = `${appDir}/service`;
7959
+ ensureDir2(path7.join(projectDir, serviceDir));
7960
+ if (hasOrm) {
7961
+ const repositoryDir = `${appDir}/repository`;
7962
+ ensureDir2(path7.join(projectDir, repositoryDir));
7963
+ const entityDir = `${appDir}/entity`;
7964
+ ensureDir2(path7.join(projectDir, entityDir));
7965
+ writeTemplate(projectDir, `${entityDir}/BaseEntity.java`, `package ${appPackage}.entity;
7966
+
7967
+ import jakarta.persistence.GeneratedValue;
7968
+ import jakarta.persistence.GenerationType;
7969
+ import jakarta.persistence.Id;
7970
+ import jakarta.persistence.MappedSuperclass;
7971
+ import java.time.LocalDateTime;
7972
+
7973
+ @MappedSuperclass
7974
+ public abstract class BaseEntity {
7975
+
7976
+ @Id
7977
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
7978
+ private Long id;
7979
+
7980
+ private LocalDateTime createdAt;
7981
+ private LocalDateTime updatedAt;
7982
+
7983
+ public Long getId() { return id; }
7984
+ public void setId(Long id) { this.id = id; }
7985
+ public LocalDateTime getCreatedAt() { return createdAt; }
7986
+ public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; }
7987
+ public LocalDateTime getUpdatedAt() { return updatedAt; }
7988
+ public void setUpdatedAt(LocalDateTime updatedAt) { this.updatedAt = updatedAt; }
7989
+ }
7990
+ `);
7991
+ }
7992
+ ensureDir2(path7.join(projectDir, "src/main/resources"));
7993
+ const datasourceConfig = hasOrm ? `
7994
+ spring:
7995
+ datasource:
7996
+ url: jdbc:h2:mem:${ctx.packageName}
7997
+ driver-class-name: org.h2.Driver
7998
+ username: sa
7999
+ password:
8000
+ jpa:
8001
+ hibernate:
8002
+ ddl-auto: create-drop
8003
+ show-sql: false
8004
+ properties:
8005
+ hibernate:
8006
+ format_sql: true
8007
+ ` : "";
8008
+ const liquibaseConfig = hasLiquibase ? `
8009
+ liquibase:
8010
+ change-log: classpath:db/changelog/db.changelog-master.xml
8011
+ ` : "";
8012
+ writeTemplate(projectDir, "src/main/resources/application.yml", `server:
8013
+ port: 8080
8014
+ ${datasourceConfig}${liquibaseConfig}
8015
+ logging:
8016
+ level:
8017
+ root: INFO
8018
+ ${ctx.packageName}: DEBUG
8019
+ `);
8020
+ if (hasLiquibase) {
8021
+ ensureDir2(path7.join(projectDir, "src/main/resources/db/changelog"));
8022
+ writeTemplate(projectDir, "src/main/resources/db/changelog/db.changelog-master.xml", `<?xml version="1.0" encoding="UTF-8"?>
8023
+ <databaseChangeLog
8024
+ xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
8025
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
8026
+ xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
8027
+ http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
8028
+
8029
+ <changeSet id="001" author="deepstorm">
8030
+ <createTable tableName="flyway_schema_history">
8031
+ <column name="version" type="VARCHAR(50)"/>
8032
+ </createTable>
8033
+ </changeSet>
8034
+ </databaseChangeLog>
8035
+ `);
8036
+ }
8037
+ const testDir = `src/test/java/${appPackage.replace(/\./g, "/")}`;
8038
+ ensureDir2(path7.join(projectDir, testDir));
8039
+ ensureDir2(path7.join(projectDir, "src/test/resources"));
8040
+ writeTemplate(projectDir, `${testDir}/ApplicationTests.java`, `package ${appPackage};
8041
+
8042
+ import org.junit.jupiter.api.Test;
8043
+ import org.springframework.boot.test.context.SpringBootTest;
8044
+
8045
+ @SpringBootTest
8046
+ class ApplicationTests {
8047
+
8048
+ @Test
8049
+ void contextLoads() {
8050
+ }
8051
+ }
8052
+ `);
8053
+ writeTemplate(projectDir, "src/test/resources/junit-platform.properties", `junit.jupiter.testinstance.lifecycle.default = per_class
8054
+ `);
8055
+ ensureDir2(path7.join(projectDir, "gradle/wrapper"));
8056
+ writeTemplate(projectDir, "gradle/wrapper/gradle-wrapper.properties", `distributionBase=GRADLE_USER_HOME
8057
+ distributionPath=wrapper/dists
8058
+ distributionUrl=https\\://services.gradle.org/distributions/gradle-8.12-bin.zip
8059
+ networkTimeout=10000
8060
+ validateDistributionUrl=true
8061
+ zipStoreBase=GRADLE_USER_HOME
8062
+ zipStorePath=wrapper/dists
8063
+ `);
8064
+ writeTemplate(projectDir, "gradlew", `#!/bin/sh
8065
+
8066
+ #
8067
+ # Gradle start up script for POSIX generated by Gradle.
8068
+ #
8069
+
8070
+ # Attempt to set APP_HOME
8071
+ PRG="$0"
8072
+ while [ -h "$PRG" ] ; do
8073
+ ls=$(ls -ld "$PRG")
8074
+ link=$(expr "$ls" : '.*-> \\(.*\\)$')
8075
+ if expr "$link" : '/.*' > /dev/null; then
8076
+ PRG="$link"
8077
+ else
8078
+ PRG=$(dirname "$PRG")/"$link"
8079
+ fi
8080
+ done
8081
+ SAVED="$(pwd)"
8082
+ cd "$(dirname "$PRG")/" >/dev/null
8083
+ APP_HOME="$(pwd -P)"
8084
+ cd "$SAVED" >/dev/null
8085
+
8086
+ APP_NAME="Gradle"
8087
+ APP_BASE_NAME=$(basename "$0")
8088
+
8089
+ MAX_FD="maximum"
8090
+
8091
+ warn () {
8092
+ echo "$*"
8093
+ } >&2
8094
+
8095
+ die () {
8096
+ echo
8097
+ echo "$*"
8098
+ echo
8099
+ exit 1
8100
+ } >&2
8101
+
8102
+ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
8103
+
8104
+ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
8105
+
8106
+ # Determine the Java command to use to start the JVM.
8107
+ if [ -n "$JAVA_HOME" ] ; then
8108
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
8109
+ JAVACMD="$JAVA_HOME/jre/sh/java"
8110
+ else
8111
+ JAVACMD="$JAVA_HOME/bin/java"
8112
+ fi
8113
+ if [ ! -x "$JAVACMD" ] ; then
8114
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME"
8115
+ fi
8116
+ else
8117
+ JAVACMD="java"
8118
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH."
8119
+ fi
8120
+
8121
+ exec "$JAVACMD" $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
8122
+ `);
8123
+ writeTemplate(projectDir, "gradlew.bat", `@rem
8124
+ @rem Gradle startup script for Windows
8125
+ @rem
8126
+ @if "%DEBUG%"=="" @echo off
8127
+ @rem Set local scope for the variables
8128
+ setlocal enabledelayedexpansion
8129
+ set APP_BASE_NAME=%~n0
8130
+ set APP_HOME=%CD%
8131
+ set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
8132
+ set CLASSPATH=%APP_HOME%/gradle/wrapper/gradle-wrapper.jar
8133
+ "%JAVA_HOME%/bin/java.exe" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
8134
+ :end
8135
+ @endlocal & exit /b %ERRORLEVEL%
8136
+ `);
8137
+ }
8138
+ function renderCommonFiles(projectDir, ctx) {
8139
+ writeTemplate(projectDir, ".gitignore", `node_modules/
8140
+ .gradle/
8141
+ build/
8142
+ target/
8143
+ dist/
8144
+ .env
8145
+ *.log
8146
+ .DS_Store
8147
+ __pycache__/
8148
+ *.pyc
8149
+ .idea/
8150
+ .vscode/
8151
+ *.iml
8152
+ `);
8153
+ writeTemplate(projectDir, ".env.example", `# \u6570\u636E\u5E93\u914D\u7F6E
8154
+ DB_URL=jdbc:postgresql://localhost:5432/${ctx.packageName}
8155
+ DB_USERNAME=postgres
8156
+ DB_PASSWORD=change-me
8157
+
8158
+ # API Keys
8159
+ OPENAI_API_KEY=sk-your-key-here
8160
+ `);
8161
+ const readme = generateReadme(ctx);
8162
+ writeTemplate(projectDir, "README.md", readme);
8163
+ }
8164
+ function generateReadme(ctx) {
8165
+ const lines = [];
8166
+ lines.push(`# ${ctx.projectName}`, "");
8167
+ lines.push("## \u6280\u672F\u6808", "");
8168
+ if (ctx.frontend) lines.push("- **\u524D\u7AEF\uFF1A** Angular + TypeScript");
8169
+ if (ctx.backend) lines.push("- **\u540E\u7AEF\uFF1A** Java 21 + Spring Boot 3.x + Gradle");
8170
+ lines.push("");
8171
+ lines.push("## \u5FEB\u901F\u5F00\u59CB", "");
8172
+ if (ctx.frontend) {
8173
+ lines.push("### \u524D\u7AEF", "");
8174
+ lines.push("```bash");
8175
+ lines.push("pnpm install");
8176
+ lines.push("pnpm start");
8177
+ lines.push("```", "");
8178
+ }
8179
+ if (ctx.backend) {
8180
+ lines.push("### \u540E\u7AEF", "");
8181
+ lines.push("```bash");
8182
+ lines.push("./gradlew build");
8183
+ lines.push("./gradlew bootRun");
8184
+ lines.push("```", "");
8185
+ }
8186
+ lines.push("## \u9879\u76EE\u7ED3\u6784", "");
8187
+ lines.push("```");
8188
+ if (ctx.frontend && ctx.backend) {
8189
+ lines.push("\u251C\u2500\u2500 src/main/web/ # Angular \u524D\u7AEF");
8190
+ lines.push("\u251C\u2500\u2500 src/main/java/ # Java \u540E\u7AEF");
8191
+ lines.push("\u251C\u2500\u2500 src/main/resources/ # \u914D\u7F6E");
8192
+ lines.push("\u251C\u2500\u2500 build.gradle.kts # Gradle \u6784\u5EFA");
8193
+ lines.push("\u2514\u2500\u2500 angular.json # Angular \u914D\u7F6E");
8194
+ } else if (ctx.frontend) {
8195
+ lines.push("\u251C\u2500\u2500 src/main/web/ # Angular \u524D\u7AEF");
8196
+ lines.push("\u2514\u2500\u2500 angular.json # Angular \u914D\u7F6E");
8197
+ } else if (ctx.backend) {
8198
+ lines.push("\u251C\u2500\u2500 src/main/java/ # Java \u540E\u7AEF");
8199
+ lines.push("\u2514\u2500\u2500 build.gradle.kts # Gradle \u6784\u5EFA");
8200
+ }
8201
+ lines.push("```", "");
8202
+ return lines.join("\n");
8203
+ }
8204
+ function ensureDir2(dir) {
8205
+ if (!fs11.existsSync(dir)) {
8206
+ fs11.mkdirSync(dir, { recursive: true });
8207
+ }
8208
+ }
8209
+ function writeTemplate(baseDir, relativePath, content) {
8210
+ const fullPath = path7.join(baseDir, relativePath);
8211
+ ensureDir2(path7.dirname(fullPath));
8212
+ fs11.writeFileSync(fullPath, content, "utf-8");
8213
+ }
8214
+ function printProjectTree(projectDir, hasFrontend, hasBackend) {
8215
+ console.log("\u76EE\u5F55\u7ED3\u6784:");
8216
+ console.log(` ${path7.basename(projectDir)}/`);
8217
+ if (hasFrontend && hasBackend) {
8218
+ console.log(" \u251C\u2500\u2500 src/");
8219
+ console.log(" \u2502 \u251C\u2500\u2500 main/");
8220
+ console.log(" \u2502 \u2502 \u251C\u2500\u2500 web/ # Angular \u524D\u7AEF");
8221
+ console.log(" \u2502 \u2502 \u251C\u2500\u2500 java/ # Java \u540E\u7AEF");
8222
+ console.log(" \u2502 \u2502 \u2514\u2500\u2500 resources/ # \u914D\u7F6E");
8223
+ console.log(" \u2502 \u2514\u2500\u2500 test/");
8224
+ console.log(" \u2502 \u251C\u2500\u2500 java/");
8225
+ console.log(" \u2502 \u2514\u2500\u2500 resources/");
8226
+ console.log(" \u251C\u2500\u2500 build.gradle.kts");
8227
+ console.log(" \u251C\u2500\u2500 angular.json");
8228
+ console.log(" \u2514\u2500\u2500 package.json");
8229
+ } else if (hasFrontend) {
8230
+ console.log(" \u251C\u2500\u2500 src/main/web/ # Angular \u524D\u7AEF");
8231
+ console.log(" \u251C\u2500\u2500 angular.json");
8232
+ console.log(" \u2514\u2500\u2500 package.json");
8233
+ } else if (hasBackend) {
8234
+ console.log(" \u251C\u2500\u2500 src/");
8235
+ console.log(" \u2502 \u251C\u2500\u2500 main/java/");
8236
+ console.log(" \u2502 \u251C\u2500\u2500 main/resources/");
8237
+ console.log(" \u2502 \u251C\u2500\u2500 test/java/");
8238
+ console.log(" \u2502 \u2514\u2500\u2500 test/resources/");
8239
+ console.log(" \u251C\u2500\u2500 build.gradle.kts");
8240
+ console.log(" \u2514\u2500\u2500 settings.gradle.kts");
8241
+ }
8242
+ }
8243
+
7452
8244
  // src/commands/plugin-build.ts
7453
- var fs12 = __toESM(require("node:fs"));
7454
- var path8 = __toESM(require("node:path"));
8245
+ var fs13 = __toESM(require("node:fs"));
8246
+ var path9 = __toESM(require("node:path"));
7455
8247
 
7456
8248
  // src/engine/plugin-builder.ts
7457
- var fs11 = __toESM(require("node:fs"));
7458
- var path7 = __toESM(require("node:path"));
8249
+ var fs12 = __toESM(require("node:fs"));
8250
+ var path8 = __toESM(require("node:path"));
7459
8251
  async function buildPlugin(config) {
7460
8252
  const { marketplaceName, tools, selectedMcpTools, cliDir: cliDir2, targetDir } = config;
7461
- const outputDir = path7.join(targetDir, ".deepstorm");
7462
- if (fs11.existsSync(outputDir)) {
7463
- fs11.rmSync(outputDir, { recursive: true, force: true });
8253
+ const outputDir = path8.join(targetDir, ".deepstorm");
8254
+ if (fs12.existsSync(outputDir)) {
8255
+ fs12.rmSync(outputDir, { recursive: true, force: true });
7464
8256
  }
7465
- fs11.mkdirSync(outputDir, { recursive: true });
8257
+ fs12.mkdirSync(outputDir, { recursive: true });
7466
8258
  const rootPkgMeta = readRootPackageJson(targetDir);
7467
- const claudePluginDir = path7.join(outputDir, ".claude-plugin");
7468
- fs11.mkdirSync(claudePluginDir, { recursive: true });
8259
+ const claudePluginDir = path8.join(outputDir, ".claude-plugin");
8260
+ fs12.mkdirSync(claudePluginDir, { recursive: true });
7469
8261
  const pluginJson = {
7470
8262
  name: "deepstorm",
7471
8263
  description: rootPkgMeta.description,
@@ -7474,7 +8266,7 @@ async function buildPlugin(config) {
7474
8266
  license: "MIT",
7475
8267
  keywords: ["deepstorm", "ai", "software-engineering", ...tools]
7476
8268
  };
7477
- fs11.writeFileSync(path7.join(claudePluginDir, "plugin.json"), JSON.stringify(pluginJson, null, 2), "utf-8");
8269
+ fs12.writeFileSync(path8.join(claudePluginDir, "plugin.json"), JSON.stringify(pluginJson, null, 2), "utf-8");
7478
8270
  const marketplaceJson = {
7479
8271
  name: marketplaceName,
7480
8272
  description: "DeepStorm Claude Code \u63D2\u4EF6",
@@ -7488,11 +8280,11 @@ async function buildPlugin(config) {
7488
8280
  }
7489
8281
  ]
7490
8282
  };
7491
- fs11.writeFileSync(path7.join(claudePluginDir, "marketplace.json"), JSON.stringify(marketplaceJson, null, 2), "utf-8");
8283
+ fs12.writeFileSync(path8.join(claudePluginDir, "marketplace.json"), JSON.stringify(marketplaceJson, null, 2), "utf-8");
7492
8284
  const settingsJson = {
7493
8285
  enabledMcpjsonServers: selectedMcpTools
7494
8286
  };
7495
- fs11.writeFileSync(path7.join(outputDir, "settings.json"), JSON.stringify(settingsJson, null, 2), "utf-8");
8287
+ fs12.writeFileSync(path8.join(outputDir, "settings.json"), JSON.stringify(settingsJson, null, 2), "utf-8");
7496
8288
  if (selectedMcpTools.length > 0) {
7497
8289
  const mcpServers = {};
7498
8290
  for (const mcpName of selectedMcpTools) {
@@ -7502,46 +8294,46 @@ async function buildPlugin(config) {
7502
8294
  }
7503
8295
  }
7504
8296
  if (Object.keys(mcpServers).length > 0) {
7505
- fs11.writeFileSync(
7506
- path7.join(outputDir, ".mcp.json"),
8297
+ fs12.writeFileSync(
8298
+ path8.join(outputDir, ".mcp.json"),
7507
8299
  JSON.stringify({ mcpServers }, null, 2) + "\n",
7508
8300
  "utf-8"
7509
8301
  );
7510
8302
  }
7511
8303
  }
7512
8304
  if (selectedMcpTools.length > 0) {
7513
- const envPath = path7.join(outputDir, ".env.example");
8305
+ const envPath = path8.join(outputDir, ".env.example");
7514
8306
  const envLines = [
7515
8307
  "# DeepStorm Plugin MCP \u73AF\u5883\u53D8\u91CF\u914D\u7F6E",
7516
8308
  "# \u590D\u5236\u6B64\u6587\u4EF6\u4E3A .env \u5E76\u586B\u5199\u5B9E\u9645\u503C",
7517
8309
  ""
7518
8310
  ];
7519
8311
  for (const mcpName of selectedMcpTools) {
7520
- const envExampleFile = path7.join(cliDir2, "env-examples", `${mcpName}.env-example`);
7521
- if (fs11.existsSync(envExampleFile)) {
7522
- const content = fs11.readFileSync(envExampleFile, "utf-8");
8312
+ const envExampleFile = path8.join(cliDir2, "env-examples", `${mcpName}.env-example`);
8313
+ if (fs12.existsSync(envExampleFile)) {
8314
+ const content = fs12.readFileSync(envExampleFile, "utf-8");
7523
8315
  envLines.push(`# ${mcpName}`);
7524
8316
  envLines.push(content);
7525
8317
  envLines.push("");
7526
8318
  }
7527
8319
  }
7528
- fs11.writeFileSync(envPath, envLines.join("\n"), "utf-8");
8320
+ fs12.writeFileSync(envPath, envLines.join("\n"), "utf-8");
7529
8321
  }
7530
- const readmeContent = generateReadme(marketplaceName, tools, selectedMcpTools, rootPkgMeta.version);
7531
- fs11.writeFileSync(path7.join(outputDir, "README.md"), readmeContent, "utf-8");
8322
+ const readmeContent = generateReadme2(marketplaceName, tools, selectedMcpTools, rootPkgMeta.version);
8323
+ fs12.writeFileSync(path8.join(outputDir, "README.md"), readmeContent, "utf-8");
7532
8324
  const changelogContent = `# Changelog
7533
8325
 
7534
8326
  ## v${rootPkgMeta.version}
7535
8327
 
7536
8328
  - \u9996\u6B21\u6784\u5EFA DeepStorm Plugin
7537
8329
  `;
7538
- fs11.writeFileSync(path7.join(outputDir, "CHANGELOG.md"), changelogContent, "utf-8");
8330
+ fs12.writeFileSync(path8.join(outputDir, "CHANGELOG.md"), changelogContent, "utf-8");
7539
8331
  return outputDir;
7540
8332
  }
7541
8333
  function readRootPackageJson(targetDir) {
7542
- const pkgPath = path7.join(targetDir, "package.json");
8334
+ const pkgPath = path8.join(targetDir, "package.json");
7543
8335
  try {
7544
- const pkg = JSON.parse(fs11.readFileSync(pkgPath, "utf-8"));
8336
+ const pkg = JSON.parse(fs12.readFileSync(pkgPath, "utf-8"));
7545
8337
  return {
7546
8338
  version: pkg.version || "0.1.0",
7547
8339
  description: pkg.description || "DeepStorm \u2014 Spec \u9A71\u52A8\u7684 AI \u534F\u540C\u8F6F\u4EF6\u5DE5\u7A0B\u5B9E\u8DF5\u5DE5\u5177\u96C6"
@@ -7553,7 +8345,7 @@ function readRootPackageJson(targetDir) {
7553
8345
  };
7554
8346
  }
7555
8347
  }
7556
- function generateReadme(marketplaceName, tools, selectedMcpTools, version) {
8348
+ function generateReadme2(marketplaceName, tools, selectedMcpTools, version) {
7557
8349
  const lines = [
7558
8350
  `# DeepStorm Plugin (${marketplaceName})`,
7559
8351
  "",
@@ -7593,16 +8385,16 @@ function generateReadme(marketplaceName, tools, selectedMcpTools, version) {
7593
8385
  return lines.join("\n");
7594
8386
  }
7595
8387
  function readMcpServerConfig(cliDir2, mcpName) {
7596
- const mcpDir = path7.join(cliDir2, "mcp");
7597
- if (!fs11.existsSync(mcpDir)) return null;
7598
- const entries = fs11.readdirSync(mcpDir, { withFileTypes: true });
8388
+ const mcpDir = path8.join(cliDir2, "mcp");
8389
+ if (!fs12.existsSync(mcpDir)) return null;
8390
+ const entries = fs12.readdirSync(mcpDir, { withFileTypes: true });
7599
8391
  for (const entry of entries) {
7600
8392
  if (!entry.isDirectory()) continue;
7601
- const domainDir = path7.join(mcpDir, entry.name);
7602
- const files = fs11.readdirSync(domainDir).filter((f) => f.endsWith(".json"));
8393
+ const domainDir = path8.join(mcpDir, entry.name);
8394
+ const files = fs12.readdirSync(domainDir).filter((f) => f.endsWith(".json"));
7603
8395
  for (const file of files) {
7604
8396
  try {
7605
- const content = JSON.parse(fs11.readFileSync(path7.join(domainDir, file), "utf-8"));
8397
+ const content = JSON.parse(fs12.readFileSync(path8.join(domainDir, file), "utf-8"));
7606
8398
  if (content.name === mcpName && content.mcpServers) {
7607
8399
  const servers = content.mcpServers;
7608
8400
  const keys = Object.keys(servers);
@@ -7698,27 +8490,27 @@ function registerPluginBuildCommand(program2, registry2) {
7698
8490
  });
7699
8491
  }
7700
8492
  function updatePluginJsonHooks(pluginDir) {
7701
- const hooksDir = path8.join(pluginDir, "hooks");
7702
- const pluginJsonPath = path8.join(pluginDir, ".claude-plugin", "plugin.json");
7703
- if (!fs12.existsSync(hooksDir) || !fs12.existsSync(pluginJsonPath)) return;
8493
+ const hooksDir = path9.join(pluginDir, "hooks");
8494
+ const pluginJsonPath = path9.join(pluginDir, ".claude-plugin", "plugin.json");
8495
+ if (!fs13.existsSync(hooksDir) || !fs13.existsSync(pluginJsonPath)) return;
7704
8496
  try {
7705
- const pluginJson = JSON.parse(fs12.readFileSync(pluginJsonPath, "utf-8"));
8497
+ const pluginJson = JSON.parse(fs13.readFileSync(pluginJsonPath, "utf-8"));
7706
8498
  pluginJson.hooks = "./hooks/deepstorm-hooks.json";
7707
- fs12.writeFileSync(pluginJsonPath, JSON.stringify(pluginJson, null, 2) + "\n", "utf-8");
8499
+ fs13.writeFileSync(pluginJsonPath, JSON.stringify(pluginJson, null, 2) + "\n", "utf-8");
7708
8500
  console.log("\u2714 plugin.json \u5DF2\u6DFB\u52A0 hooks \u58F0\u660E");
7709
8501
  } catch {
7710
8502
  }
7711
8503
  }
7712
8504
  function ensureGitIgnore(targetDir) {
7713
- const gitIgnorePath = path8.join(targetDir, ".gitignore");
8505
+ const gitIgnorePath = path9.join(targetDir, ".gitignore");
7714
8506
  const line = ".deepstorm/";
7715
8507
  try {
7716
- if (fs12.existsSync(gitIgnorePath)) {
7717
- const content = fs12.readFileSync(gitIgnorePath, "utf-8");
8508
+ if (fs13.existsSync(gitIgnorePath)) {
8509
+ const content = fs13.readFileSync(gitIgnorePath, "utf-8");
7718
8510
  if (content.includes(line)) return;
7719
- fs12.writeFileSync(gitIgnorePath, content.trimEnd() + "\n" + line + "\n", "utf-8");
8511
+ fs13.writeFileSync(gitIgnorePath, content.trimEnd() + "\n" + line + "\n", "utf-8");
7720
8512
  } else {
7721
- fs12.writeFileSync(gitIgnorePath, line + "\n", "utf-8");
8513
+ fs13.writeFileSync(gitIgnorePath, line + "\n", "utf-8");
7722
8514
  }
7723
8515
  console.log("\u2714 .gitignore \u5DF2\u6DFB\u52A0 .deepstorm/ \u5FFD\u7565\u89C4\u5219");
7724
8516
  } catch {
@@ -7726,27 +8518,27 @@ function ensureGitIgnore(targetDir) {
7726
8518
  }
7727
8519
  function mergePluginHooks(tools, reader, pluginDir, packagesDir) {
7728
8520
  if (!tools.some((tool) => reader.getToolHooks(tool).length > 0)) return;
7729
- const pkgsDir = packagesDir ?? path8.resolve(process.cwd(), "packages");
7730
- const pluginHooksDir = path8.join(pluginDir, "hooks");
7731
- const destHooksJson = path8.join(pluginHooksDir, "deepstorm-hooks.json");
8521
+ const pkgsDir = packagesDir ?? path9.resolve(process.cwd(), "packages");
8522
+ const pluginHooksDir = path9.join(pluginDir, "hooks");
8523
+ const destHooksJson = path9.join(pluginHooksDir, "deepstorm-hooks.json");
7732
8524
  for (const tool of tools) {
7733
- const srcPath = path8.join(pkgsDir, tool, "hooks", "hooks.json");
7734
- if (fs12.existsSync(srcPath)) {
7735
- fs12.mkdirSync(pluginHooksDir, { recursive: true });
7736
- const incoming = JSON.parse(fs12.readFileSync(srcPath, "utf-8"));
8525
+ const srcPath = path9.join(pkgsDir, tool, "hooks", "hooks.json");
8526
+ if (fs13.existsSync(srcPath)) {
8527
+ fs13.mkdirSync(pluginHooksDir, { recursive: true });
8528
+ const incoming = JSON.parse(fs13.readFileSync(srcPath, "utf-8"));
7737
8529
  mergeHooks(destHooksJson, incoming);
7738
8530
  }
7739
8531
  }
7740
8532
  }
7741
8533
 
7742
8534
  // src/commands/config.ts
7743
- var path14 = __toESM(require("node:path"));
8535
+ var path15 = __toESM(require("node:path"));
7744
8536
  var import_prompts2 = require("@clack/prompts");
7745
8537
 
7746
8538
  // src/commands/config-view.ts
7747
- var path9 = __toESM(require("node:path"));
8539
+ var path10 = __toESM(require("node:path"));
7748
8540
  function viewConfig(targetDir) {
7749
- const settingsPath = path9.join(targetDir, ".claude", "settings.json");
8541
+ const settingsPath = path10.join(targetDir, ".claude", "settings.json");
7750
8542
  const deepstorm = readDeepStormConfig(settingsPath);
7751
8543
  if (!deepstorm) {
7752
8544
  console.log("\u5C1A\u672A\u914D\u7F6E DeepStorm\uFF0C\u8BF7\u8FD0\u884C deepstorm setup");
@@ -7757,24 +8549,24 @@ function viewConfig(targetDir) {
7757
8549
  }
7758
8550
 
7759
8551
  // src/commands/config-set.ts
7760
- var fs14 = __toESM(require("node:fs"));
7761
- var path11 = __toESM(require("node:path"));
8552
+ var fs15 = __toESM(require("node:fs"));
8553
+ var path12 = __toESM(require("node:path"));
7762
8554
  var p6 = __toESM(require("@clack/prompts"));
7763
8555
 
7764
8556
  // src/utils/config-schema.ts
7765
- var fs13 = __toESM(require("node:fs"));
7766
- var path10 = __toESM(require("node:path"));
8557
+ var fs14 = __toESM(require("node:fs"));
8558
+ var path11 = __toESM(require("node:path"));
7767
8559
  function loadValidConfigKeys() {
7768
8560
  const candidates = [
7769
- path10.resolve(__dirname, "config-schema.json"),
7770
- path10.resolve(__dirname, "..", "config-schema.json"),
7771
- path10.resolve(process.cwd(), "config-schema.json"),
7772
- path10.resolve(process.cwd(), "packages", "cli", "config-schema.json")
8561
+ path11.resolve(__dirname, "config-schema.json"),
8562
+ path11.resolve(__dirname, "..", "config-schema.json"),
8563
+ path11.resolve(process.cwd(), "config-schema.json"),
8564
+ path11.resolve(process.cwd(), "packages", "cli", "config-schema.json")
7773
8565
  ];
7774
8566
  for (const schemaPath of candidates) {
7775
8567
  try {
7776
- if (!fs13.existsSync(schemaPath)) continue;
7777
- const schema = JSON.parse(fs13.readFileSync(schemaPath, "utf-8"));
8568
+ if (!fs14.existsSync(schemaPath)) continue;
8569
+ const schema = JSON.parse(fs14.readFileSync(schemaPath, "utf-8"));
7778
8570
  const keys = /* @__PURE__ */ new Set();
7779
8571
  collectLeafPaths(schema.properties, "", keys);
7780
8572
  return keys;
@@ -7809,12 +8601,12 @@ async function setConfigValue(targetDir, key, value, registry2) {
7809
8601
  if (!validateConfigKey(key)) {
7810
8602
  return;
7811
8603
  }
7812
- const settingsPath = path11.join(targetDir, ".claude", "settings.json");
8604
+ const settingsPath = path12.join(targetDir, ".claude", "settings.json");
7813
8605
  readDeepStormConfig(settingsPath);
7814
8606
  let settings = {};
7815
- if (fs14.existsSync(settingsPath)) {
8607
+ if (fs15.existsSync(settingsPath)) {
7816
8608
  try {
7817
- settings = JSON.parse(fs14.readFileSync(settingsPath, "utf-8"));
8609
+ settings = JSON.parse(fs15.readFileSync(settingsPath, "utf-8"));
7818
8610
  } catch {
7819
8611
  settings = {};
7820
8612
  }
@@ -7852,7 +8644,7 @@ async function setConfigValue(targetDir, key, value, registry2) {
7852
8644
  writePointer = writePointer[parts[i]];
7853
8645
  }
7854
8646
  writePointer[parts[parts.length - 1]] = value;
7855
- fs14.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf-8");
8647
+ fs15.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf-8");
7856
8648
  console.log(`\u2714 ${key} \u5DF2\u66F4\u65B0\u4E3A ${value}`);
7857
8649
  const affected = findAffectedTemplates(registry2, key);
7858
8650
  if (affected.length === 0) {
@@ -7890,8 +8682,8 @@ async function setConfigValue(targetDir, key, value, registry2) {
7890
8682
  const templateVariables = buildTemplateVariables(registry2, fullConfig, installedMcpServers);
7891
8683
  let renderCount = 0;
7892
8684
  for (const tmplRelPath of affected) {
7893
- const tmplPath = path11.join(cliDir, tmplRelPath);
7894
- if (!fs14.existsSync(tmplPath)) {
8685
+ const tmplPath = path12.join(cliDir, tmplRelPath);
8686
+ if (!fs15.existsSync(tmplPath)) {
7895
8687
  console.warn(` \u26A0 \u6A21\u677F\u6587\u4EF6\u4E0D\u5B58\u5728: ${tmplRelPath}\uFF0C\u8DF3\u8FC7`);
7896
8688
  continue;
7897
8689
  }
@@ -7899,12 +8691,12 @@ async function setConfigValue(targetDir, key, value, registry2) {
7899
8691
  const assetType = pathParts[0];
7900
8692
  const assetName = pathParts[1];
7901
8693
  const outputFile = pathParts[pathParts.length - 1].replace(/\.tmpl$/, "");
7902
- const targetDirPath = path11.join(targetDir, ".claude", assetType, assetName);
8694
+ const targetDirPath = path12.join(targetDir, ".claude", assetType, assetName);
7903
8695
  ensureDir(targetDirPath);
7904
- const outputPath = path11.join(targetDirPath, outputFile);
8696
+ const outputPath = path12.join(targetDirPath, outputFile);
7905
8697
  renderTemplate(tmplPath, templateVariables, outputPath);
7906
- const variantsDir = path11.join(cliDir, assetType, assetName, "variants");
7907
- if (fs14.existsSync(variantsDir)) {
8698
+ const variantsDir = path12.join(cliDir, assetType, assetName, "variants");
8699
+ if (fs15.existsSync(variantsDir)) {
7908
8700
  copyVariants(variantsDir, value, targetDirPath, true);
7909
8701
  }
7910
8702
  renderCount++;
@@ -7914,33 +8706,33 @@ async function setConfigValue(targetDir, key, value, registry2) {
7914
8706
  }
7915
8707
 
7916
8708
  // src/commands/config-reset.ts
7917
- var fs15 = __toESM(require("node:fs"));
7918
- var path12 = __toESM(require("node:path"));
8709
+ var fs16 = __toESM(require("node:fs"));
8710
+ var path13 = __toESM(require("node:path"));
7919
8711
  function resetConfig(targetDir) {
7920
- const settingsPath = path12.join(targetDir, ".claude", "settings.json");
7921
- if (!fs15.existsSync(settingsPath)) return;
8712
+ const settingsPath = path13.join(targetDir, ".claude", "settings.json");
8713
+ if (!fs16.existsSync(settingsPath)) return;
7922
8714
  try {
7923
- const settings = JSON.parse(fs15.readFileSync(settingsPath, "utf-8"));
8715
+ const settings = JSON.parse(fs16.readFileSync(settingsPath, "utf-8"));
7924
8716
  if (!settings.deepstorm) return;
7925
8717
  delete settings.deepstorm;
7926
- fs15.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf-8");
8718
+ fs16.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf-8");
7927
8719
  } catch {
7928
8720
  }
7929
8721
  }
7930
8722
 
7931
8723
  // src/commands/config-refresh.ts
7932
- var fs16 = __toESM(require("node:fs"));
7933
- var path13 = __toESM(require("node:path"));
8724
+ var fs17 = __toESM(require("node:fs"));
8725
+ var path14 = __toESM(require("node:path"));
7934
8726
  function refreshConfig(cliDir2, targetDotClaudeDir, registry2) {
7935
8727
  const result = { refreshed: [], errors: [] };
7936
- const settingsPath = path13.join(targetDotClaudeDir, "settings.json");
7937
- if (!fs16.existsSync(settingsPath)) {
8728
+ const settingsPath = path14.join(targetDotClaudeDir, "settings.json");
8729
+ if (!fs17.existsSync(settingsPath)) {
7938
8730
  return result;
7939
8731
  }
7940
8732
  readDeepStormConfig(settingsPath);
7941
8733
  let settings;
7942
8734
  try {
7943
- settings = JSON.parse(fs16.readFileSync(settingsPath, "utf-8"));
8735
+ settings = JSON.parse(fs17.readFileSync(settingsPath, "utf-8"));
7944
8736
  } catch {
7945
8737
  return result;
7946
8738
  }
@@ -7950,10 +8742,10 @@ function refreshConfig(cliDir2, targetDotClaudeDir, registry2) {
7950
8742
  const installedMcpServers = deepstorm.installedMcpServers ?? [];
7951
8743
  if (installedSkills.length === 0) return result;
7952
8744
  for (const skillId of installedSkills) {
7953
- const tmplPath = path13.join(cliDir2, "skills", skillId, "SKILL.md.tmpl");
7954
- if (!fs16.existsSync(tmplPath)) continue;
7955
- const targetSkillDir = path13.join(targetDotClaudeDir, "skills", skillId);
7956
- const outputPath = path13.join(targetSkillDir, "SKILL.md");
8745
+ const tmplPath = path14.join(cliDir2, "skills", skillId, "SKILL.md.tmpl");
8746
+ if (!fs17.existsSync(tmplPath)) continue;
8747
+ const targetSkillDir = path14.join(targetDotClaudeDir, "skills", skillId);
8748
+ const outputPath = path14.join(targetSkillDir, "SKILL.md");
7957
8749
  try {
7958
8750
  const enrichedVars = injectSkillCapabilities(
7959
8751
  tmplPath,
@@ -7961,7 +8753,7 @@ function refreshConfig(cliDir2, targetDotClaudeDir, registry2) {
7961
8753
  installedMcpServers,
7962
8754
  registry2.mcpTools ?? {}
7963
8755
  );
7964
- fs16.mkdirSync(targetSkillDir, { recursive: true });
8756
+ fs17.mkdirSync(targetSkillDir, { recursive: true });
7965
8757
  renderTemplate(tmplPath, enrichedVars, outputPath);
7966
8758
  result.refreshed.push(skillId);
7967
8759
  } catch (err) {
@@ -7978,14 +8770,14 @@ function refreshConfig(cliDir2, targetDotClaudeDir, registry2) {
7978
8770
  }
7979
8771
  function buildUnifiedMcpCapabilities2(cliDir2, installedMcpTools, mcpTools) {
7980
8772
  const allDeclarations = {};
7981
- const skillsDir = path13.join(cliDir2, "skills");
7982
- if (!fs16.existsSync(skillsDir)) return {};
7983
- const skillDirs = fs16.readdirSync(skillsDir, { withFileTypes: true });
8773
+ const skillsDir = path14.join(cliDir2, "skills");
8774
+ if (!fs17.existsSync(skillsDir)) return {};
8775
+ const skillDirs = fs17.readdirSync(skillsDir, { withFileTypes: true });
7984
8776
  for (const entry of skillDirs) {
7985
8777
  if (!entry.isDirectory()) continue;
7986
- const tmplPath = path13.join(skillsDir, entry.name, "SKILL.md.tmpl");
7987
- if (!fs16.existsSync(tmplPath)) continue;
7988
- const content = fs16.readFileSync(tmplPath, "utf-8");
8778
+ const tmplPath = path14.join(skillsDir, entry.name, "SKILL.md.tmpl");
8779
+ if (!fs17.existsSync(tmplPath)) continue;
8780
+ const content = fs17.readFileSync(tmplPath, "utf-8");
7989
8781
  const fm = parseFrontmatter(content);
7990
8782
  if (!fm) continue;
7991
8783
  const mcpCap = fm.mcpCapabilities;
@@ -8028,7 +8820,7 @@ function registerConfigCommand(program2, registry2) {
8028
8820
  });
8029
8821
  configCmd.command("refresh").description("\u6839\u636E\u6700\u65B0 MCP \u5B89\u88C5\u72B6\u6001\uFF0C\u5237\u65B0\u6240\u6709\u5DF2\u5B89\u88C5 skill \u7684\u6A21\u677F\u6E32\u67D3").action(() => {
8030
8822
  const targetDir = process.cwd();
8031
- const dotClaudeDir = path14.join(targetDir, ".claude");
8823
+ const dotClaudeDir = path15.join(targetDir, ".claude");
8032
8824
  const cliDir2 = __dirname;
8033
8825
  const result = refreshConfig(cliDir2, dotClaudeDir, registry2);
8034
8826
  if (result.errors.length > 0) {
@@ -8069,17 +8861,17 @@ function listTemplates(registry2, tool) {
8069
8861
  }
8070
8862
 
8071
8863
  // src/commands/template-init.ts
8072
- var fs17 = __toESM(require("node:fs"));
8073
- var path15 = __toESM(require("node:path"));
8864
+ var fs18 = __toESM(require("node:fs"));
8865
+ var path16 = __toESM(require("node:path"));
8074
8866
  var import_prompts3 = require("@clack/prompts");
8075
8867
  async function initTemplate(cliDir2, targetDir, skillId) {
8076
- const srcDir = path15.join(cliDir2, "skills", skillId);
8077
- const destDir = path15.join(targetDir, ".deepstorm", "templates", skillId);
8078
- if (!fs17.existsSync(srcDir)) {
8868
+ const srcDir = path16.join(cliDir2, "skills", skillId);
8869
+ const destDir = path16.join(targetDir, ".deepstorm", "templates", skillId);
8870
+ if (!fs18.existsSync(srcDir)) {
8079
8871
  console.log(`\u6A21\u677F\u4E0D\u5B58\u5728\uFF1A${skillId}`);
8080
8872
  return;
8081
8873
  }
8082
- if (fs17.existsSync(destDir)) {
8874
+ if (fs18.existsSync(destDir)) {
8083
8875
  const shouldOverwrite = await (0, import_prompts3.confirm)({
8084
8876
  message: `\u6A21\u677F ${skillId} \u5DF2\u5B58\u5728\uFF0C\u662F\u5426\u8986\u76D6\uFF1F`,
8085
8877
  initialValue: false
@@ -8088,21 +8880,21 @@ async function initTemplate(cliDir2, targetDir, skillId) {
8088
8880
  console.log("\u5DF2\u53D6\u6D88");
8089
8881
  return;
8090
8882
  }
8091
- fs17.rmSync(destDir, { recursive: true, force: true });
8883
+ fs18.rmSync(destDir, { recursive: true, force: true });
8092
8884
  }
8093
- ensureDir(path15.dirname(destDir));
8885
+ ensureDir(path16.dirname(destDir));
8094
8886
  copyDir(srcDir, destDir);
8095
8887
  console.log(`\u2714 \u6A21\u677F\u5DF2\u5BFC\u51FA\u5230 .deepstorm/templates/${skillId}/`);
8096
8888
  console.log(` \u4FEE\u6539\u5B8C\u6210\u540E\u8FD0\u884C deepstorm template apply ${skillId} \u5E94\u7528\u66F4\u6539`);
8097
8889
  }
8098
8890
 
8099
8891
  // src/commands/template-apply.ts
8100
- var fs18 = __toESM(require("node:fs"));
8101
- var path16 = __toESM(require("node:path"));
8892
+ var fs19 = __toESM(require("node:fs"));
8893
+ var path17 = __toESM(require("node:path"));
8102
8894
  function applyTemplate(targetDir, skillId) {
8103
- const srcDir = path16.join(targetDir, ".deepstorm", "templates", skillId);
8104
- const destDir = path16.join(targetDir, ".claude", "skills", skillId);
8105
- if (!fs18.existsSync(srcDir)) {
8895
+ const srcDir = path17.join(targetDir, ".deepstorm", "templates", skillId);
8896
+ const destDir = path17.join(targetDir, ".claude", "skills", skillId);
8897
+ if (!fs19.existsSync(srcDir)) {
8106
8898
  console.log(`\u6A21\u677F\u4E0D\u5B58\u5728\uFF0C\u8BF7\u5148\u8FD0\u884C deepstorm template init ${skillId}`);
8107
8899
  return;
8108
8900
  }
@@ -8136,22 +8928,22 @@ function registerTemplateCommand(program2, registry2) {
8136
8928
  }
8137
8929
 
8138
8930
  // src/commands/update.ts
8139
- var fs21 = __toESM(require("node:fs"));
8140
- var path19 = __toESM(require("node:path"));
8931
+ var fs22 = __toESM(require("node:fs"));
8932
+ var path20 = __toESM(require("node:path"));
8141
8933
  var import_node_child_process = require("node:child_process");
8142
8934
 
8143
8935
  // src/utils/version.ts
8144
- var fs19 = __toESM(require("node:fs"));
8145
- var path17 = __toESM(require("node:path"));
8936
+ var fs20 = __toESM(require("node:fs"));
8937
+ var path18 = __toESM(require("node:path"));
8146
8938
  function getCliVersion() {
8147
8939
  try {
8148
8940
  const paths = [
8149
- path17.resolve(__dirname, "package.json"),
8150
- path17.resolve(__dirname, "..", "package.json")
8941
+ path18.resolve(__dirname, "package.json"),
8942
+ path18.resolve(__dirname, "..", "package.json")
8151
8943
  ];
8152
8944
  for (const pkgPath of paths) {
8153
- if (fs19.existsSync(pkgPath)) {
8154
- const pkg = JSON.parse(fs19.readFileSync(pkgPath, "utf-8"));
8945
+ if (fs20.existsSync(pkgPath)) {
8946
+ const pkg = JSON.parse(fs20.readFileSync(pkgPath, "utf-8"));
8155
8947
  return pkg.version || "0.0.0";
8156
8948
  }
8157
8949
  }
@@ -8162,14 +8954,14 @@ function getCliVersion() {
8162
8954
  }
8163
8955
 
8164
8956
  // src/commands/template-upgrade.ts
8165
- var fs20 = __toESM(require("node:fs"));
8166
- var path18 = __toESM(require("node:path"));
8957
+ var fs21 = __toESM(require("node:fs"));
8958
+ var path19 = __toESM(require("node:path"));
8167
8959
  var crypto = __toESM(require("node:crypto"));
8168
8960
  var CHECKSUM_FILE = "deepstorm-checksums.json";
8169
8961
  function computeFileChecksum(filePath) {
8170
8962
  try {
8171
- if (!fs20.existsSync(filePath)) return null;
8172
- const content = fs20.readFileSync(filePath);
8963
+ if (!fs21.existsSync(filePath)) return null;
8964
+ const content = fs21.readFileSync(filePath);
8173
8965
  return crypto.createHash("sha256").update(content).digest("hex");
8174
8966
  } catch {
8175
8967
  return null;
@@ -8177,15 +8969,15 @@ function computeFileChecksum(filePath) {
8177
8969
  }
8178
8970
  function computeDirChecksums(dirPath, relativeTo = dirPath) {
8179
8971
  const result = {};
8180
- if (!fs20.existsSync(dirPath)) return result;
8972
+ if (!fs21.existsSync(dirPath)) return result;
8181
8973
  function walk(current) {
8182
- for (const entry of fs20.readdirSync(current, { withFileTypes: true })) {
8183
- const fullPath = path18.join(current, entry.name);
8974
+ for (const entry of fs21.readdirSync(current, { withFileTypes: true })) {
8975
+ const fullPath = path19.join(current, entry.name);
8184
8976
  if (entry.name === ".DS_Store") continue;
8185
8977
  if (entry.isDirectory()) {
8186
8978
  walk(fullPath);
8187
8979
  } else if (entry.isFile()) {
8188
- const relPath = path18.relative(relativeTo, fullPath);
8980
+ const relPath = path19.relative(relativeTo, fullPath);
8189
8981
  const checksum = computeFileChecksum(fullPath);
8190
8982
  if (checksum) result[relPath] = checksum;
8191
8983
  }
@@ -8195,32 +8987,32 @@ function computeDirChecksums(dirPath, relativeTo = dirPath) {
8195
8987
  return result;
8196
8988
  }
8197
8989
  function loadChecksums(targetDir) {
8198
- const filePath = path18.join(targetDir, ".claude", CHECKSUM_FILE);
8990
+ const filePath = path19.join(targetDir, ".claude", CHECKSUM_FILE);
8199
8991
  try {
8200
- return JSON.parse(fs20.readFileSync(filePath, "utf-8"));
8992
+ return JSON.parse(fs21.readFileSync(filePath, "utf-8"));
8201
8993
  } catch {
8202
8994
  return {};
8203
8995
  }
8204
8996
  }
8205
8997
  function saveChecksums(targetDir, checksums) {
8206
- const dir = path18.join(targetDir, ".claude");
8998
+ const dir = path19.join(targetDir, ".claude");
8207
8999
  ensureDir(dir);
8208
- fs20.writeFileSync(
8209
- path18.join(dir, CHECKSUM_FILE),
9000
+ fs21.writeFileSync(
9001
+ path19.join(dir, CHECKSUM_FILE),
8210
9002
  JSON.stringify(checksums, null, 2) + "\n",
8211
9003
  "utf-8"
8212
9004
  );
8213
9005
  }
8214
9006
  function backupFile(filePath) {
8215
9007
  try {
8216
- if (!fs20.existsSync(filePath)) return null;
8217
- const dir = path18.dirname(filePath);
8218
- const ext = path18.extname(filePath);
8219
- const base = path18.basename(filePath, ext);
9008
+ if (!fs21.existsSync(filePath)) return null;
9009
+ const dir = path19.dirname(filePath);
9010
+ const ext = path19.extname(filePath);
9011
+ const base = path19.basename(filePath, ext);
8220
9012
  const timestamp = Date.now();
8221
9013
  const bakName = `${base}.${timestamp}.bak`;
8222
- const bakPath = path18.join(dir, bakName);
8223
- fs20.cpSync(filePath, bakPath, { force: true });
9014
+ const bakPath = path19.join(dir, bakName);
9015
+ fs21.cpSync(filePath, bakPath, { force: true });
8224
9016
  return bakName;
8225
9017
  } catch {
8226
9018
  return null;
@@ -8241,19 +9033,19 @@ function backupModifiedAssets(targetDir, skillIds, toolNames, registry2) {
8241
9033
  const stored = loadChecksums(targetDir);
8242
9034
  const backedUp = [];
8243
9035
  for (const skillId of skillIds) {
8244
- const skillDir = path18.join(targetDir, ".claude", "skills", skillId);
8245
- if (!fs20.existsSync(skillDir)) continue;
9036
+ const skillDir = path19.join(targetDir, ".claude", "skills", skillId);
9037
+ if (!fs21.existsSync(skillDir)) continue;
8246
9038
  const checksums = computeDirChecksums(skillDir);
8247
9039
  for (const [relPath] of Object.entries(checksums)) {
8248
9040
  const key = `skills/${skillId}/${relPath}`;
8249
- checkAndBackup(key, path18.join(skillDir, relPath), stored, backedUp);
9041
+ checkAndBackup(key, path19.join(skillDir, relPath), stored, backedUp);
8250
9042
  }
8251
9043
  }
8252
9044
  const reader = new RegistryReader(registry2);
8253
9045
  for (const tool of toolNames) {
8254
9046
  const agents = reader.getToolAgents(tool);
8255
9047
  for (const agentFile of agents) {
8256
- const filePath = path18.join(targetDir, ".claude", "agents", agentFile.replace(/\.tmpl$/, ""));
9048
+ const filePath = path19.join(targetDir, ".claude", "agents", agentFile.replace(/\.tmpl$/, ""));
8257
9049
  const key = `agents/${agentFile.replace(/\.tmpl$/, "")}`;
8258
9050
  checkAndBackup(key, filePath, stored, backedUp);
8259
9051
  }
@@ -8261,7 +9053,7 @@ function backupModifiedAssets(targetDir, skillIds, toolNames, registry2) {
8261
9053
  for (const tool of toolNames) {
8262
9054
  const hooks = reader.getToolHooks(tool);
8263
9055
  for (const hookFile of hooks) {
8264
- const filePath = path18.join(targetDir, ".claude", "hooks", hookFile);
9056
+ const filePath = path19.join(targetDir, ".claude", "hooks", hookFile);
8265
9057
  const key = `hooks/${hookFile}`;
8266
9058
  checkAndBackup(key, filePath, stored, backedUp);
8267
9059
  }
@@ -8272,7 +9064,7 @@ function storeNewChecksums(targetDir, skillIds, toolNames, registry2) {
8272
9064
  const newChecksums = {};
8273
9065
  const reader = new RegistryReader(registry2);
8274
9066
  for (const skillId of skillIds) {
8275
- const skillDir = path18.join(targetDir, ".claude", "skills", skillId);
9067
+ const skillDir = path19.join(targetDir, ".claude", "skills", skillId);
8276
9068
  const checksums = computeDirChecksums(skillDir);
8277
9069
  for (const [relPath, checksum] of Object.entries(checksums)) {
8278
9070
  newChecksums[`skills/${skillId}/${relPath}`] = checksum;
@@ -8282,7 +9074,7 @@ function storeNewChecksums(targetDir, skillIds, toolNames, registry2) {
8282
9074
  const agents = reader.getToolAgents(tool);
8283
9075
  for (const agentFile of agents) {
8284
9076
  const installedName = agentFile.replace(/\.tmpl$/, "");
8285
- const filePath = path18.join(targetDir, ".claude", "agents", installedName);
9077
+ const filePath = path19.join(targetDir, ".claude", "agents", installedName);
8286
9078
  const chk = computeFileChecksum(filePath);
8287
9079
  if (chk) newChecksums[`agents/${installedName}`] = chk;
8288
9080
  }
@@ -8290,7 +9082,7 @@ function storeNewChecksums(targetDir, skillIds, toolNames, registry2) {
8290
9082
  for (const tool of toolNames) {
8291
9083
  const hooks = reader.getToolHooks(tool);
8292
9084
  for (const hookFile of hooks) {
8293
- const filePath = path18.join(targetDir, ".claude", "hooks", hookFile);
9085
+ const filePath = path19.join(targetDir, ".claude", "hooks", hookFile);
8294
9086
  const chk = computeFileChecksum(filePath);
8295
9087
  if (chk) newChecksums[`hooks/${hookFile}`] = chk;
8296
9088
  }
@@ -8321,9 +9113,9 @@ function detectToolsFromConfig(config, registry2) {
8321
9113
  return [...found];
8322
9114
  }
8323
9115
  function readSettingsConfig(targetDir) {
8324
- const settingsPath = path18.join(targetDir, ".claude", "settings.json");
9116
+ const settingsPath = path19.join(targetDir, ".claude", "settings.json");
8325
9117
  try {
8326
- const raw = fs20.readFileSync(settingsPath, "utf-8");
9118
+ const raw = fs21.readFileSync(settingsPath, "utf-8");
8327
9119
  const settings = JSON.parse(raw);
8328
9120
  const deepstorm = settings.deepstorm || {};
8329
9121
  const metaKeys = /* @__PURE__ */ new Set([
@@ -8352,22 +9144,22 @@ function flattenNestedConfig(obj, prefix, result, skipKeys) {
8352
9144
  }
8353
9145
  }
8354
9146
  function loadRegistryFromCliDir(cliDir2) {
8355
- const registryPath = path18.join(cliDir2, "registry.json");
9147
+ const registryPath = path19.join(cliDir2, "registry.json");
8356
9148
  try {
8357
- const raw = fs20.readFileSync(registryPath, "utf-8");
9149
+ const raw = fs21.readFileSync(registryPath, "utf-8");
8358
9150
  return JSON.parse(raw);
8359
9151
  } catch {
8360
9152
  return null;
8361
9153
  }
8362
9154
  }
8363
9155
  function mergeToolHooksJson(toolNames, cliDir2, targetDir) {
8364
- const hooksSrcDir = path18.join(cliDir2, "hooks");
8365
- const destHooksJson = path18.join(targetDir, ".claude", "hooks.json");
9156
+ const hooksSrcDir = path19.join(cliDir2, "hooks");
9157
+ const destHooksJson = path19.join(targetDir, ".claude", "hooks.json");
8366
9158
  for (const tool of toolNames) {
8367
- const toolHooksJsonPath = path18.join(hooksSrcDir, `${tool}-hooks.json`);
8368
- if (fs20.existsSync(toolHooksJsonPath)) {
8369
- ensureDir(path18.join(targetDir, ".claude"));
8370
- const incoming = JSON.parse(fs20.readFileSync(toolHooksJsonPath, "utf-8"));
9159
+ const toolHooksJsonPath = path19.join(hooksSrcDir, `${tool}-hooks.json`);
9160
+ if (fs21.existsSync(toolHooksJsonPath)) {
9161
+ ensureDir(path19.join(targetDir, ".claude"));
9162
+ const incoming = JSON.parse(fs21.readFileSync(toolHooksJsonPath, "utf-8"));
8371
9163
  mergeHooks(destHooksJson, incoming);
8372
9164
  }
8373
9165
  }
@@ -8485,8 +9277,8 @@ function readLocalRegistryFile(url) {
8485
9277
  filePath = filePath.slice(7);
8486
9278
  }
8487
9279
  try {
8488
- if (fs21.existsSync(filePath)) {
8489
- return JSON.parse(fs21.readFileSync(filePath, "utf-8"));
9280
+ if (fs22.existsSync(filePath)) {
9281
+ return JSON.parse(fs22.readFileSync(filePath, "utf-8"));
8490
9282
  }
8491
9283
  } catch {
8492
9284
  }
@@ -8568,9 +9360,9 @@ async function updateCLI(fetchFn) {
8568
9360
  return result;
8569
9361
  }
8570
9362
  function getInstalledSkillIds(targetDir) {
8571
- const settingsPath = path19.join(targetDir, ".claude", "settings.json");
9363
+ const settingsPath = path20.join(targetDir, ".claude", "settings.json");
8572
9364
  try {
8573
- const raw = fs21.readFileSync(settingsPath, "utf-8");
9365
+ const raw = fs22.readFileSync(settingsPath, "utf-8");
8574
9366
  const settings = JSON.parse(raw);
8575
9367
  return settings.deepstorm?.installedSkills ?? [];
8576
9368
  } catch {
@@ -8591,11 +9383,11 @@ function registerUpdateCommand(program2) {
8591
9383
  }
8592
9384
 
8593
9385
  // src/commands/doctor.ts
8594
- var fs22 = __toESM(require("node:fs"));
8595
- var path20 = __toESM(require("node:path"));
9386
+ var fs23 = __toESM(require("node:fs"));
9387
+ var path21 = __toESM(require("node:path"));
8596
9388
  function getInstalledSkills(settingsPath) {
8597
9389
  try {
8598
- const settings = JSON.parse(fs22.readFileSync(settingsPath, "utf-8"));
9390
+ const settings = JSON.parse(fs23.readFileSync(settingsPath, "utf-8"));
8599
9391
  return settings.deepstorm?.installedSkills || [];
8600
9392
  } catch {
8601
9393
  return [];
@@ -8604,7 +9396,7 @@ function getInstalledSkills(settingsPath) {
8604
9396
  function runDoctor(targetDir) {
8605
9397
  const checks = [];
8606
9398
  const version = getCliVersion();
8607
- const settingsPath = path20.join(targetDir, ".claude", "settings.json");
9399
+ const settingsPath = path21.join(targetDir, ".claude", "settings.json");
8608
9400
  readDeepStormConfig(settingsPath);
8609
9401
  checks.push({
8610
9402
  name: "CLI \u7248\u672C",
@@ -8612,7 +9404,7 @@ function runDoctor(targetDir) {
8612
9404
  message: `v${version}\uFF08\u8FD0\u884C deepstorm update --check \u68C0\u67E5\u6700\u65B0\u7248\u672C\uFF09`
8613
9405
  });
8614
9406
  let hasDeepStorm = false;
8615
- if (!fs22.existsSync(settingsPath)) {
9407
+ if (!fs23.existsSync(settingsPath)) {
8616
9408
  checks.push({
8617
9409
  name: "\u914D\u7F6E\u6587\u4EF6",
8618
9410
  status: "warn",
@@ -8620,7 +9412,7 @@ function runDoctor(targetDir) {
8620
9412
  });
8621
9413
  } else {
8622
9414
  try {
8623
- const settings = JSON.parse(fs22.readFileSync(settingsPath, "utf-8"));
9415
+ const settings = JSON.parse(fs23.readFileSync(settingsPath, "utf-8"));
8624
9416
  if (settings.deepstorm) {
8625
9417
  hasDeepStorm = true;
8626
9418
  checks.push({
@@ -8643,20 +9435,20 @@ function runDoctor(targetDir) {
8643
9435
  });
8644
9436
  }
8645
9437
  }
8646
- const skillsDir = path20.join(targetDir, ".claude", "skills");
8647
- if (fs22.existsSync(skillsDir)) {
8648
- const skillDirs = fs22.readdirSync(skillsDir).filter(
8649
- (n) => fs22.statSync(path20.join(skillsDir, n)).isDirectory()
9438
+ const skillsDir = path21.join(targetDir, ".claude", "skills");
9439
+ if (fs23.existsSync(skillsDir)) {
9440
+ const skillDirs = fs23.readdirSync(skillsDir).filter(
9441
+ (n) => fs23.statSync(path21.join(skillsDir, n)).isDirectory()
8650
9442
  );
8651
9443
  let validCount = 0;
8652
9444
  let invalidCount = 0;
8653
9445
  for (const skillName of skillDirs) {
8654
- const skillMd = path20.join(skillsDir, skillName, "SKILL.md");
8655
- if (!fs22.existsSync(skillMd)) {
9446
+ const skillMd = path21.join(skillsDir, skillName, "SKILL.md");
9447
+ if (!fs23.existsSync(skillMd)) {
8656
9448
  invalidCount++;
8657
9449
  continue;
8658
9450
  }
8659
- const content = fs22.readFileSync(skillMd, "utf-8");
9451
+ const content = fs23.readFileSync(skillMd, "utf-8");
8660
9452
  const frontmatter = parseFrontmatter(content);
8661
9453
  if (frontmatter && frontmatter.name) {
8662
9454
  validCount++;
@@ -8686,7 +9478,7 @@ function runDoctor(targetDir) {
8686
9478
  const installedSkills = getInstalledSkills(settingsPath);
8687
9479
  const missingSkills = [];
8688
9480
  for (const skillId of installedSkills) {
8689
- if (!fs22.existsSync(path20.join(skillsDir, skillId))) {
9481
+ if (!fs23.existsSync(path21.join(skillsDir, skillId))) {
8690
9482
  missingSkills.push(skillId);
8691
9483
  }
8692
9484
  }
@@ -8710,10 +9502,10 @@ function runDoctor(targetDir) {
8710
9502
  message: ".claude/skills/ \u4E0D\u5B58\u5728"
8711
9503
  });
8712
9504
  }
8713
- const mcpPath = path20.join(targetDir, ".mcp.json");
8714
- if (fs22.existsSync(mcpPath)) {
9505
+ const mcpPath = path21.join(targetDir, ".mcp.json");
9506
+ if (fs23.existsSync(mcpPath)) {
8715
9507
  try {
8716
- const mcp = JSON.parse(fs22.readFileSync(mcpPath, "utf-8"));
9508
+ const mcp = JSON.parse(fs23.readFileSync(mcpPath, "utf-8"));
8717
9509
  const hasServers = mcp.mcpServers && Object.keys(mcp.mcpServers).length > 0;
8718
9510
  checks.push({
8719
9511
  name: "MCP \u670D\u52A1\u5668",
@@ -8734,12 +9526,12 @@ function runDoctor(targetDir) {
8734
9526
  message: ".mcp.json \u4E0D\u5B58\u5728"
8735
9527
  });
8736
9528
  }
8737
- if (hasDeepStorm && fs22.existsSync(settingsPath)) {
9529
+ if (hasDeepStorm && fs23.existsSync(settingsPath)) {
8738
9530
  try {
8739
- const settings = JSON.parse(fs22.readFileSync(settingsPath, "utf-8"));
9531
+ const settings = JSON.parse(fs23.readFileSync(settingsPath, "utf-8"));
8740
9532
  const installedMcp = settings.deepstorm?.installedMcpServers;
8741
9533
  if (installedMcp && installedMcp.length > 0) {
8742
- const mcpExists = fs22.existsSync(mcpPath);
9534
+ const mcpExists = fs23.existsSync(mcpPath);
8743
9535
  if (!mcpExists) {
8744
9536
  checks.push({
8745
9537
  name: "MCP \u4E00\u81F4\u6027",
@@ -8748,7 +9540,7 @@ function runDoctor(targetDir) {
8748
9540
  });
8749
9541
  } else {
8750
9542
  try {
8751
- const mcpConfig = JSON.parse(fs22.readFileSync(mcpPath, "utf-8"));
9543
+ const mcpConfig = JSON.parse(fs23.readFileSync(mcpPath, "utf-8"));
8752
9544
  const servers = mcpConfig.mcpServers || {};
8753
9545
  const missing = [];
8754
9546
  for (const toolName of installedMcp) {
@@ -8776,9 +9568,9 @@ function runDoctor(targetDir) {
8776
9568
  } catch {
8777
9569
  }
8778
9570
  }
8779
- if (hasDeepStorm && fs22.existsSync(settingsPath)) {
9571
+ if (hasDeepStorm && fs23.existsSync(settingsPath)) {
8780
9572
  try {
8781
- const settings = JSON.parse(fs22.readFileSync(settingsPath, "utf-8"));
9573
+ const settings = JSON.parse(fs23.readFileSync(settingsPath, "utf-8"));
8782
9574
  const config = settings.deepstorm;
8783
9575
  const validKeys = loadValidConfigKeys();
8784
9576
  if (validKeys.size > 0 && config) {
@@ -8832,18 +9624,18 @@ function printDoctorReport(report) {
8832
9624
  }
8833
9625
 
8834
9626
  // src/commands/uninstall.ts
8835
- var fs23 = __toESM(require("node:fs"));
8836
- var path21 = __toESM(require("node:path"));
9627
+ var fs24 = __toESM(require("node:fs"));
9628
+ var path22 = __toESM(require("node:path"));
8837
9629
  var import_prompts4 = require("@clack/prompts");
8838
9630
  async function uninstallDeepStorm(targetDir) {
8839
- const settingsPath = path21.join(targetDir, ".claude", "settings.json");
8840
- if (!fs23.existsSync(settingsPath)) {
9631
+ const settingsPath = path22.join(targetDir, ".claude", "settings.json");
9632
+ if (!fs24.existsSync(settingsPath)) {
8841
9633
  console.log("DeepStorm \u5C1A\u672A\u914D\u7F6E\uFF0C\u65E0\u9700\u5378\u8F7D");
8842
9634
  return;
8843
9635
  }
8844
9636
  let hasDeepStorm = false;
8845
9637
  try {
8846
- const settings = JSON.parse(fs23.readFileSync(settingsPath, "utf-8"));
9638
+ const settings = JSON.parse(fs24.readFileSync(settingsPath, "utf-8"));
8847
9639
  hasDeepStorm = !!settings.deepstorm;
8848
9640
  } catch {
8849
9641
  }
@@ -8853,14 +9645,14 @@ async function uninstallDeepStorm(targetDir) {
8853
9645
  }
8854
9646
  cleanInstalled(targetDir);
8855
9647
  resetConfig(targetDir);
8856
- const templatesDir = path21.join(targetDir, ".deepstorm", "templates");
8857
- if (fs23.existsSync(templatesDir)) {
9648
+ const templatesDir = path22.join(targetDir, ".deepstorm", "templates");
9649
+ if (fs24.existsSync(templatesDir)) {
8858
9650
  const shouldDelete = await (0, import_prompts4.confirm)({
8859
9651
  message: "\u662F\u5426\u5220\u9664 .deepstorm/templates/ \u76EE\u5F55\uFF1F",
8860
9652
  initialValue: false
8861
9653
  });
8862
9654
  if (shouldDelete) {
8863
- fs23.rmSync(templatesDir, { recursive: true, force: true });
9655
+ fs24.rmSync(templatesDir, { recursive: true, force: true });
8864
9656
  console.log("\u2714 .deepstorm/templates/ \u5DF2\u5220\u9664");
8865
9657
  } else {
8866
9658
  console.log("\u4FDD\u7559 .deepstorm/templates/");
@@ -8873,9 +9665,9 @@ async function uninstallDeepStorm(targetDir) {
8873
9665
  var program = new import_commander.Command();
8874
9666
  program.name("deepstorm").description("DeepStorm CLI \u2014 \u4E00\u952E\u914D\u7F6E\u9879\u76EE\u5F00\u53D1\u73AF\u5883").version(getCliVersion(), "-v, --version", "\u8F93\u51FA\u7248\u672C\u53F7");
8875
9667
  function loadRegistry() {
8876
- const registryPath = path22.join(__dirname, "registry.json");
9668
+ const registryPath = path23.join(__dirname, "registry.json");
8877
9669
  try {
8878
- const raw = fs24.readFileSync(registryPath, "utf-8");
9670
+ const raw = fs25.readFileSync(registryPath, "utf-8");
8879
9671
  return JSON.parse(raw);
8880
9672
  } catch {
8881
9673
  return { version: "1", tools: {}, wizards: {}, skills: {} };
@@ -8883,6 +9675,7 @@ function loadRegistry() {
8883
9675
  }
8884
9676
  var registry = loadRegistry();
8885
9677
  registerSetupCommand(program, registry);
9678
+ registerInitCommand(program);
8886
9679
  registerPluginBuildCommand(program, registry);
8887
9680
  registerConfigCommand(program, registry);
8888
9681
  registerTemplateCommand(program, registry);