@deepstorm/cli 0.6.5 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/cli.js +588 -447
  2. package/package.json +2 -2
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(path22) {
1191
- return /^\.|this\b/.test(path22.original);
1190
+ scopedId: function scopedId(path23) {
1191
+ return /^\.|this\b/.test(path23.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(path22) {
1196
- return path22.parts.length === 1 && !AST.helpers.scopedId(path22) && !path22.depth;
1195
+ simpleId: function simpleId(path23) {
1196
+ return path23.parts.length === 1 && !AST.helpers.scopedId(path23) && !path23.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(path22, params, hash, open, strip, locInfo) {
2266
+ function prepareMustache(path23, 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: path22,
2271
+ path: path23,
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), path22 = decorator.path;
2589
+ var params = this.setupFullMustacheParams(decorator, program2, void 0), path23 = decorator.path;
2590
2590
  this.useDecorators = true;
2591
- this.opcode("registerDecorator", params.length, path22.original);
2591
+ this.opcode("registerDecorator", params.length, path23.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 path22 = sexpr.path, name = path22.parts[0], isBlock = program2 != null || inverse != null;
2656
- this.opcode("getContext", path22.depth);
2655
+ var path23 = sexpr.path, name = path23.parts[0], isBlock = program2 != null || inverse != null;
2656
+ this.opcode("getContext", path23.depth);
2657
2657
  this.opcode("pushProgram", program2);
2658
2658
  this.opcode("pushProgram", inverse);
2659
- path22.strict = true;
2660
- this.accept(path22);
2659
+ path23.strict = true;
2660
+ this.accept(path23);
2661
2661
  this.opcode("invokeAmbiguous", name, isBlock);
2662
2662
  },
2663
2663
  simpleSexpr: function simpleSexpr(sexpr) {
2664
- var path22 = sexpr.path;
2665
- path22.strict = true;
2666
- this.accept(path22);
2664
+ var path23 = sexpr.path;
2665
+ path23.strict = true;
2666
+ this.accept(path23);
2667
2667
  this.opcode("resolvePossibleLambda");
2668
2668
  },
2669
2669
  helperSexpr: function helperSexpr(sexpr, program2, inverse) {
2670
- var params = this.setupFullMustacheParams(sexpr, program2, inverse), path22 = sexpr.path, name = path22.parts[0];
2670
+ var params = this.setupFullMustacheParams(sexpr, program2, inverse), path23 = sexpr.path, name = path23.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
- path22.strict = true;
2677
- path22.falsy = true;
2678
- this.accept(path22);
2679
- this.opcode("invokeHelper", params.length, path22.original, _ast2["default"].helpers.simpleId(path22));
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));
2680
2680
  }
2681
2681
  },
2682
- PathExpression: function PathExpression(path22) {
2683
- this.addDepth(path22.depth);
2684
- this.opcode("getContext", path22.depth);
2685
- var name = path22.parts[0], scoped = _ast2["default"].helpers.scopedId(path22), blockParamId = !path22.depth && !scoped && this.blockParamIndex(name);
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);
2686
2686
  if (blockParamId) {
2687
- this.opcode("lookupBlockParam", blockParamId, path22.parts);
2687
+ this.opcode("lookupBlockParam", blockParamId, path23.parts);
2688
2688
  } else if (!name) {
2689
2689
  this.opcode("pushContext");
2690
- } else if (path22.data) {
2690
+ } else if (path23.data) {
2691
2691
  this.options.data = true;
2692
- this.opcode("lookupData", path22.depth, path22.parts, path22.strict);
2692
+ this.opcode("lookupData", path23.depth, path23.parts, path23.strict);
2693
2693
  } else {
2694
- this.opcode("lookupOnContext", path22.parts, path22.falsy, path22.strict, scoped);
2694
+ this.opcode("lookupOnContext", path23.parts, path23.falsy, path23.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 path22 = aPath;
3044
+ var path23 = aPath;
3045
3045
  var url = urlParse(aPath);
3046
3046
  if (url) {
3047
3047
  if (!url.path) {
3048
3048
  return aPath;
3049
3049
  }
3050
- path22 = url.path;
3050
+ path23 = url.path;
3051
3051
  }
3052
- var isAbsolute = exports2.isAbsolute(path22);
3053
- var parts = path22.split(/\/+/);
3052
+ var isAbsolute = exports2.isAbsolute(path23);
3053
+ var parts = path23.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
- path22 = parts.join("/");
3071
- if (path22 === "") {
3072
- path22 = isAbsolute ? "/" : ".";
3070
+ path23 = parts.join("/");
3071
+ if (path23 === "") {
3072
+ path23 = isAbsolute ? "/" : ".";
3073
3073
  }
3074
3074
  if (url) {
3075
- url.path = path22;
3075
+ url.path = path23;
3076
3076
  return urlGenerate(url);
3077
3077
  }
3078
- return path22;
3078
+ return path23;
3079
3079
  }
3080
3080
  exports2.normalize = normalize;
3081
- function join20(aRoot, aPath) {
3081
+ function join21(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 = join20;
3113
+ exports2.join = join21;
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 = join20(urlGenerate(parsed), sourceURL);
3286
+ sourceURL = join21(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 path22 = id.parts.join("/");
5862
- return (id.data ? "@" : "") + "PATH:" + path22;
5861
+ var path23 = id.parts.join("/");
5862
+ return (id.data ? "@" : "") + "PATH:" + path23;
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 fs27 = require("fs");
5902
- var templateString = fs27.readFileSync(filename, "utf8");
5901
+ var fs28 = require("fs");
5902
+ var templateString = fs28.readFileSync(filename, "utf8");
5903
5903
  module3.exports = handlebars.compile(templateString);
5904
5904
  }
5905
5905
  if (typeof require !== "undefined" && require.extensions) {
@@ -5911,12 +5911,12 @@ var require_lib = __commonJS({
5911
5911
 
5912
5912
  // src/index.ts
5913
5913
  var import_commander = require("commander");
5914
- var fs26 = __toESM(require("node:fs"));
5915
- var path21 = __toESM(require("node:path"));
5914
+ var fs27 = __toESM(require("node:fs"));
5915
+ var path22 = __toESM(require("node:path"));
5916
5916
 
5917
5917
  // src/commands/setup.ts
5918
- var path8 = __toESM(require("node:path"));
5919
- var fs12 = __toESM(require("node:fs"));
5918
+ var path9 = __toESM(require("node:path"));
5919
+ var fs13 = __toESM(require("node:fs"));
5920
5920
 
5921
5921
  // src/engine/registry.ts
5922
5922
  var RegistryReader = class {
@@ -6247,19 +6247,38 @@ function initContextMap(targetDir, opts) {
6247
6247
  const content = CONTEXT_MD_TEMPLATE.replace("{backend.language}", backendLang).replace("{frontend.framework}", frontendFramework);
6248
6248
  fs2.writeFileSync(contextPath, content, "utf-8");
6249
6249
  console.log("\u2714 \u5DF2\u521B\u5EFA .deepstorm/context.md \u9879\u76EE\u4E0A\u4E0B\u6587\u5730\u56FE");
6250
- appendClaudeMdRef(targetDir);
6251
6250
  }
6252
- function appendClaudeMdRef(targetDir) {
6253
- const claudeMdPath = path2.join(targetDir, "CLAUDE.md");
6254
- const refLine = "\n> \u9879\u76EE\u4E8B\u5B9E\u89C1 .deepstorm/context.md\n";
6255
- if (!fs2.existsSync(claudeMdPath)) {
6256
- fs2.writeFileSync(claudeMdPath, refLine, "utf-8");
6257
- return;
6251
+ function initClaudeMd(targetDir, opts) {
6252
+ const claudeDir = path2.join(targetDir, ".claude");
6253
+ const claudeMdPath = path2.join(claudeDir, "CLAUDE.md");
6254
+ if (fs2.existsSync(claudeMdPath)) return;
6255
+ ensureDir2(claudeDir);
6256
+ const projectName = opts.projectName || "unknown";
6257
+ const lines = [
6258
+ `# ${projectName}`,
6259
+ ""
6260
+ ];
6261
+ const techLines = [];
6262
+ if (opts.frontend) {
6263
+ techLines.push(`- **\u524D\u7AEF**\uFF1A${opts.frontend}`);
6264
+ if (opts.uiLib) techLines.push(`- **UI \u5E93**\uFF1A${opts.uiLib}`);
6265
+ if (opts.cssFramework) techLines.push(`- **CSS \u65B9\u6848**\uFF1A${opts.cssFramework}`);
6266
+ }
6267
+ if (opts.backend) {
6268
+ techLines.push(`- **\u540E\u7AEF**\uFF1A${opts.backend}`);
6269
+ if (opts.orm) techLines.push(`- **ORM**\uFF1A${opts.orm}`);
6270
+ if (opts.migration) techLines.push(`- **\u6570\u636E\u5E93\u8FC1\u79FB**\uFF1A${opts.migration}`);
6271
+ if (opts.ai) techLines.push(`- **AI \u6846\u67B6**\uFF1A${opts.ai}`);
6258
6272
  }
6259
- const existing = fs2.readFileSync(claudeMdPath, "utf-8");
6260
- if (existing.includes(".deepstorm/context.md")) return;
6261
- fs2.appendFileSync(claudeMdPath, refLine, "utf-8");
6262
- console.log("\u2714 \u5DF2\u5728 CLAUDE.md \u8FFD\u52A0\u9879\u76EE\u4E0A\u4E0B\u6587\u5F15\u7528");
6273
+ if (techLines.length > 0) {
6274
+ lines.push("## \u6280\u672F\u6808", "");
6275
+ lines.push(...techLines);
6276
+ lines.push("");
6277
+ }
6278
+ lines.push("> \u9879\u76EE\u4E8B\u5B9E\u89C1 .deepstorm/context.md");
6279
+ lines.push("");
6280
+ fs2.writeFileSync(claudeMdPath, lines.join("\n"), "utf-8");
6281
+ console.log("\u2714 \u5DF2\u521B\u5EFA .claude/claude.md \u9879\u76EE\u4FE1\u606F");
6263
6282
  }
6264
6283
  function writeInitTechStack(baseDir, opts) {
6265
6284
  const config = {};
@@ -6280,6 +6299,7 @@ function writeInitTechStack(baseDir, opts) {
6280
6299
  const nested = buildInitNestedConfig(config);
6281
6300
  writeDeepStormConfig(baseDir, nested);
6282
6301
  initContextMap(baseDir, opts);
6302
+ initClaudeMd(baseDir, opts);
6283
6303
  }
6284
6304
  function buildInitNestedConfig(flat) {
6285
6305
  const result = { reef: {} };
@@ -6346,9 +6366,10 @@ async function promptContinueSetup(targetDir, projectName, registry2) {
6346
6366
  }
6347
6367
  }
6348
6368
  function buildContext(opts) {
6369
+ const projectName = opts.projectName || "project";
6349
6370
  return {
6350
- projectName: opts.projectName,
6351
- packageName: opts.projectName.replace(/[_-]/g, "").toLowerCase(),
6371
+ projectName,
6372
+ packageName: projectName.replace(/[_-]/g, "").toLowerCase(),
6352
6373
  groupId: "com.example",
6353
6374
  frontend: opts.frontend || false,
6354
6375
  backend: opts.backend || false,
@@ -6362,19 +6383,34 @@ function buildContext(opts) {
6362
6383
  async function runInteractiveMode(targetDir) {
6363
6384
  const { intro: intro2, outro: outro2, text: text2, select: select2, isCancel: isCancel8, confirm: confirm6 } = await import("@clack/prompts");
6364
6385
  intro2("\u{1F680} DeepStorm Init \u2014 \u9879\u76EE\u811A\u624B\u67B6\u521D\u59CB\u5316");
6365
- const projectName = await text2({
6366
- message: "\u9879\u76EE\u540D\u79F0\uFF1A",
6367
- placeholder: "my-project",
6368
- validate: (value) => {
6369
- if (!value) return "\u8BF7\u8F93\u5165\u9879\u76EE\u540D\u79F0";
6370
- 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";
6371
- return void 0;
6372
- }
6386
+ const isProjectDir = await confirm6({
6387
+ message: "\u5F53\u524D\u8DEF\u5F84\u662F\u5426\u4E3A\u9879\u76EE\u76EE\u5F55\uFF1F",
6388
+ initialValue: false
6373
6389
  });
6374
- if (isCancel8(projectName) || typeof projectName !== "string") {
6390
+ if (isCancel8(isProjectDir)) {
6375
6391
  outro2("\u5DF2\u53D6\u6D88");
6376
6392
  return;
6377
6393
  }
6394
+ let projectName;
6395
+ if (isProjectDir) {
6396
+ console.log("\u2713 \u5C06\u5728\u5F53\u524D\u76EE\u5F55\u76F4\u63A5\u751F\u6210\u811A\u624B\u67B6");
6397
+ projectName = void 0;
6398
+ } else {
6399
+ const name = await text2({
6400
+ message: "\u9879\u76EE\u540D\u79F0\uFF1A",
6401
+ placeholder: "my-project",
6402
+ validate: (value) => {
6403
+ if (!value) return "\u8BF7\u8F93\u5165\u9879\u76EE\u540D\u79F0";
6404
+ 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";
6405
+ return void 0;
6406
+ }
6407
+ });
6408
+ if (isCancel8(name) || typeof name !== "string") {
6409
+ outro2("\u5DF2\u53D6\u6D88");
6410
+ return;
6411
+ }
6412
+ projectName = name;
6413
+ }
6378
6414
  const frontendChoice = await select2({
6379
6415
  message: "\u9009\u62E9\u524D\u7AEF\u6846\u67B6\uFF1A",
6380
6416
  options: [
@@ -6389,28 +6425,30 @@ async function runInteractiveMode(targetDir) {
6389
6425
  let uiLib;
6390
6426
  let cssFramework;
6391
6427
  if (frontendChoice === "angular") {
6392
- uiLib = await select2({
6428
+ const uiLibResult = await select2({
6393
6429
  message: "\u9009\u62E9 UI \u5E93\uFF1A",
6394
6430
  options: [
6395
6431
  { value: "primeng", label: "PrimeNG" },
6396
6432
  { value: "none", label: "\u65E0\uFF08\u4EC5 Angular \u6838\u5FC3\uFF09" }
6397
6433
  ]
6398
6434
  });
6399
- if (isCancel8(uiLib)) {
6435
+ if (isCancel8(uiLibResult)) {
6400
6436
  outro2("\u5DF2\u53D6\u6D88");
6401
6437
  return;
6402
6438
  }
6403
- cssFramework = await select2({
6439
+ uiLib = uiLibResult;
6440
+ const cssResult = await select2({
6404
6441
  message: "\u9009\u62E9 CSS \u65B9\u6848\uFF1A",
6405
6442
  options: [
6406
6443
  { value: "tailwind", label: "Tailwind CSS" },
6407
6444
  { value: "none", label: "\u6807\u51C6 CSS" }
6408
6445
  ]
6409
6446
  });
6410
- if (isCancel8(cssFramework)) {
6447
+ if (isCancel8(cssResult)) {
6411
6448
  outro2("\u5DF2\u53D6\u6D88");
6412
6449
  return;
6413
6450
  }
6451
+ cssFramework = cssResult;
6414
6452
  }
6415
6453
  const backendChoice = await select2({
6416
6454
  message: "\u9009\u62E9\u540E\u7AEF\u6846\u67B6\uFF1A",
@@ -6427,39 +6465,42 @@ async function runInteractiveMode(targetDir) {
6427
6465
  let migration;
6428
6466
  let aiChoice;
6429
6467
  if (backendChoice === "java") {
6430
- orm = await select2({
6468
+ const ormResult = await select2({
6431
6469
  message: "\u9009\u62E9 ORM \u6846\u67B6\uFF1A",
6432
6470
  options: [
6433
6471
  { value: "hibernate", label: "Hibernate" },
6434
6472
  { value: "none", label: "\u65E0" }
6435
6473
  ]
6436
6474
  });
6437
- if (isCancel8(orm)) {
6475
+ if (isCancel8(ormResult)) {
6438
6476
  outro2("\u5DF2\u53D6\u6D88");
6439
6477
  return;
6440
6478
  }
6441
- migration = await select2({
6479
+ orm = ormResult;
6480
+ const migrationResult = await select2({
6442
6481
  message: "\u9009\u62E9\u6570\u636E\u5E93\u8FC1\u79FB\u5DE5\u5177\uFF1A",
6443
6482
  options: [
6444
6483
  { value: "liquibase", label: "Liquibase" },
6445
6484
  { value: "none", label: "\u65E0" }
6446
6485
  ]
6447
6486
  });
6448
- if (isCancel8(migration)) {
6487
+ if (isCancel8(migrationResult)) {
6449
6488
  outro2("\u5DF2\u53D6\u6D88");
6450
6489
  return;
6451
6490
  }
6452
- aiChoice = await select2({
6491
+ migration = migrationResult;
6492
+ const aiResult = await select2({
6453
6493
  message: "\u9009\u62E9 AI \u6846\u67B6\uFF1A",
6454
6494
  options: [
6455
6495
  { value: "spring-ai", label: "Spring AI" },
6456
6496
  { value: "none", label: "\u65E0" }
6457
6497
  ]
6458
6498
  });
6459
- if (isCancel8(aiChoice)) {
6499
+ if (isCancel8(aiResult)) {
6460
6500
  outro2("\u5DF2\u53D6\u6D88");
6461
6501
  return;
6462
6502
  }
6503
+ aiChoice = aiResult;
6463
6504
  }
6464
6505
  if ((!frontendChoice || frontendChoice === "none") && (!backendChoice || backendChoice === "none")) {
6465
6506
  console.error("\u274C \u81F3\u5C11\u9700\u8981\u9009\u62E9\u524D\u7AEF\u6216\u540E\u7AEF\u4E4B\u4E00");
@@ -6481,18 +6522,19 @@ async function runInteractiveMode(targetDir) {
6481
6522
  return opts;
6482
6523
  }
6483
6524
  async function runInit(baseDir, opts) {
6484
- if (!opts.projectName) {
6485
- throw new Error("\u9879\u76EE\u540D\u79F0\u4E3A\u5FC5\u586B\u9879");
6486
- }
6487
- if (!VALID_PROJECT_NAME.test(opts.projectName)) {
6488
- 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`);
6525
+ const inPlace = !opts.projectName;
6526
+ const projectName = inPlace ? "project" : opts.projectName;
6527
+ if (!inPlace && !VALID_PROJECT_NAME.test(projectName)) {
6528
+ throw new Error(`\u9879\u76EE\u540D "${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`);
6489
6529
  }
6490
- const projectDir = path2.join(baseDir, opts.projectName);
6491
- if (fs2.existsSync(projectDir)) {
6530
+ const projectDir = inPlace ? baseDir : path2.join(baseDir, projectName);
6531
+ if (!inPlace && fs2.existsSync(projectDir)) {
6492
6532
  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`);
6493
6533
  }
6534
+ if (!inPlace) {
6535
+ fs2.mkdirSync(projectDir, { recursive: true });
6536
+ }
6494
6537
  const ctx = buildContext(opts);
6495
- fs2.mkdirSync(projectDir, { recursive: true });
6496
6538
  const hasFrontend = opts.frontend === "angular";
6497
6539
  const hasBackend = opts.backend === "java";
6498
6540
  try {
@@ -6506,13 +6548,18 @@ async function runInit(baseDir, opts) {
6506
6548
  console.log(`
6507
6549
  \u2714 \u9879\u76EE\u5DF2\u521B\u5EFA: ${projectDir}`);
6508
6550
  console.log("\n\u4E0B\u4E00\u6B65:");
6509
- console.log(` cd ${opts.projectName}`);
6551
+ if (!inPlace) {
6552
+ console.log(` cd ${opts.projectName}`);
6553
+ }
6510
6554
  if (opts.frontend) console.log(` pnpm install # \u5B89\u88C5\u524D\u7AEF\u4F9D\u8D56`);
6511
6555
  if (opts.backend) console.log(` ./gradlew build # \u6784\u5EFA\u540E\u7AEF`);
6512
6556
  console.log();
6513
6557
  printProjectTree(projectDir, hasFrontend, hasBackend);
6558
+ if (inPlace) {
6559
+ initClaudeMd(baseDir, opts);
6560
+ }
6514
6561
  } catch (err) {
6515
- if (fs2.existsSync(projectDir)) {
6562
+ if (!inPlace && fs2.existsSync(projectDir)) {
6516
6563
  fs2.rmSync(projectDir, { recursive: true, force: true });
6517
6564
  }
6518
6565
  throw err;
@@ -7018,7 +7065,7 @@ __pycache__/
7018
7065
  .vscode/
7019
7066
  *.iml
7020
7067
  `);
7021
- writeTemplate(projectDir, ".env.example", `# \u6570\u636E\u5E93\u914D\u7F6E
7068
+ writeEnvFile(projectDir, `# \u6570\u636E\u5E93\u914D\u7F6E
7022
7069
  DB_URL=jdbc:postgresql://localhost:5432/${ctx.packageName}
7023
7070
  DB_USERNAME=postgres
7024
7071
  DB_PASSWORD=change-me
@@ -7076,9 +7123,23 @@ function ensureDir2(dir) {
7076
7123
  }
7077
7124
  function writeTemplate(baseDir, relativePath, content) {
7078
7125
  const fullPath = path2.join(baseDir, relativePath);
7126
+ if (fs2.existsSync(fullPath)) {
7127
+ console.log(` \u2139 \u8DF3\u8FC7\u5DF2\u6709\u6587\u4EF6: ${relativePath}`);
7128
+ return;
7129
+ }
7079
7130
  ensureDir2(path2.dirname(fullPath));
7080
7131
  fs2.writeFileSync(fullPath, content, "utf-8");
7081
7132
  }
7133
+ function writeEnvFile(baseDir, content) {
7134
+ const envPath = path2.join(baseDir, ".env");
7135
+ ensureDir2(path2.dirname(envPath));
7136
+ if (fs2.existsSync(envPath)) {
7137
+ const existing = fs2.readFileSync(envPath, "utf-8").trimEnd();
7138
+ fs2.writeFileSync(envPath, existing + "\n\n" + content, "utf-8");
7139
+ } else {
7140
+ fs2.writeFileSync(envPath, content, "utf-8");
7141
+ }
7142
+ }
7082
7143
  function printProjectTree(projectDir, hasFrontend, hasBackend) {
7083
7144
  console.log("\u76EE\u5F55\u7ED3\u6784:");
7084
7145
  console.log(` ${path2.basename(projectDir)}/`);
@@ -7109,13 +7170,90 @@ function printProjectTree(projectDir, hasFrontend, hasBackend) {
7109
7170
  }
7110
7171
  }
7111
7172
 
7112
- // src/merger/mcp.ts
7173
+ // src/utils/auto-install.ts
7113
7174
  var fs3 = __toESM(require("node:fs"));
7175
+ var path3 = __toESM(require("node:path"));
7176
+ var import_node_child_process = require("node:child_process");
7177
+ var EXEC_OPTIONS = { encoding: "utf-8", timeout: 12e4, stdio: "pipe" };
7178
+ function execSafe(command) {
7179
+ try {
7180
+ const output = (0, import_node_child_process.execSync)(command, EXEC_OPTIONS);
7181
+ return { success: true, output: output.toString() };
7182
+ } catch (error) {
7183
+ const message = error instanceof Error ? error.message : String(error);
7184
+ return { success: false, output: message };
7185
+ }
7186
+ }
7187
+ function isBmadInstalled() {
7188
+ const result = execSafe("npx bmad-method status");
7189
+ return result.success && result.output.includes("Version:");
7190
+ }
7191
+ function isGrillMeInstalled(targetDir) {
7192
+ return fs3.existsSync(path3.join(targetDir, ".claude", "skills", "grill-me", "SKILL.md"));
7193
+ }
7194
+ function installBmadMethod() {
7195
+ if (isBmadInstalled()) {
7196
+ console.log("\u2139 BMAD Method \u5DF2\u5B58\u5728\uFF0C\u8DF3\u8FC7\u5B89\u88C5");
7197
+ return;
7198
+ }
7199
+ const result = execSafe("npx bmad-method install");
7200
+ if (result.success) {
7201
+ console.log("\u2714 BMAD Method \u5DF2\u5B89\u88C5");
7202
+ } else {
7203
+ console.log("\u26A0 BMAD Method \u5B89\u88C5\u5931\u8D25\uFF0C\u8BF7\u624B\u52A8\u6267\u884C npx bmad-method install");
7204
+ }
7205
+ }
7206
+ function installGrillMe(targetDir) {
7207
+ if (isGrillMeInstalled(targetDir)) {
7208
+ console.log("\u2139 grill-me \u5DF2\u5B58\u5728\uFF0C\u8DF3\u8FC7\u5B89\u88C5");
7209
+ return;
7210
+ }
7211
+ const skillDir = path3.join(targetDir, ".claude", "skills", "grill-me");
7212
+ fs3.mkdirSync(skillDir, { recursive: true });
7213
+ try {
7214
+ (0, import_node_child_process.execSync)(
7215
+ "curl -fsSL https://raw.githubusercontent.com/mattpocock/skills/main/grill-me/SKILL.md -o SKILL.md",
7216
+ { ...EXEC_OPTIONS, cwd: skillDir }
7217
+ );
7218
+ console.log("\u2714 grill-me skill \u5DF2\u5B89\u88C5");
7219
+ } catch {
7220
+ console.log("\u26A0 grill-me \u5B89\u88C5\u5931\u8D25\uFF0C\u8BF7\u624B\u52A8\u5B89\u88C5 https://github.com/mattpocock/skills");
7221
+ }
7222
+ }
7223
+ function isPlaywrightInstalled(targetDir) {
7224
+ const result = execSafe("npx playwright install --dry-run");
7225
+ return result.success && !result.output.toLowerCase().includes("to install");
7226
+ }
7227
+ function installPlaywright(config, targetDir) {
7228
+ if (config["sweep.e2eFramework"] !== "playwright") return;
7229
+ if (isPlaywrightInstalled(targetDir)) {
7230
+ console.log("\u2139 Playwright \u6D4F\u89C8\u5668\u5DF2\u5B58\u5728\uFF0C\u8DF3\u8FC7\u5B89\u88C5");
7231
+ return;
7232
+ }
7233
+ const result = execSafe("npx playwright install");
7234
+ if (result.success) {
7235
+ console.log("\u2714 Playwright \u6D4F\u89C8\u5668\u5DF2\u5B89\u88C5");
7236
+ } else {
7237
+ console.log("\u26A0 Playwright \u6D4F\u89C8\u5668\u5B89\u88C5\u5931\u8D25\uFF0C\u8BF7\u624B\u52A8\u6267\u884C npx playwright install");
7238
+ }
7239
+ }
7240
+ function step9AutoInstallDeps(tools, config, targetDir) {
7241
+ if (tools.includes("tide")) {
7242
+ installBmadMethod();
7243
+ installGrillMe(targetDir);
7244
+ }
7245
+ if (tools.includes("sweep")) {
7246
+ installPlaywright(config, targetDir);
7247
+ }
7248
+ }
7249
+
7250
+ // src/merger/mcp.ts
7251
+ var fs4 = __toESM(require("node:fs"));
7114
7252
  function mergeMcpServers(mcpPath, servers) {
7115
7253
  let mcp = {};
7116
7254
  try {
7117
- if (fs3.existsSync(mcpPath)) {
7118
- const raw = fs3.readFileSync(mcpPath, "utf-8");
7255
+ if (fs4.existsSync(mcpPath)) {
7256
+ const raw = fs4.readFileSync(mcpPath, "utf-8");
7119
7257
  mcp = JSON.parse(raw);
7120
7258
  }
7121
7259
  } catch {
@@ -7123,31 +7261,31 @@ function mergeMcpServers(mcpPath, servers) {
7123
7261
  }
7124
7262
  const existingServers = mcp.mcpServers || {};
7125
7263
  mcp.mcpServers = deepMerge(existingServers, servers);
7126
- fs3.writeFileSync(mcpPath, JSON.stringify(mcp, null, 2) + "\n", "utf-8");
7264
+ fs4.writeFileSync(mcpPath, JSON.stringify(mcp, null, 2) + "\n", "utf-8");
7127
7265
  }
7128
7266
 
7129
7267
  // src/merger/hooks.ts
7130
- var fs4 = __toESM(require("node:fs"));
7268
+ var fs5 = __toESM(require("node:fs"));
7131
7269
  function mergeHooks(hooksPath, hooks) {
7132
7270
  let existing = {};
7133
7271
  try {
7134
- if (fs4.existsSync(hooksPath)) {
7135
- const raw = fs4.readFileSync(hooksPath, "utf-8");
7272
+ if (fs5.existsSync(hooksPath)) {
7273
+ const raw = fs5.readFileSync(hooksPath, "utf-8");
7136
7274
  existing = JSON.parse(raw);
7137
7275
  }
7138
7276
  } catch {
7139
7277
  existing = {};
7140
7278
  }
7141
7279
  const merged = deepMerge(existing, hooks);
7142
- fs4.writeFileSync(hooksPath, JSON.stringify(merged, null, 2) + "\n", "utf-8");
7280
+ fs5.writeFileSync(hooksPath, JSON.stringify(merged, null, 2) + "\n", "utf-8");
7143
7281
  }
7144
7282
 
7145
7283
  // src/wizard/mcp-env.ts
7146
- var fs5 = __toESM(require("node:fs"));
7147
- var path3 = __toESM(require("node:path"));
7284
+ var fs6 = __toESM(require("node:fs"));
7285
+ var path4 = __toESM(require("node:path"));
7148
7286
  function parseEnvExampleFile(filePath) {
7149
- if (!fs5.existsSync(filePath)) return [];
7150
- const content = fs5.readFileSync(filePath, "utf-8");
7287
+ if (!fs6.existsSync(filePath)) return [];
7288
+ const content = fs6.readFileSync(filePath, "utf-8");
7151
7289
  const lines = content.split("\n");
7152
7290
  const entries = [];
7153
7291
  let lastComment = "";
@@ -7173,7 +7311,7 @@ function getMcpEnvStubs(selectedTools, examplesDir) {
7173
7311
  if (!examplesDir) return [];
7174
7312
  const result = [];
7175
7313
  for (const tool of selectedTools) {
7176
- const filePath = path3.join(examplesDir, `${tool}.env-example`);
7314
+ const filePath = path4.join(examplesDir, `${tool}.env-example`);
7177
7315
  const entries = parseEnvExampleFile(filePath);
7178
7316
  result.push(...entries);
7179
7317
  }
@@ -7182,9 +7320,9 @@ function getMcpEnvStubs(selectedTools, examplesDir) {
7182
7320
  function collectEnvSections(selectedTools, examplesDir, existingKeys) {
7183
7321
  const sections = [];
7184
7322
  for (const tool of selectedTools) {
7185
- const filePath = path3.join(examplesDir, `${tool}.env-example`);
7186
- if (!fs5.existsSync(filePath)) continue;
7187
- const content = fs5.readFileSync(filePath, "utf-8").trimEnd();
7323
+ const filePath = path4.join(examplesDir, `${tool}.env-example`);
7324
+ if (!fs6.existsSync(filePath)) continue;
7325
+ const content = fs6.readFileSync(filePath, "utf-8").trimEnd();
7188
7326
  const entries = parseEnvExampleFile(filePath);
7189
7327
  const allExist = entries.every((e) => existingKeys.has(e.key));
7190
7328
  if (allExist) continue;
@@ -7220,7 +7358,7 @@ function filterExistingKeys(content, existingKeys) {
7220
7358
 
7221
7359
  // src/wizard/wizard-flow.ts
7222
7360
  var p4 = __toESM(require("@clack/prompts"));
7223
- var fs7 = __toESM(require("node:fs"));
7361
+ var fs8 = __toESM(require("node:fs"));
7224
7362
 
7225
7363
  // src/wizard/tool-select.ts
7226
7364
  var p = __toESM(require("@clack/prompts"));
@@ -7612,7 +7750,7 @@ function parseFrontmatter(content) {
7612
7750
  }
7613
7751
 
7614
7752
  // src/template/registry.ts
7615
- var fs6 = __toESM(require("node:fs"));
7753
+ var fs7 = __toESM(require("node:fs"));
7616
7754
  function buildMcpCapabilities(mcpCapabilities, installedMcpServers, mcpTools) {
7617
7755
  const installedSet = new Set(installedMcpServers);
7618
7756
  const result = {};
@@ -7637,8 +7775,8 @@ function deriveVariableName(frontmatter) {
7637
7775
  return "tide_capabilities";
7638
7776
  }
7639
7777
  function injectSkillCapabilities(tmplFilePath, baseVariables, installedMcpServers, mcpTools, variableName) {
7640
- if (!fs6.existsSync(tmplFilePath)) return baseVariables;
7641
- const content = fs6.readFileSync(tmplFilePath, "utf-8");
7778
+ if (!fs7.existsSync(tmplFilePath)) return baseVariables;
7779
+ const content = fs7.readFileSync(tmplFilePath, "utf-8");
7642
7780
  const fm = parseFrontmatter(content);
7643
7781
  if (!fm) return baseVariables;
7644
7782
  const mcpCapabilities = fm.mcpCapabilities;
@@ -7732,9 +7870,9 @@ function buildTemplateVariables(registry2, config, installedMcpTools = []) {
7732
7870
  // src/wizard/wizard-flow.ts
7733
7871
  function loadExistingConfigKeys(targetDir) {
7734
7872
  const settingsPath = getDeepStormConfigPath(targetDir);
7735
- if (!fs7.existsSync(settingsPath)) return /* @__PURE__ */ new Set();
7873
+ if (!fs8.existsSync(settingsPath)) return /* @__PURE__ */ new Set();
7736
7874
  try {
7737
- const raw = fs7.readFileSync(settingsPath, "utf-8");
7875
+ const raw = fs8.readFileSync(settingsPath, "utf-8");
7738
7876
  const config = JSON.parse(raw);
7739
7877
  if (!config || Object.keys(config).length === 0) return /* @__PURE__ */ new Set();
7740
7878
  const keys = /* @__PURE__ */ new Set();
@@ -7793,16 +7931,16 @@ async function runWizardFlow(reader, registry2, initialMcpValues, targetDir) {
7793
7931
  }
7794
7932
 
7795
7933
  // src/wizard/reconfigure.ts
7796
- var fs8 = __toESM(require("node:fs"));
7797
- var path4 = __toESM(require("node:path"));
7934
+ var fs9 = __toESM(require("node:fs"));
7935
+ var path5 = __toESM(require("node:path"));
7798
7936
  function cleanInstalled(targetDir) {
7799
7937
  const settingsPath = getDeepStormConfigPath(targetDir);
7800
- if (!fs8.existsSync(settingsPath)) {
7938
+ if (!fs9.existsSync(settingsPath)) {
7801
7939
  return;
7802
7940
  }
7803
7941
  let config;
7804
7942
  try {
7805
- config = JSON.parse(fs8.readFileSync(settingsPath, "utf-8"));
7943
+ config = JSON.parse(fs9.readFileSync(settingsPath, "utf-8"));
7806
7944
  } catch {
7807
7945
  return;
7808
7946
  }
@@ -7810,41 +7948,41 @@ function cleanInstalled(targetDir) {
7810
7948
  const installedSkills = config.installedSkills;
7811
7949
  if (installedSkills) {
7812
7950
  for (const skillId of installedSkills) {
7813
- const skillDir = path4.join(targetDir, ".claude", "skills", skillId);
7814
- if (fs8.existsSync(skillDir)) {
7815
- fs8.rmSync(skillDir, { recursive: true, force: true });
7951
+ const skillDir = path5.join(targetDir, ".claude", "skills", skillId);
7952
+ if (fs9.existsSync(skillDir)) {
7953
+ fs9.rmSync(skillDir, { recursive: true, force: true });
7816
7954
  }
7817
7955
  }
7818
7956
  }
7819
7957
  const installedAgents = config.installedAgents;
7820
7958
  if (installedAgents) {
7821
7959
  for (const agent of installedAgents) {
7822
- const agentDir = path4.join(targetDir, ".claude", "agents", agent);
7823
- if (fs8.existsSync(agentDir)) {
7824
- fs8.rmSync(agentDir, { recursive: true, force: true });
7960
+ const agentDir = path5.join(targetDir, ".claude", "agents", agent);
7961
+ if (fs9.existsSync(agentDir)) {
7962
+ fs9.rmSync(agentDir, { recursive: true, force: true });
7825
7963
  }
7826
7964
  }
7827
7965
  }
7828
- const hooksJson = path4.join(targetDir, ".claude", "hooks.json");
7829
- if (fs8.existsSync(hooksJson)) {
7830
- fs8.rmSync(hooksJson, { force: true });
7966
+ const hooksJson = path5.join(targetDir, ".claude", "hooks.json");
7967
+ if (fs9.existsSync(hooksJson)) {
7968
+ fs9.rmSync(hooksJson, { force: true });
7831
7969
  }
7832
- const hooksDir = path4.join(targetDir, ".claude", "hooks");
7833
- if (fs8.existsSync(hooksDir)) {
7834
- fs8.rmSync(hooksDir, { recursive: true, force: true });
7970
+ const hooksDir = path5.join(targetDir, ".claude", "hooks");
7971
+ if (fs9.existsSync(hooksDir)) {
7972
+ fs9.rmSync(hooksDir, { recursive: true, force: true });
7835
7973
  }
7836
7974
  const installedMcp = config.installedMcpServers;
7837
7975
  if (installedMcp) {
7838
- const mcpPath = path4.join(targetDir, ".mcp.json");
7839
- if (fs8.existsSync(mcpPath)) {
7976
+ const mcpPath = path5.join(targetDir, ".mcp.json");
7977
+ if (fs9.existsSync(mcpPath)) {
7840
7978
  try {
7841
- const mcp = JSON.parse(fs8.readFileSync(mcpPath, "utf-8"));
7979
+ const mcp = JSON.parse(fs9.readFileSync(mcpPath, "utf-8"));
7842
7980
  if (mcp.mcpServers) {
7843
7981
  for (const serverName of installedMcp) {
7844
7982
  delete mcp.mcpServers[`deepstorm-${serverName}`];
7845
7983
  }
7846
7984
  }
7847
- fs8.writeFileSync(mcpPath, JSON.stringify(mcp, null, 2) + "\n", "utf-8");
7985
+ fs9.writeFileSync(mcpPath, JSON.stringify(mcp, null, 2) + "\n", "utf-8");
7848
7986
  } catch {
7849
7987
  }
7850
7988
  }
@@ -7871,8 +8009,8 @@ function parseNonInteractiveArgs(toolsStr, setValues) {
7871
8009
  }
7872
8010
 
7873
8011
  // src/wizard/guide.ts
7874
- var fs9 = __toESM(require("node:fs"));
7875
- var path5 = __toESM(require("node:path"));
8012
+ var fs10 = __toESM(require("node:fs"));
8013
+ var path6 = __toESM(require("node:path"));
7876
8014
  var import_prompts = require("@clack/prompts");
7877
8015
  function printMcpEnvStatus(mcpTools, installedMcpServices, examplesDir, targetDir) {
7878
8016
  const allMcp = [.../* @__PURE__ */ new Set([...mcpTools, ...installedMcpServices])];
@@ -7880,8 +8018,8 @@ function printMcpEnvStatus(mcpTools, installedMcpServices, examplesDir, targetDi
7880
8018
  console.log("");
7881
8019
  console.log(" \u73AF\u5883\u53D8\u91CF\u914D\u7F6E\u72B6\u6001\uFF1A");
7882
8020
  for (const mcp of allMcp) {
7883
- const filePath = path5.join(examplesDir, `${mcp}.env-example`);
7884
- if (!fs9.existsSync(filePath)) {
8021
+ const filePath = path6.join(examplesDir, `${mcp}.env-example`);
8022
+ if (!fs10.existsSync(filePath)) {
7885
8023
  console.log(` \u2139 ${mcp}: \u65E0\u9700\u73AF\u5883\u53D8\u91CF\u914D\u7F6E`);
7886
8024
  continue;
7887
8025
  }
@@ -7890,10 +8028,10 @@ function printMcpEnvStatus(mcpTools, installedMcpServices, examplesDir, targetDi
7890
8028
  console.log(` \u2139 ${mcp}: \u65E0\u9700\u73AF\u5883\u53D8\u91CF\u914D\u7F6E`);
7891
8029
  continue;
7892
8030
  }
7893
- const dotEnvPath = path5.join(targetDir, ".env");
8031
+ const dotEnvPath = path6.join(targetDir, ".env");
7894
8032
  const dotEnvMap = /* @__PURE__ */ new Map();
7895
- if (fs9.existsSync(dotEnvPath)) {
7896
- const content = fs9.readFileSync(dotEnvPath, "utf-8");
8033
+ if (fs10.existsSync(dotEnvPath)) {
8034
+ const content = fs10.readFileSync(dotEnvPath, "utf-8");
7897
8035
  for (const line of content.split("\n")) {
7898
8036
  const trimmed = line.trim();
7899
8037
  if (trimmed.includes("=") && !trimmed.startsWith("#")) {
@@ -7906,7 +8044,7 @@ function printMcpEnvStatus(mcpTools, installedMcpServices, examplesDir, targetDi
7906
8044
  }
7907
8045
  }
7908
8046
  }
7909
- const envDefaultContent = fs9.readFileSync(filePath, "utf-8");
8047
+ const envDefaultContent = fs10.readFileSync(filePath, "utf-8");
7910
8048
  const defaults = /* @__PURE__ */ new Map();
7911
8049
  for (const line of envDefaultContent.split("\n")) {
7912
8050
  const trimmed = line.trim();
@@ -7966,17 +8104,17 @@ async function printGuide(options) {
7966
8104
  console.log(" \u4E0B\u4E00\u6B65\uFF1A");
7967
8105
  console.log(" \u8FD0\u884C Claude Code\uFF0C\u8F93\u5165 /help \u67E5\u770B\u6240\u6709\u53EF\u7528\u7684 DeepStorm \u547D\u4EE4");
7968
8106
  console.log("");
7969
- const gitDir = path5.join(options.targetDir, ".git");
7970
- if (fs9.existsSync(gitDir)) {
8107
+ const gitDir = path6.join(options.targetDir, ".git");
8108
+ if (fs10.existsSync(gitDir)) {
7971
8109
  const shouldAdd = await (0, import_prompts.confirm)({
7972
8110
  message: "\u662F\u5426\u5C06 .claude/ \u914D\u7F6E\u63D0\u4EA4\u5230 Git\uFF1F(.gitignore \u9700\u8981\u5FFD\u7565 .claude/)",
7973
8111
  initialValue: false
7974
8112
  });
7975
8113
  if (!(0, import_prompts.isCancel)(shouldAdd) && shouldAdd) {
7976
- const gitignorePath = path5.join(options.targetDir, ".gitignore");
8114
+ const gitignorePath = path6.join(options.targetDir, ".gitignore");
7977
8115
  let isIgnored = false;
7978
- if (fs9.existsSync(gitignorePath)) {
7979
- const gitignore = fs9.readFileSync(gitignorePath, "utf-8");
8116
+ if (fs10.existsSync(gitignorePath)) {
8117
+ const gitignore = fs10.readFileSync(gitignorePath, "utf-8");
7980
8118
  isIgnored = gitignore.split("\n").some((line) => {
7981
8119
  const trimmed = line.trim();
7982
8120
  return trimmed === ".claude" || trimmed === ".claude/" || trimmed === ".claude/**";
@@ -7995,25 +8133,25 @@ async function printGuide(options) {
7995
8133
  }
7996
8134
 
7997
8135
  // src/template/renderer.ts
7998
- var fs11 = __toESM(require("node:fs"));
7999
- var path7 = __toESM(require("node:path"));
8136
+ var fs12 = __toESM(require("node:fs"));
8137
+ var path8 = __toESM(require("node:path"));
8000
8138
  var import_handlebars = __toESM(require_lib());
8001
8139
 
8002
8140
  // src/utils/fs.ts
8003
- var fs10 = __toESM(require("node:fs"));
8004
- var path6 = __toESM(require("node:path"));
8141
+ var fs11 = __toESM(require("node:fs"));
8142
+ var path7 = __toESM(require("node:path"));
8005
8143
  function ensureDir3(dir) {
8006
- fs10.mkdirSync(dir, { recursive: true });
8144
+ fs11.mkdirSync(dir, { recursive: true });
8007
8145
  }
8008
8146
  function copyDir(src, dest) {
8009
- fs10.cpSync(src, dest, { recursive: true, force: true });
8147
+ fs11.cpSync(src, dest, { recursive: true, force: true });
8010
8148
  }
8011
8149
  function removeDirContents(dir) {
8012
- const entries = fs10.readdirSync(dir);
8150
+ const entries = fs11.readdirSync(dir);
8013
8151
  for (const entry of entries) {
8014
8152
  if (entry === ".DS_Store") continue;
8015
- const fullPath = path6.join(dir, entry);
8016
- fs10.rmSync(fullPath, { recursive: true, force: true });
8153
+ const fullPath = path7.join(dir, entry);
8154
+ fs11.rmSync(fullPath, { recursive: true, force: true });
8017
8155
  }
8018
8156
  }
8019
8157
 
@@ -8034,38 +8172,38 @@ function toNested(vars) {
8034
8172
  }
8035
8173
  var compiledCache = /* @__PURE__ */ new Map();
8036
8174
  function renderTemplate(tmplPath, variables, outputPath) {
8037
- if (!fs11.existsSync(tmplPath)) {
8175
+ if (!fs12.existsSync(tmplPath)) {
8038
8176
  throw new Error(`\u6A21\u677F\u6587\u4EF6\u4E0D\u5B58\u5728: ${tmplPath}`);
8039
8177
  }
8040
8178
  let templateFn = compiledCache.get(tmplPath);
8041
8179
  if (!templateFn) {
8042
- const source = fs11.readFileSync(tmplPath, "utf-8");
8180
+ const source = fs12.readFileSync(tmplPath, "utf-8");
8043
8181
  templateFn = import_handlebars.default.compile(source, { noEscape: true });
8044
8182
  compiledCache.set(tmplPath, templateFn);
8045
8183
  }
8046
8184
  const nestedVars = toNested(variables);
8047
8185
  const content = templateFn(nestedVars);
8048
- ensureDir3(path7.dirname(outputPath));
8049
- fs11.writeFileSync(outputPath, content, "utf-8");
8186
+ ensureDir3(path8.dirname(outputPath));
8187
+ fs12.writeFileSync(outputPath, content, "utf-8");
8050
8188
  }
8051
8189
  function copyVariants(sourceVariantsDir, selectedValue, targetDir, clean = false) {
8052
- const variantDir = path7.join(sourceVariantsDir, selectedValue);
8053
- if (!fs11.existsSync(variantDir)) {
8190
+ const variantDir = path8.join(sourceVariantsDir, selectedValue);
8191
+ if (!fs12.existsSync(variantDir)) {
8054
8192
  console.warn(
8055
8193
  `[template] \u26A0 \u53D8\u4F53\u76EE\u5F55\u4E0D\u5B58\u5728: ${variantDir}\uFF08\u76F8\u5BF9\u4E8E ${sourceVariantsDir}\uFF09\uFF0C\u8DF3\u8FC7`
8056
8194
  );
8057
8195
  return;
8058
8196
  }
8059
- if (clean && fs11.existsSync(targetDir)) {
8197
+ if (clean && fs12.existsSync(targetDir)) {
8060
8198
  removeDirContents(targetDir);
8061
8199
  }
8062
8200
  ensureDir3(targetDir);
8063
- const entries = fs11.readdirSync(variantDir);
8201
+ const entries = fs12.readdirSync(variantDir);
8064
8202
  for (const entry of entries) {
8065
8203
  if (entry === ".DS_Store") continue;
8066
- const src = path7.join(variantDir, entry);
8067
- const dest = path7.join(targetDir, entry);
8068
- fs11.cpSync(src, dest, { recursive: true, force: true });
8204
+ const src = path8.join(variantDir, entry);
8205
+ const dest = path8.join(targetDir, entry);
8206
+ fs12.cpSync(src, dest, { recursive: true, force: true });
8069
8207
  }
8070
8208
  }
8071
8209
 
@@ -8093,7 +8231,7 @@ async function runSetup(reader, targetDir, cliDir2, options, registry2) {
8093
8231
  let selectedMcpTools = [];
8094
8232
  let templateVariables = {};
8095
8233
  let enabledMcpJsonServers = [];
8096
- const examplesDir = path8.join(cliDir2, "env-examples");
8234
+ const examplesDir = path9.join(cliDir2, "env-examples");
8097
8235
  const installedSkillIds = [];
8098
8236
  if (options.nonInteractive) {
8099
8237
  const parsed = parseNonInteractiveArgs(options.tools, options.set);
@@ -8121,7 +8259,7 @@ async function runSetup(reader, targetDir, cliDir2, options, registry2) {
8121
8259
  templateVariables = wizardResult.templateVariables;
8122
8260
  }
8123
8261
  if (selectedMcpTools.length > 0) {
8124
- const mcpPath = path8.join(targetDir, ".mcp.json");
8262
+ const mcpPath = path9.join(targetDir, ".mcp.json");
8125
8263
  const servers = loadMcpServerConfigs(cliDir2, selectedMcpTools);
8126
8264
  mergeMcpServers(mcpPath, servers);
8127
8265
  enabledMcpJsonServers = Object.keys(servers);
@@ -8133,13 +8271,13 @@ async function runSetup(reader, targetDir, cliDir2, options, registry2) {
8133
8271
  installedSkillIds.push(...ids);
8134
8272
  }
8135
8273
  if (shouldInstallGlobalHooks(tools, reader)) {
8136
- const hooksSrcDir = path8.join(cliDir2, "hooks");
8137
- const destHooksJson = path8.join(targetDir, ".claude", "hooks.json");
8274
+ const hooksSrcDir = path9.join(cliDir2, "hooks");
8275
+ const destHooksJson = path9.join(targetDir, ".claude", "hooks.json");
8138
8276
  for (const tool of tools) {
8139
- const toolHooksJsonPath = path8.join(hooksSrcDir, `${tool}-hooks.json`);
8140
- if (fs12.existsSync(toolHooksJsonPath)) {
8141
- ensureDir3(path8.join(targetDir, ".claude"));
8142
- const incoming = JSON.parse(fs12.readFileSync(toolHooksJsonPath, "utf-8"));
8277
+ const toolHooksJsonPath = path9.join(hooksSrcDir, `${tool}-hooks.json`);
8278
+ if (fs13.existsSync(toolHooksJsonPath)) {
8279
+ ensureDir3(path9.join(targetDir, ".claude"));
8280
+ const incoming = JSON.parse(fs13.readFileSync(toolHooksJsonPath, "utf-8"));
8143
8281
  mergeHooks(destHooksJson, incoming);
8144
8282
  }
8145
8283
  }
@@ -8165,7 +8303,7 @@ async function runSetup(reader, targetDir, cliDir2, options, registry2) {
8165
8303
  const frontend = nestedConfig.reef?.frontend?.framework ?? void 0;
8166
8304
  const backend = nestedConfig.reef?.backend?.language ?? void 0;
8167
8305
  initContextMap(targetDir, { frontend, backend, projectName: "" });
8168
- const claudeSettingsPath = path8.join(targetDir, ".claude", "settings.json");
8306
+ const claudeSettingsPath = path9.join(targetDir, ".claude", "settings.json");
8169
8307
  if (enabledMcpJsonServers.length > 0) {
8170
8308
  writeEnabledMcpJsonServers(claudeSettingsPath, enabledMcpJsonServers);
8171
8309
  const servers = loadMcpServerConfigs(cliDir2, selectedMcpTools);
@@ -8173,13 +8311,13 @@ async function runSetup(reader, targetDir, cliDir2, options, registry2) {
8173
8311
  }
8174
8312
  mergeSandboxDisabled(claudeSettingsPath);
8175
8313
  if (selectedMcpTools.length > 0) {
8176
- const envPath = path8.join(targetDir, ".env");
8314
+ const envPath = path9.join(targetDir, ".env");
8177
8315
  const existingKeys = readExistingEnvKeys(envPath);
8178
8316
  const sections = collectEnvSections(selectedMcpTools, examplesDir, existingKeys);
8179
8317
  if (sections.length > 0) {
8180
8318
  let existing = "";
8181
- if (fs12.existsSync(envPath)) {
8182
- existing = fs12.readFileSync(envPath, "utf-8").trimEnd();
8319
+ if (fs13.existsSync(envPath)) {
8320
+ existing = fs13.readFileSync(envPath, "utf-8").trimEnd();
8183
8321
  }
8184
8322
  const deepstormHeader = [
8185
8323
  "# \u2500\u2500 DeepStorm \u2500\u2500",
@@ -8194,7 +8332,7 @@ async function runSetup(reader, targetDir, cliDir2, options, registry2) {
8194
8332
  ""
8195
8333
  ].join("\n");
8196
8334
  const content = existing ? existing + "\n\n" + deepstormHeader + sections.join("\n\n") + "\n" : deepstormHeader + sections.join("\n\n") + "\n";
8197
- fs12.writeFileSync(envPath, content, "utf-8");
8335
+ fs13.writeFileSync(envPath, content, "utf-8");
8198
8336
  console.log(`\u2714 \u5DF2\u751F\u6210 .env \u73AF\u5883\u53D8\u91CF\u6A21\u677F`);
8199
8337
  }
8200
8338
  }
@@ -8210,6 +8348,7 @@ async function runSetup(reader, targetDir, cliDir2, options, registry2) {
8210
8348
  mcpTools: selectedMcpTools.length > 0 ? selectedMcpTools : void 0,
8211
8349
  mcpEnvStubs: mcpEnvStubs.length > 0 ? mcpEnvStubs : void 0
8212
8350
  });
8351
+ step9AutoInstallDeps(tools, config, targetDir);
8213
8352
  }
8214
8353
  function shouldSkipSkill(skill, config) {
8215
8354
  if (!skill.configKey) return false;
@@ -8229,9 +8368,9 @@ function shouldSkipAgent(agentFile, config) {
8229
8368
  }
8230
8369
  function renderToolAssets(tool, reader, cliDir2, targetDir, templateVariables, config, registry2, installedMcpTools = [], targetSubDir = ".claude", skillIdFilter) {
8231
8370
  const installedSkillIds = [];
8232
- const targetSkillsDir = targetSubDir ? path8.join(targetDir, targetSubDir, "skills") : path8.join(targetDir, "skills");
8371
+ const targetSkillsDir = targetSubDir ? path9.join(targetDir, targetSubDir, "skills") : path9.join(targetDir, "skills");
8233
8372
  const toolSkills = reader.getToolSkills(tool);
8234
- const skillsDir = path8.join(cliDir2, "skills");
8373
+ const skillsDir = path9.join(cliDir2, "skills");
8235
8374
  for (const skill of toolSkills) {
8236
8375
  const skillId = getSkillId(skill, registry2);
8237
8376
  if (!skillId) continue;
@@ -8240,12 +8379,12 @@ function renderToolAssets(tool, reader, cliDir2, targetDir, templateVariables, c
8240
8379
  console.log(` \u23ED ${skillId}\uFF1A\u4F9D\u8D56 ${skill.configKey} \u672A\u914D\u7F6E\uFF0C\u8DF3\u8FC7`);
8241
8380
  continue;
8242
8381
  }
8243
- const srcDir = path8.join(skillsDir, skillId);
8244
- const targetDirPath = path8.join(targetSkillsDir, skillId);
8245
- if (!fs12.existsSync(srcDir)) continue;
8246
- const tmplPath = path8.join(srcDir, "SKILL.md.tmpl");
8247
- const variantsDir = path8.join(srcDir, "variants");
8248
- if (fs12.existsSync(tmplPath)) {
8382
+ const srcDir = path9.join(skillsDir, skillId);
8383
+ const targetDirPath = path9.join(targetSkillsDir, skillId);
8384
+ if (!fs13.existsSync(srcDir)) continue;
8385
+ const tmplPath = path9.join(srcDir, "SKILL.md.tmpl");
8386
+ const variantsDir = path9.join(srcDir, "variants");
8387
+ if (fs13.existsSync(tmplPath)) {
8249
8388
  const enrichedVars = injectSkillCapabilities(
8250
8389
  tmplPath,
8251
8390
  templateVariables,
@@ -8256,7 +8395,7 @@ function renderToolAssets(tool, reader, cliDir2, targetDir, templateVariables, c
8256
8395
  renderTemplate(
8257
8396
  tmplPath,
8258
8397
  enrichedVars,
8259
- path8.join(targetDirPath, "SKILL.md")
8398
+ path9.join(targetDirPath, "SKILL.md")
8260
8399
  );
8261
8400
  copyVariantsForConfig(variantsDir, config, targetDirPath, skill.configKey);
8262
8401
  copyFragmentsForSkill(skillId, srcDir, config, registry2, targetDirPath);
@@ -8267,9 +8406,9 @@ function renderToolAssets(tool, reader, cliDir2, targetDir, templateVariables, c
8267
8406
  installedSkillIds.push(skillId);
8268
8407
  }
8269
8408
  const toolAgents = reader.getToolAgents(tool);
8270
- const agentsSrcDir = path8.join(cliDir2, "agents");
8271
- const targetAgentsDir = targetSubDir ? path8.join(targetDir, targetSubDir, "agents") : path8.join(targetDir, "agents");
8272
- if (fs12.existsSync(agentsSrcDir)) {
8409
+ const agentsSrcDir = path9.join(cliDir2, "agents");
8410
+ const targetAgentsDir = targetSubDir ? path9.join(targetDir, targetSubDir, "agents") : path9.join(targetDir, "agents");
8411
+ if (fs13.existsSync(agentsSrcDir)) {
8273
8412
  ensureDir3(targetAgentsDir);
8274
8413
  for (const agentFile of toolAgents) {
8275
8414
  if (shouldSkipAgent(agentFile, config)) {
@@ -8277,38 +8416,38 @@ function renderToolAssets(tool, reader, cliDir2, targetDir, templateVariables, c
8277
8416
  console.log(` \u23ED ${base}\uFF1A\u4F9D\u8D56\u672A\u914D\u7F6E\uFF0C\u8DF3\u8FC7`);
8278
8417
  continue;
8279
8418
  }
8280
- const srcPath = path8.join(agentsSrcDir, agentFile);
8281
- if (!fs12.existsSync(srcPath)) {
8282
- const tmplSrcPath = path8.join(agentsSrcDir, agentFile.replace(/\.md$/, ".md.tmpl"));
8283
- if (fs12.existsSync(tmplSrcPath)) {
8419
+ const srcPath = path9.join(agentsSrcDir, agentFile);
8420
+ if (!fs13.existsSync(srcPath)) {
8421
+ const tmplSrcPath = path9.join(agentsSrcDir, agentFile.replace(/\.md$/, ".md.tmpl"));
8422
+ if (fs13.existsSync(tmplSrcPath)) {
8284
8423
  const outputName = agentFile.replace(/\.tmpl$/, "");
8285
8424
  renderTemplate(
8286
8425
  tmplSrcPath,
8287
8426
  templateVariables,
8288
- path8.join(targetAgentsDir, outputName)
8427
+ path9.join(targetAgentsDir, outputName)
8289
8428
  );
8290
8429
  }
8291
8430
  continue;
8292
8431
  }
8293
- copyDir(srcPath, path8.join(targetAgentsDir, agentFile));
8432
+ copyDir(srcPath, path9.join(targetAgentsDir, agentFile));
8294
8433
  }
8295
8434
  }
8296
8435
  const toolHooks = reader.getToolHooks(tool);
8297
- const hooksSrcDir = path8.join(cliDir2, "hooks");
8298
- const targetHooksDir = targetSubDir ? path8.join(targetDir, targetSubDir, "hooks") : path8.join(targetDir, "hooks");
8299
- if (fs12.existsSync(hooksSrcDir)) {
8436
+ const hooksSrcDir = path9.join(cliDir2, "hooks");
8437
+ const targetHooksDir = targetSubDir ? path9.join(targetDir, targetSubDir, "hooks") : path9.join(targetDir, "hooks");
8438
+ if (fs13.existsSync(hooksSrcDir)) {
8300
8439
  ensureDir3(targetHooksDir);
8301
8440
  for (const hookFile of toolHooks) {
8302
- const srcPath = path8.join(hooksSrcDir, hookFile);
8303
- if (fs12.existsSync(srcPath)) {
8304
- copyDir(srcPath, path8.join(targetHooksDir, hookFile));
8441
+ const srcPath = path9.join(hooksSrcDir, hookFile);
8442
+ if (fs13.existsSync(srcPath)) {
8443
+ copyDir(srcPath, path9.join(targetHooksDir, hookFile));
8305
8444
  } else {
8306
8445
  const tmplPath = srcPath + ".tmpl";
8307
- if (fs12.existsSync(tmplPath)) {
8446
+ if (fs13.existsSync(tmplPath)) {
8308
8447
  renderTemplate(
8309
8448
  tmplPath,
8310
8449
  templateVariables,
8311
- path8.join(targetHooksDir, hookFile)
8450
+ path9.join(targetHooksDir, hookFile)
8312
8451
  );
8313
8452
  }
8314
8453
  }
@@ -8317,9 +8456,9 @@ function renderToolAssets(tool, reader, cliDir2, targetDir, templateVariables, c
8317
8456
  return installedSkillIds;
8318
8457
  }
8319
8458
  function installMcpSkills(tools, reader, cliDir2, targetDir, installedSkillIds, selectedMcpTools = []) {
8320
- const mcpSkillsDir = path8.join(cliDir2, "mcp-skills");
8321
- const targetSkillsDir = path8.join(targetDir, ".claude", "skills");
8322
- if (!fs12.existsSync(mcpSkillsDir)) return;
8459
+ const mcpSkillsDir = path9.join(cliDir2, "mcp-skills");
8460
+ const targetSkillsDir = path9.join(targetDir, ".claude", "skills");
8461
+ if (!fs13.existsSync(mcpSkillsDir)) return;
8323
8462
  if (selectedMcpTools.length === 0) {
8324
8463
  console.log("\u23ED \u672A\u9009\u62E9 MCP \u670D\u52A1\uFF0C\u8DF3\u8FC7 MCP \u6280\u80FD\u5B89\u88C5");
8325
8464
  return;
@@ -8336,9 +8475,9 @@ function installMcpSkills(tools, reader, cliDir2, targetDir, installedSkillIds,
8336
8475
  }
8337
8476
  let installed = 0;
8338
8477
  for (const skillId of neededSkills) {
8339
- const srcDir = path8.join(mcpSkillsDir, skillId);
8340
- if (fs12.existsSync(srcDir)) {
8341
- const targetDirPath = path8.join(targetSkillsDir, skillId);
8478
+ const srcDir = path9.join(mcpSkillsDir, skillId);
8479
+ if (fs13.existsSync(srcDir)) {
8480
+ const targetDirPath = path9.join(targetSkillsDir, skillId);
8342
8481
  copyDir(srcDir, targetDirPath);
8343
8482
  installedSkillIds.push(skillId);
8344
8483
  installed++;
@@ -8353,14 +8492,14 @@ function shouldInstallGlobalHooks(tools, reader) {
8353
8492
  }
8354
8493
  function buildUnifiedMcpCapabilities(cliDir2, installedMcpTools, mcpTools) {
8355
8494
  const allDeclarations = {};
8356
- const skillsDir = path8.join(cliDir2, "skills");
8357
- if (!fs12.existsSync(skillsDir)) return {};
8358
- const skillDirs = fs12.readdirSync(skillsDir, { withFileTypes: true });
8495
+ const skillsDir = path9.join(cliDir2, "skills");
8496
+ if (!fs13.existsSync(skillsDir)) return {};
8497
+ const skillDirs = fs13.readdirSync(skillsDir, { withFileTypes: true });
8359
8498
  for (const entry of skillDirs) {
8360
8499
  if (!entry.isDirectory()) continue;
8361
- const tmplPath = path8.join(skillsDir, entry.name, "SKILL.md.tmpl");
8362
- if (!fs12.existsSync(tmplPath)) continue;
8363
- const content = fs12.readFileSync(tmplPath, "utf-8");
8500
+ const tmplPath = path9.join(skillsDir, entry.name, "SKILL.md.tmpl");
8501
+ if (!fs13.existsSync(tmplPath)) continue;
8502
+ const content = fs13.readFileSync(tmplPath, "utf-8");
8364
8503
  const fm = parseFrontmatter(content);
8365
8504
  if (!fm) continue;
8366
8505
  const mcpCap = fm.mcpCapabilities;
@@ -8379,7 +8518,7 @@ function getSkillId(skill, registry2) {
8379
8518
  return void 0;
8380
8519
  }
8381
8520
  function copyVariantsForConfig(variantsDir, config, targetDir, configKey) {
8382
- if (!fs12.existsSync(variantsDir)) return;
8521
+ if (!fs13.existsSync(variantsDir)) return;
8383
8522
  for (const [key, value] of Object.entries(config)) {
8384
8523
  if (configKey && key !== configKey) continue;
8385
8524
  if (value.includes(",")) continue;
@@ -8387,8 +8526,8 @@ function copyVariantsForConfig(variantsDir, config, targetDir, configKey) {
8387
8526
  }
8388
8527
  }
8389
8528
  function copyFragmentsForSkill(skillId, srcDir, config, registry2, targetDir) {
8390
- const fragmentsDir = path8.join(srcDir, "fragments");
8391
- if (!fs12.existsSync(fragmentsDir)) return;
8529
+ const fragmentsDir = path9.join(srcDir, "fragments");
8530
+ if (!fs13.existsSync(fragmentsDir)) return;
8392
8531
  const selectedFragments = [];
8393
8532
  for (const wizard of Object.values(registry2.wizards)) {
8394
8533
  for (const question of wizard.questions) {
@@ -8396,43 +8535,43 @@ function copyFragmentsForSkill(skillId, srcDir, config, registry2, targetDir) {
8396
8535
  }
8397
8536
  }
8398
8537
  if (selectedFragments.length === 0) return;
8399
- const targetExamplesDir = path8.join(targetDir, "examples");
8538
+ const targetExamplesDir = path9.join(targetDir, "examples");
8400
8539
  for (const { category, value } of selectedFragments) {
8401
- const srcPath = path8.join(fragmentsDir, category, value);
8402
- if (!fs12.existsSync(srcPath)) continue;
8403
- const srcQr = path8.join(srcPath, "quick-reference.md");
8404
- if (fs12.existsSync(srcQr)) {
8405
- fs12.cpSync(srcQr, path8.join(targetDir, `${value}.md`), { force: true });
8406
- }
8407
- const srcExamples = path8.join(srcPath, "examples");
8408
- if (fs12.existsSync(srcExamples)) {
8409
- const exampleFiles = fs12.readdirSync(srcExamples);
8540
+ const srcPath = path9.join(fragmentsDir, category, value);
8541
+ if (!fs13.existsSync(srcPath)) continue;
8542
+ const srcQr = path9.join(srcPath, "quick-reference.md");
8543
+ if (fs13.existsSync(srcQr)) {
8544
+ fs13.cpSync(srcQr, path9.join(targetDir, `${value}.md`), { force: true });
8545
+ }
8546
+ const srcExamples = path9.join(srcPath, "examples");
8547
+ if (fs13.existsSync(srcExamples)) {
8548
+ const exampleFiles = fs13.readdirSync(srcExamples);
8410
8549
  for (const file of exampleFiles) {
8411
8550
  if (file === ".DS_Store") continue;
8412
8551
  ensureDir3(targetExamplesDir);
8413
- fs12.cpSync(
8414
- path8.join(srcExamples, file),
8415
- path8.join(targetExamplesDir, `${value}-${file}`),
8552
+ fs13.cpSync(
8553
+ path9.join(srcExamples, file),
8554
+ path9.join(targetExamplesDir, `${value}-${file}`),
8416
8555
  { force: true }
8417
8556
  );
8418
8557
  }
8419
8558
  }
8420
- const allFiles = fs12.readdirSync(srcPath);
8559
+ const allFiles = fs13.readdirSync(srcPath);
8421
8560
  for (const file of allFiles) {
8422
8561
  if (file === ".DS_Store") continue;
8423
8562
  if (file === "quick-reference.md") continue;
8424
8563
  if (file === "examples") continue;
8425
8564
  if (!file.endsWith(".md")) continue;
8426
- fs12.cpSync(path8.join(srcPath, file), path8.join(targetDir, file), { force: true });
8565
+ fs13.cpSync(path9.join(srcPath, file), path9.join(targetDir, file), { force: true });
8427
8566
  }
8428
8567
  }
8429
8568
  }
8430
8569
  function copyReferencesForSkill(srcDir, targetDir) {
8431
- const referencesDir = path8.join(srcDir, "references");
8432
- if (fs12.existsSync(referencesDir)) {
8433
- const targetReferencesDir = path8.join(targetDir, "references");
8570
+ const referencesDir = path9.join(srcDir, "references");
8571
+ if (fs13.existsSync(referencesDir)) {
8572
+ const targetReferencesDir = path9.join(targetDir, "references");
8434
8573
  ensureDir3(targetReferencesDir);
8435
- fs12.cpSync(referencesDir, targetReferencesDir, { recursive: true, force: true });
8574
+ fs13.cpSync(referencesDir, targetReferencesDir, { recursive: true, force: true });
8436
8575
  }
8437
8576
  }
8438
8577
  function collectFragmentsFromQuestion(question, config, selectedFragments) {
@@ -8458,15 +8597,15 @@ function collectFragmentsFromQuestion(question, config, selectedFragments) {
8458
8597
  }
8459
8598
  }
8460
8599
  function loadMcpServerConfigs(cliDir2, selectedTools) {
8461
- const mcpDir = path8.join(cliDir2, "mcp");
8462
- if (!fs12.existsSync(mcpDir)) return {};
8600
+ const mcpDir = path9.join(cliDir2, "mcp");
8601
+ if (!fs13.existsSync(mcpDir)) return {};
8463
8602
  const servers = {};
8464
8603
  function collectJsonFiles(dir) {
8465
8604
  const results = [];
8466
- for (const entry of fs12.readdirSync(dir)) {
8467
- const fullPath = path8.join(dir, entry);
8605
+ for (const entry of fs13.readdirSync(dir)) {
8606
+ const fullPath = path9.join(dir, entry);
8468
8607
  if (entry === ".DS_Store") continue;
8469
- if (fs12.statSync(fullPath).isDirectory()) {
8608
+ if (fs13.statSync(fullPath).isDirectory()) {
8470
8609
  results.push(...collectJsonFiles(fullPath));
8471
8610
  } else if (entry.endsWith(".json")) {
8472
8611
  results.push(fullPath);
@@ -8477,7 +8616,7 @@ function loadMcpServerConfigs(cliDir2, selectedTools) {
8477
8616
  const jsonFiles = collectJsonFiles(mcpDir);
8478
8617
  for (const jsonPath of jsonFiles) {
8479
8618
  try {
8480
- const data = JSON.parse(fs12.readFileSync(jsonPath, "utf-8"));
8619
+ const data = JSON.parse(fs13.readFileSync(jsonPath, "utf-8"));
8481
8620
  if (!data.name || !selectedTools.includes(data.name)) continue;
8482
8621
  if (!data.mcpServers || typeof data.mcpServers !== "object") continue;
8483
8622
  for (const [serverName, serverConfig] of Object.entries(data.mcpServers)) {
@@ -8523,37 +8662,37 @@ function writeEnabledMcpJsonServers(settingsPath, serverNames) {
8523
8662
  if (serverNames.length === 0) return;
8524
8663
  let settings = {};
8525
8664
  try {
8526
- if (fs12.existsSync(settingsPath)) {
8527
- const raw = fs12.readFileSync(settingsPath, "utf-8");
8665
+ if (fs13.existsSync(settingsPath)) {
8666
+ const raw = fs13.readFileSync(settingsPath, "utf-8");
8528
8667
  settings = JSON.parse(raw);
8529
8668
  }
8530
8669
  } catch {
8531
8670
  settings = {};
8532
8671
  }
8533
8672
  settings.enabledMcpjsonServers = serverNames;
8534
- ensureDir3(path8.dirname(settingsPath));
8535
- fs12.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf-8");
8673
+ ensureDir3(path9.dirname(settingsPath));
8674
+ fs13.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf-8");
8536
8675
  }
8537
8676
  function mergeSandboxDisabled(settingsPath) {
8538
8677
  let settings = {};
8539
8678
  try {
8540
- if (fs12.existsSync(settingsPath)) {
8541
- const raw = fs12.readFileSync(settingsPath, "utf-8");
8679
+ if (fs13.existsSync(settingsPath)) {
8680
+ const raw = fs13.readFileSync(settingsPath, "utf-8");
8542
8681
  settings = JSON.parse(raw);
8543
8682
  }
8544
8683
  } catch {
8545
8684
  settings = {};
8546
8685
  }
8547
8686
  settings.sandbox = { enabled: false };
8548
- ensureDir3(path8.dirname(settingsPath));
8549
- fs12.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf-8");
8687
+ ensureDir3(path9.dirname(settingsPath));
8688
+ fs13.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf-8");
8550
8689
  }
8551
8690
  function mergeSettingsMcpServers(settingsPath, servers) {
8552
8691
  if (!servers || Object.keys(servers).length === 0) return;
8553
8692
  let settings = {};
8554
8693
  try {
8555
- if (fs12.existsSync(settingsPath)) {
8556
- const raw = fs12.readFileSync(settingsPath, "utf-8");
8694
+ if (fs13.existsSync(settingsPath)) {
8695
+ const raw = fs13.readFileSync(settingsPath, "utf-8");
8557
8696
  settings = JSON.parse(raw);
8558
8697
  }
8559
8698
  } catch {
@@ -8561,13 +8700,13 @@ function mergeSettingsMcpServers(settingsPath, servers) {
8561
8700
  }
8562
8701
  const existingServers = settings.mcpServers || {};
8563
8702
  settings.mcpServers = deepMerge(existingServers, servers);
8564
- ensureDir3(path8.dirname(settingsPath));
8565
- fs12.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf-8");
8703
+ ensureDir3(path9.dirname(settingsPath));
8704
+ fs13.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf-8");
8566
8705
  }
8567
8706
  function readExistingEnvKeys(envPath) {
8568
8707
  const keys = /* @__PURE__ */ new Set();
8569
- if (!fs12.existsSync(envPath)) return keys;
8570
- for (const line of fs12.readFileSync(envPath, "utf-8").split("\n")) {
8708
+ if (!fs13.existsSync(envPath)) return keys;
8709
+ for (const line of fs13.readFileSync(envPath, "utf-8").split("\n")) {
8571
8710
  const trimmed = line.trim();
8572
8711
  if (!trimmed || trimmed.startsWith("#")) continue;
8573
8712
  const eqIdx = trimmed.indexOf("=");
@@ -8582,22 +8721,22 @@ function readExistingEnvKeys(envPath) {
8582
8721
  }
8583
8722
 
8584
8723
  // src/commands/plugin-build.ts
8585
- var fs14 = __toESM(require("node:fs"));
8586
- var path10 = __toESM(require("node:path"));
8724
+ var fs15 = __toESM(require("node:fs"));
8725
+ var path11 = __toESM(require("node:path"));
8587
8726
 
8588
8727
  // src/engine/plugin-builder.ts
8589
- var fs13 = __toESM(require("node:fs"));
8590
- var path9 = __toESM(require("node:path"));
8728
+ var fs14 = __toESM(require("node:fs"));
8729
+ var path10 = __toESM(require("node:path"));
8591
8730
  async function buildPlugin(config) {
8592
8731
  const { marketplaceName, tools, selectedMcpTools, cliDir: cliDir2, targetDir } = config;
8593
- const outputDir = path9.join(targetDir, ".deepstorm");
8594
- if (fs13.existsSync(outputDir)) {
8595
- fs13.rmSync(outputDir, { recursive: true, force: true });
8732
+ const outputDir = path10.join(targetDir, ".deepstorm");
8733
+ if (fs14.existsSync(outputDir)) {
8734
+ fs14.rmSync(outputDir, { recursive: true, force: true });
8596
8735
  }
8597
- fs13.mkdirSync(outputDir, { recursive: true });
8736
+ fs14.mkdirSync(outputDir, { recursive: true });
8598
8737
  const rootPkgMeta = readRootPackageJson(targetDir);
8599
- const claudePluginDir = path9.join(outputDir, ".claude-plugin");
8600
- fs13.mkdirSync(claudePluginDir, { recursive: true });
8738
+ const claudePluginDir = path10.join(outputDir, ".claude-plugin");
8739
+ fs14.mkdirSync(claudePluginDir, { recursive: true });
8601
8740
  const pluginJson = {
8602
8741
  name: "deepstorm",
8603
8742
  description: rootPkgMeta.description,
@@ -8606,7 +8745,7 @@ async function buildPlugin(config) {
8606
8745
  license: "MIT",
8607
8746
  keywords: ["deepstorm", "ai", "software-engineering", ...tools]
8608
8747
  };
8609
- fs13.writeFileSync(path9.join(claudePluginDir, "plugin.json"), JSON.stringify(pluginJson, null, 2), "utf-8");
8748
+ fs14.writeFileSync(path10.join(claudePluginDir, "plugin.json"), JSON.stringify(pluginJson, null, 2), "utf-8");
8610
8749
  const marketplaceJson = {
8611
8750
  name: marketplaceName,
8612
8751
  description: "DeepStorm Claude Code \u63D2\u4EF6",
@@ -8620,11 +8759,11 @@ async function buildPlugin(config) {
8620
8759
  }
8621
8760
  ]
8622
8761
  };
8623
- fs13.writeFileSync(path9.join(claudePluginDir, "marketplace.json"), JSON.stringify(marketplaceJson, null, 2), "utf-8");
8762
+ fs14.writeFileSync(path10.join(claudePluginDir, "marketplace.json"), JSON.stringify(marketplaceJson, null, 2), "utf-8");
8624
8763
  const settingsJson = {
8625
8764
  enabledMcpjsonServers: selectedMcpTools
8626
8765
  };
8627
- fs13.writeFileSync(path9.join(outputDir, "settings.json"), JSON.stringify(settingsJson, null, 2), "utf-8");
8766
+ fs14.writeFileSync(path10.join(outputDir, "settings.json"), JSON.stringify(settingsJson, null, 2), "utf-8");
8628
8767
  if (selectedMcpTools.length > 0) {
8629
8768
  const mcpServers = {};
8630
8769
  for (const mcpName of selectedMcpTools) {
@@ -8634,46 +8773,48 @@ async function buildPlugin(config) {
8634
8773
  }
8635
8774
  }
8636
8775
  if (Object.keys(mcpServers).length > 0) {
8637
- fs13.writeFileSync(
8638
- path9.join(outputDir, ".mcp.json"),
8776
+ fs14.writeFileSync(
8777
+ path10.join(outputDir, ".mcp.json"),
8639
8778
  JSON.stringify({ mcpServers }, null, 2) + "\n",
8640
8779
  "utf-8"
8641
8780
  );
8642
8781
  }
8643
8782
  }
8644
8783
  if (selectedMcpTools.length > 0) {
8645
- const envPath = path9.join(outputDir, ".env.example");
8646
- const envLines = [
8647
- "# DeepStorm Plugin MCP \u73AF\u5883\u53D8\u91CF\u914D\u7F6E",
8648
- "# \u590D\u5236\u6B64\u6587\u4EF6\u4E3A .env \u5E76\u586B\u5199\u5B9E\u9645\u503C",
8649
- ""
8650
- ];
8784
+ const envPath = path10.join(targetDir, ".env");
8785
+ const header = "# \u2500\u2500 DeepStorm Plugin MCP \u73AF\u5883\u53D8\u91CF \u2500\u2500\n\n";
8786
+ const sections = [];
8651
8787
  for (const mcpName of selectedMcpTools) {
8652
- const envExampleFile = path9.join(cliDir2, "env-examples", `${mcpName}.env-example`);
8653
- if (fs13.existsSync(envExampleFile)) {
8654
- const content = fs13.readFileSync(envExampleFile, "utf-8");
8655
- envLines.push(`# ${mcpName}`);
8656
- envLines.push(content);
8657
- envLines.push("");
8788
+ const envExampleFile = path10.join(cliDir2, "env-examples", `${mcpName}.env-example`);
8789
+ if (fs14.existsSync(envExampleFile)) {
8790
+ const content = fs14.readFileSync(envExampleFile, "utf-8");
8791
+ sections.push(`# ${mcpName}`);
8792
+ sections.push(content);
8658
8793
  }
8659
8794
  }
8660
- fs13.writeFileSync(envPath, envLines.join("\n"), "utf-8");
8795
+ const newContent = header + sections.join("\n") + "\n";
8796
+ if (fs14.existsSync(envPath)) {
8797
+ const existing = fs14.readFileSync(envPath, "utf-8").trimEnd();
8798
+ fs14.writeFileSync(envPath, existing + "\n\n" + newContent, "utf-8");
8799
+ } else {
8800
+ fs14.writeFileSync(envPath, newContent, "utf-8");
8801
+ }
8661
8802
  }
8662
8803
  const readmeContent = generateReadme2(marketplaceName, tools, selectedMcpTools, rootPkgMeta.version);
8663
- fs13.writeFileSync(path9.join(outputDir, "README.md"), readmeContent, "utf-8");
8804
+ fs14.writeFileSync(path10.join(outputDir, "README.md"), readmeContent, "utf-8");
8664
8805
  const changelogContent = `# Changelog
8665
8806
 
8666
8807
  ## v${rootPkgMeta.version}
8667
8808
 
8668
8809
  - \u9996\u6B21\u6784\u5EFA DeepStorm Plugin
8669
8810
  `;
8670
- fs13.writeFileSync(path9.join(outputDir, "CHANGELOG.md"), changelogContent, "utf-8");
8811
+ fs14.writeFileSync(path10.join(outputDir, "CHANGELOG.md"), changelogContent, "utf-8");
8671
8812
  return outputDir;
8672
8813
  }
8673
8814
  function readRootPackageJson(targetDir) {
8674
- const pkgPath = path9.join(targetDir, "package.json");
8815
+ const pkgPath = path10.join(targetDir, "package.json");
8675
8816
  try {
8676
- const pkg = JSON.parse(fs13.readFileSync(pkgPath, "utf-8"));
8817
+ const pkg = JSON.parse(fs14.readFileSync(pkgPath, "utf-8"));
8677
8818
  return {
8678
8819
  version: pkg.version || "0.1.0",
8679
8820
  description: pkg.description || "DeepStorm \u2014 Spec \u9A71\u52A8\u7684 AI \u534F\u540C\u8F6F\u4EF6\u5DE5\u7A0B\u5B9E\u8DF5\u5DE5\u5177\u96C6"
@@ -8713,7 +8854,7 @@ function generateReadme2(marketplaceName, tools, selectedMcpTools, version) {
8713
8854
  "",
8714
8855
  "## \u73AF\u5883\u53D8\u91CF",
8715
8856
  "",
8716
- "\u590D\u5236 .env.example \u4E3A .env\uFF0C\u586B\u5199\u5BF9\u5E94\u7684 API Token \u540E\u91CD\u542F Claude Code \u4F1A\u8BDD\u3002",
8857
+ "\u7F16\u8F91 .env \u6587\u4EF6\uFF0C\u586B\u5199\u5BF9\u5E94\u7684 API Token \u540E\u91CD\u542F Claude Code \u4F1A\u8BDD\u3002",
8717
8858
  "",
8718
8859
  "## \u5F00\u53D1",
8719
8860
  "",
@@ -8725,16 +8866,16 @@ function generateReadme2(marketplaceName, tools, selectedMcpTools, version) {
8725
8866
  return lines.join("\n");
8726
8867
  }
8727
8868
  function readMcpServerConfig(cliDir2, mcpName) {
8728
- const mcpDir = path9.join(cliDir2, "mcp");
8729
- if (!fs13.existsSync(mcpDir)) return null;
8730
- const entries = fs13.readdirSync(mcpDir, { withFileTypes: true });
8869
+ const mcpDir = path10.join(cliDir2, "mcp");
8870
+ if (!fs14.existsSync(mcpDir)) return null;
8871
+ const entries = fs14.readdirSync(mcpDir, { withFileTypes: true });
8731
8872
  for (const entry of entries) {
8732
8873
  if (!entry.isDirectory()) continue;
8733
- const domainDir = path9.join(mcpDir, entry.name);
8734
- const files = fs13.readdirSync(domainDir).filter((f) => f.endsWith(".json"));
8874
+ const domainDir = path10.join(mcpDir, entry.name);
8875
+ const files = fs14.readdirSync(domainDir).filter((f) => f.endsWith(".json"));
8735
8876
  for (const file of files) {
8736
8877
  try {
8737
- const content = JSON.parse(fs13.readFileSync(path9.join(domainDir, file), "utf-8"));
8878
+ const content = JSON.parse(fs14.readFileSync(path10.join(domainDir, file), "utf-8"));
8738
8879
  if (content.name === mcpName && content.mcpServers) {
8739
8880
  const servers = content.mcpServers;
8740
8881
  const keys = Object.keys(servers);
@@ -8830,27 +8971,27 @@ function registerPluginBuildCommand(program2, registry2) {
8830
8971
  });
8831
8972
  }
8832
8973
  function updatePluginJsonHooks(pluginDir) {
8833
- const hooksDir = path10.join(pluginDir, "hooks");
8834
- const pluginJsonPath = path10.join(pluginDir, ".claude-plugin", "plugin.json");
8835
- if (!fs14.existsSync(hooksDir) || !fs14.existsSync(pluginJsonPath)) return;
8974
+ const hooksDir = path11.join(pluginDir, "hooks");
8975
+ const pluginJsonPath = path11.join(pluginDir, ".claude-plugin", "plugin.json");
8976
+ if (!fs15.existsSync(hooksDir) || !fs15.existsSync(pluginJsonPath)) return;
8836
8977
  try {
8837
- const pluginJson = JSON.parse(fs14.readFileSync(pluginJsonPath, "utf-8"));
8978
+ const pluginJson = JSON.parse(fs15.readFileSync(pluginJsonPath, "utf-8"));
8838
8979
  pluginJson.hooks = "./hooks/deepstorm-hooks.json";
8839
- fs14.writeFileSync(pluginJsonPath, JSON.stringify(pluginJson, null, 2) + "\n", "utf-8");
8980
+ fs15.writeFileSync(pluginJsonPath, JSON.stringify(pluginJson, null, 2) + "\n", "utf-8");
8840
8981
  console.log("\u2714 plugin.json \u5DF2\u6DFB\u52A0 hooks \u58F0\u660E");
8841
8982
  } catch {
8842
8983
  }
8843
8984
  }
8844
8985
  function ensureGitIgnore(targetDir) {
8845
- const gitIgnorePath = path10.join(targetDir, ".gitignore");
8986
+ const gitIgnorePath = path11.join(targetDir, ".gitignore");
8846
8987
  const line = ".deepstorm/";
8847
8988
  try {
8848
- if (fs14.existsSync(gitIgnorePath)) {
8849
- const content = fs14.readFileSync(gitIgnorePath, "utf-8");
8989
+ if (fs15.existsSync(gitIgnorePath)) {
8990
+ const content = fs15.readFileSync(gitIgnorePath, "utf-8");
8850
8991
  if (content.includes(line)) return;
8851
- fs14.writeFileSync(gitIgnorePath, content.trimEnd() + "\n" + line + "\n", "utf-8");
8992
+ fs15.writeFileSync(gitIgnorePath, content.trimEnd() + "\n" + line + "\n", "utf-8");
8852
8993
  } else {
8853
- fs14.writeFileSync(gitIgnorePath, line + "\n", "utf-8");
8994
+ fs15.writeFileSync(gitIgnorePath, line + "\n", "utf-8");
8854
8995
  }
8855
8996
  console.log("\u2714 .gitignore \u5DF2\u6DFB\u52A0 .deepstorm/ \u5FFD\u7565\u89C4\u5219");
8856
8997
  } catch {
@@ -8858,14 +8999,14 @@ function ensureGitIgnore(targetDir) {
8858
8999
  }
8859
9000
  function mergePluginHooks(tools, reader, pluginDir, packagesDir) {
8860
9001
  if (!tools.some((tool) => reader.getToolHooks(tool).length > 0)) return;
8861
- const pkgsDir = packagesDir ?? path10.resolve(process.cwd(), "packages");
8862
- const pluginHooksDir = path10.join(pluginDir, "hooks");
8863
- const destHooksJson = path10.join(pluginHooksDir, "deepstorm-hooks.json");
9002
+ const pkgsDir = packagesDir ?? path11.resolve(process.cwd(), "packages");
9003
+ const pluginHooksDir = path11.join(pluginDir, "hooks");
9004
+ const destHooksJson = path11.join(pluginHooksDir, "deepstorm-hooks.json");
8864
9005
  for (const tool of tools) {
8865
- const srcPath = path10.join(pkgsDir, tool, "hooks", "hooks.json");
8866
- if (fs14.existsSync(srcPath)) {
8867
- fs14.mkdirSync(pluginHooksDir, { recursive: true });
8868
- const incoming = JSON.parse(fs14.readFileSync(srcPath, "utf-8"));
9006
+ const srcPath = path11.join(pkgsDir, tool, "hooks", "hooks.json");
9007
+ if (fs15.existsSync(srcPath)) {
9008
+ fs15.mkdirSync(pluginHooksDir, { recursive: true });
9009
+ const incoming = JSON.parse(fs15.readFileSync(srcPath, "utf-8"));
8869
9010
  mergeHooks(destHooksJson, incoming);
8870
9011
  }
8871
9012
  }
@@ -8886,24 +9027,24 @@ function viewConfig(targetDir) {
8886
9027
  }
8887
9028
 
8888
9029
  // src/commands/config-set.ts
8889
- var fs16 = __toESM(require("node:fs"));
8890
- var path12 = __toESM(require("node:path"));
9030
+ var fs17 = __toESM(require("node:fs"));
9031
+ var path13 = __toESM(require("node:path"));
8891
9032
  var p6 = __toESM(require("@clack/prompts"));
8892
9033
 
8893
9034
  // src/utils/config-schema.ts
8894
- var fs15 = __toESM(require("node:fs"));
8895
- var path11 = __toESM(require("node:path"));
9035
+ var fs16 = __toESM(require("node:fs"));
9036
+ var path12 = __toESM(require("node:path"));
8896
9037
  function loadValidConfigKeys() {
8897
9038
  const candidates = [
8898
- path11.resolve(__dirname, "config-schema.json"),
8899
- path11.resolve(__dirname, "..", "config-schema.json"),
8900
- path11.resolve(process.cwd(), "config-schema.json"),
8901
- path11.resolve(process.cwd(), "packages", "cli", "config-schema.json")
9039
+ path12.resolve(__dirname, "config-schema.json"),
9040
+ path12.resolve(__dirname, "..", "config-schema.json"),
9041
+ path12.resolve(process.cwd(), "config-schema.json"),
9042
+ path12.resolve(process.cwd(), "packages", "cli", "config-schema.json")
8902
9043
  ];
8903
9044
  for (const schemaPath of candidates) {
8904
9045
  try {
8905
- if (!fs15.existsSync(schemaPath)) continue;
8906
- const schema = JSON.parse(fs15.readFileSync(schemaPath, "utf-8"));
9046
+ if (!fs16.existsSync(schemaPath)) continue;
9047
+ const schema = JSON.parse(fs16.readFileSync(schemaPath, "utf-8"));
8907
9048
  const keys = /* @__PURE__ */ new Set();
8908
9049
  collectLeafPaths(schema.properties, "", keys);
8909
9050
  return keys;
@@ -8941,9 +9082,9 @@ async function setConfigValue(targetDir, key, value, registry2) {
8941
9082
  const settingsPath = getDeepStormConfigPath(targetDir);
8942
9083
  readDeepStormConfig(targetDir);
8943
9084
  let config = {};
8944
- if (fs16.existsSync(settingsPath)) {
9085
+ if (fs17.existsSync(settingsPath)) {
8945
9086
  try {
8946
- config = JSON.parse(fs16.readFileSync(settingsPath, "utf-8"));
9087
+ config = JSON.parse(fs17.readFileSync(settingsPath, "utf-8"));
8947
9088
  } catch {
8948
9089
  config = {};
8949
9090
  }
@@ -8977,7 +9118,7 @@ async function setConfigValue(targetDir, key, value, registry2) {
8977
9118
  writePointer = writePointer[parts[i]];
8978
9119
  }
8979
9120
  writePointer[parts[parts.length - 1]] = value;
8980
- fs16.writeFileSync(settingsPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
9121
+ fs17.writeFileSync(settingsPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
8981
9122
  console.log(`\u2714 ${key} \u5DF2\u66F4\u65B0\u4E3A ${value}`);
8982
9123
  const affected = findAffectedTemplates(registry2, key);
8983
9124
  if (affected.length === 0) {
@@ -9015,8 +9156,8 @@ async function setConfigValue(targetDir, key, value, registry2) {
9015
9156
  const templateVariables = buildTemplateVariables(registry2, fullConfig, installedMcpServers);
9016
9157
  let renderCount = 0;
9017
9158
  for (const tmplRelPath of affected) {
9018
- const tmplPath = path12.join(cliDir, tmplRelPath);
9019
- if (!fs16.existsSync(tmplPath)) {
9159
+ const tmplPath = path13.join(cliDir, tmplRelPath);
9160
+ if (!fs17.existsSync(tmplPath)) {
9020
9161
  console.warn(` \u26A0 \u6A21\u677F\u6587\u4EF6\u4E0D\u5B58\u5728: ${tmplRelPath}\uFF0C\u8DF3\u8FC7`);
9021
9162
  continue;
9022
9163
  }
@@ -9024,12 +9165,12 @@ async function setConfigValue(targetDir, key, value, registry2) {
9024
9165
  const assetType = pathParts[0];
9025
9166
  const assetName = pathParts[1];
9026
9167
  const outputFile = pathParts[pathParts.length - 1].replace(/\.tmpl$/, "");
9027
- const targetDirPath = path12.join(targetDir, ".claude", assetType, assetName);
9168
+ const targetDirPath = path13.join(targetDir, ".claude", assetType, assetName);
9028
9169
  ensureDir3(targetDirPath);
9029
- const outputPath = path12.join(targetDirPath, outputFile);
9170
+ const outputPath = path13.join(targetDirPath, outputFile);
9030
9171
  renderTemplate(tmplPath, templateVariables, outputPath);
9031
- const variantsDir = path12.join(cliDir, assetType, assetName, "variants");
9032
- if (fs16.existsSync(variantsDir)) {
9172
+ const variantsDir = path13.join(cliDir, assetType, assetName, "variants");
9173
+ if (fs17.existsSync(variantsDir)) {
9033
9174
  copyVariants(variantsDir, value, targetDirPath, true);
9034
9175
  }
9035
9176
  renderCount++;
@@ -9039,43 +9180,43 @@ async function setConfigValue(targetDir, key, value, registry2) {
9039
9180
  }
9040
9181
 
9041
9182
  // src/commands/config-reset.ts
9042
- var fs17 = __toESM(require("node:fs"));
9043
- var path13 = __toESM(require("node:path"));
9183
+ var fs18 = __toESM(require("node:fs"));
9184
+ var path14 = __toESM(require("node:path"));
9044
9185
  function resetConfig(targetDir) {
9045
- const settingsPath = path13.join(targetDir, ".deepstorm", "settings.json");
9046
- if (!fs17.existsSync(settingsPath)) return;
9186
+ const settingsPath = path14.join(targetDir, ".deepstorm", "settings.json");
9187
+ if (!fs18.existsSync(settingsPath)) return;
9047
9188
  try {
9048
- fs17.unlinkSync(settingsPath);
9189
+ fs18.unlinkSync(settingsPath);
9049
9190
  console.log("\u2714 \u5DF2\u6E05\u9664 DeepStorm \u914D\u7F6E");
9050
9191
  } catch {
9051
9192
  }
9052
9193
  }
9053
9194
 
9054
9195
  // src/commands/config-refresh.ts
9055
- var fs18 = __toESM(require("node:fs"));
9056
- var path14 = __toESM(require("node:path"));
9196
+ var fs19 = __toESM(require("node:fs"));
9197
+ var path15 = __toESM(require("node:path"));
9057
9198
  function refreshConfig(cliDir2, targetDir, registry2) {
9058
9199
  const result = { refreshed: [], errors: [] };
9059
9200
  const settingsPath = getDeepStormConfigPath(targetDir);
9060
- if (!fs18.existsSync(settingsPath)) {
9201
+ if (!fs19.existsSync(settingsPath)) {
9061
9202
  return result;
9062
9203
  }
9063
9204
  readDeepStormConfig(targetDir);
9064
9205
  let config;
9065
9206
  try {
9066
- config = JSON.parse(fs18.readFileSync(settingsPath, "utf-8"));
9207
+ config = JSON.parse(fs19.readFileSync(settingsPath, "utf-8"));
9067
9208
  } catch {
9068
9209
  return result;
9069
9210
  }
9070
9211
  const installedSkills = config.installedSkills ?? [];
9071
9212
  const installedMcpServers = config.installedMcpServers ?? [];
9072
- const targetDotClaudeDir = path14.join(targetDir, ".claude");
9213
+ const targetDotClaudeDir = path15.join(targetDir, ".claude");
9073
9214
  if (installedSkills.length === 0) return result;
9074
9215
  for (const skillId of installedSkills) {
9075
- const tmplPath = path14.join(cliDir2, "skills", skillId, "SKILL.md.tmpl");
9076
- if (!fs18.existsSync(tmplPath)) continue;
9077
- const targetSkillDir = path14.join(targetDotClaudeDir, "skills", skillId);
9078
- const outputPath = path14.join(targetSkillDir, "SKILL.md");
9216
+ const tmplPath = path15.join(cliDir2, "skills", skillId, "SKILL.md.tmpl");
9217
+ if (!fs19.existsSync(tmplPath)) continue;
9218
+ const targetSkillDir = path15.join(targetDotClaudeDir, "skills", skillId);
9219
+ const outputPath = path15.join(targetSkillDir, "SKILL.md");
9079
9220
  try {
9080
9221
  const enrichedVars = injectSkillCapabilities(
9081
9222
  tmplPath,
@@ -9083,7 +9224,7 @@ function refreshConfig(cliDir2, targetDir, registry2) {
9083
9224
  installedMcpServers,
9084
9225
  registry2.mcpTools ?? {}
9085
9226
  );
9086
- fs18.mkdirSync(targetSkillDir, { recursive: true });
9227
+ fs19.mkdirSync(targetSkillDir, { recursive: true });
9087
9228
  renderTemplate(tmplPath, enrichedVars, outputPath);
9088
9229
  result.refreshed.push(skillId);
9089
9230
  } catch (err) {
@@ -9100,14 +9241,14 @@ function refreshConfig(cliDir2, targetDir, registry2) {
9100
9241
  }
9101
9242
  function buildUnifiedMcpCapabilities2(cliDir2, installedMcpTools, mcpTools) {
9102
9243
  const allDeclarations = {};
9103
- const skillsDir = path14.join(cliDir2, "skills");
9104
- if (!fs18.existsSync(skillsDir)) return {};
9105
- const skillDirs = fs18.readdirSync(skillsDir, { withFileTypes: true });
9244
+ const skillsDir = path15.join(cliDir2, "skills");
9245
+ if (!fs19.existsSync(skillsDir)) return {};
9246
+ const skillDirs = fs19.readdirSync(skillsDir, { withFileTypes: true });
9106
9247
  for (const entry of skillDirs) {
9107
9248
  if (!entry.isDirectory()) continue;
9108
- const tmplPath = path14.join(skillsDir, entry.name, "SKILL.md.tmpl");
9109
- if (!fs18.existsSync(tmplPath)) continue;
9110
- const content = fs18.readFileSync(tmplPath, "utf-8");
9249
+ const tmplPath = path15.join(skillsDir, entry.name, "SKILL.md.tmpl");
9250
+ if (!fs19.existsSync(tmplPath)) continue;
9251
+ const content = fs19.readFileSync(tmplPath, "utf-8");
9111
9252
  const fm = parseFrontmatter(content);
9112
9253
  if (!fm) continue;
9113
9254
  const mcpCap = fm.mcpCapabilities;
@@ -9190,17 +9331,17 @@ function listTemplates(registry2, tool) {
9190
9331
  }
9191
9332
 
9192
9333
  // src/commands/template-init.ts
9193
- var fs19 = __toESM(require("node:fs"));
9194
- var path15 = __toESM(require("node:path"));
9334
+ var fs20 = __toESM(require("node:fs"));
9335
+ var path16 = __toESM(require("node:path"));
9195
9336
  var import_prompts3 = require("@clack/prompts");
9196
9337
  async function initTemplate(cliDir2, targetDir, skillId) {
9197
- const srcDir = path15.join(cliDir2, "skills", skillId);
9198
- const destDir = path15.join(targetDir, ".deepstorm", "templates", skillId);
9199
- if (!fs19.existsSync(srcDir)) {
9338
+ const srcDir = path16.join(cliDir2, "skills", skillId);
9339
+ const destDir = path16.join(targetDir, ".deepstorm", "templates", skillId);
9340
+ if (!fs20.existsSync(srcDir)) {
9200
9341
  console.log(`\u6A21\u677F\u4E0D\u5B58\u5728\uFF1A${skillId}`);
9201
9342
  return;
9202
9343
  }
9203
- if (fs19.existsSync(destDir)) {
9344
+ if (fs20.existsSync(destDir)) {
9204
9345
  const shouldOverwrite = await (0, import_prompts3.confirm)({
9205
9346
  message: `\u6A21\u677F ${skillId} \u5DF2\u5B58\u5728\uFF0C\u662F\u5426\u8986\u76D6\uFF1F`,
9206
9347
  initialValue: false
@@ -9209,21 +9350,21 @@ async function initTemplate(cliDir2, targetDir, skillId) {
9209
9350
  console.log("\u5DF2\u53D6\u6D88");
9210
9351
  return;
9211
9352
  }
9212
- fs19.rmSync(destDir, { recursive: true, force: true });
9353
+ fs20.rmSync(destDir, { recursive: true, force: true });
9213
9354
  }
9214
- ensureDir3(path15.dirname(destDir));
9355
+ ensureDir3(path16.dirname(destDir));
9215
9356
  copyDir(srcDir, destDir);
9216
9357
  console.log(`\u2714 \u6A21\u677F\u5DF2\u5BFC\u51FA\u5230 .deepstorm/templates/${skillId}/`);
9217
9358
  console.log(` \u4FEE\u6539\u5B8C\u6210\u540E\u8FD0\u884C deepstorm template apply ${skillId} \u5E94\u7528\u66F4\u6539`);
9218
9359
  }
9219
9360
 
9220
9361
  // src/commands/template-apply.ts
9221
- var fs20 = __toESM(require("node:fs"));
9222
- var path16 = __toESM(require("node:path"));
9362
+ var fs21 = __toESM(require("node:fs"));
9363
+ var path17 = __toESM(require("node:path"));
9223
9364
  function applyTemplate(targetDir, skillId) {
9224
- const srcDir = path16.join(targetDir, ".deepstorm", "templates", skillId);
9225
- const destDir = path16.join(targetDir, ".claude", "skills", skillId);
9226
- if (!fs20.existsSync(srcDir)) {
9365
+ const srcDir = path17.join(targetDir, ".deepstorm", "templates", skillId);
9366
+ const destDir = path17.join(targetDir, ".claude", "skills", skillId);
9367
+ if (!fs21.existsSync(srcDir)) {
9227
9368
  console.log(`\u6A21\u677F\u4E0D\u5B58\u5728\uFF0C\u8BF7\u5148\u8FD0\u884C deepstorm template init ${skillId}`);
9228
9369
  return;
9229
9370
  }
@@ -9257,21 +9398,21 @@ function registerTemplateCommand(program2, registry2) {
9257
9398
  }
9258
9399
 
9259
9400
  // src/commands/update.ts
9260
- var fs23 = __toESM(require("node:fs"));
9261
- var import_node_child_process = require("node:child_process");
9401
+ var fs24 = __toESM(require("node:fs"));
9402
+ var import_node_child_process2 = require("node:child_process");
9262
9403
 
9263
9404
  // src/utils/version.ts
9264
- var fs21 = __toESM(require("node:fs"));
9265
- var path17 = __toESM(require("node:path"));
9405
+ var fs22 = __toESM(require("node:fs"));
9406
+ var path18 = __toESM(require("node:path"));
9266
9407
  function getCliVersion() {
9267
9408
  try {
9268
9409
  const paths = [
9269
- path17.resolve(__dirname, "package.json"),
9270
- path17.resolve(__dirname, "..", "package.json")
9410
+ path18.resolve(__dirname, "package.json"),
9411
+ path18.resolve(__dirname, "..", "package.json")
9271
9412
  ];
9272
9413
  for (const pkgPath of paths) {
9273
- if (fs21.existsSync(pkgPath)) {
9274
- const pkg = JSON.parse(fs21.readFileSync(pkgPath, "utf-8"));
9414
+ if (fs22.existsSync(pkgPath)) {
9415
+ const pkg = JSON.parse(fs22.readFileSync(pkgPath, "utf-8"));
9275
9416
  return pkg.version || "0.0.0";
9276
9417
  }
9277
9418
  }
@@ -9282,14 +9423,14 @@ function getCliVersion() {
9282
9423
  }
9283
9424
 
9284
9425
  // src/commands/template-upgrade.ts
9285
- var fs22 = __toESM(require("node:fs"));
9286
- var path18 = __toESM(require("node:path"));
9426
+ var fs23 = __toESM(require("node:fs"));
9427
+ var path19 = __toESM(require("node:path"));
9287
9428
  var crypto = __toESM(require("node:crypto"));
9288
9429
  var CHECKSUM_FILE = "deepstorm-checksums.json";
9289
9430
  function computeFileChecksum(filePath) {
9290
9431
  try {
9291
- if (!fs22.existsSync(filePath)) return null;
9292
- const content = fs22.readFileSync(filePath);
9432
+ if (!fs23.existsSync(filePath)) return null;
9433
+ const content = fs23.readFileSync(filePath);
9293
9434
  return crypto.createHash("sha256").update(content).digest("hex");
9294
9435
  } catch {
9295
9436
  return null;
@@ -9297,15 +9438,15 @@ function computeFileChecksum(filePath) {
9297
9438
  }
9298
9439
  function computeDirChecksums(dirPath, relativeTo = dirPath) {
9299
9440
  const result = {};
9300
- if (!fs22.existsSync(dirPath)) return result;
9441
+ if (!fs23.existsSync(dirPath)) return result;
9301
9442
  function walk(current) {
9302
- for (const entry of fs22.readdirSync(current, { withFileTypes: true })) {
9303
- const fullPath = path18.join(current, entry.name);
9443
+ for (const entry of fs23.readdirSync(current, { withFileTypes: true })) {
9444
+ const fullPath = path19.join(current, entry.name);
9304
9445
  if (entry.name === ".DS_Store") continue;
9305
9446
  if (entry.isDirectory()) {
9306
9447
  walk(fullPath);
9307
9448
  } else if (entry.isFile()) {
9308
- const relPath = path18.relative(relativeTo, fullPath);
9449
+ const relPath = path19.relative(relativeTo, fullPath);
9309
9450
  const checksum = computeFileChecksum(fullPath);
9310
9451
  if (checksum) result[relPath] = checksum;
9311
9452
  }
@@ -9315,32 +9456,32 @@ function computeDirChecksums(dirPath, relativeTo = dirPath) {
9315
9456
  return result;
9316
9457
  }
9317
9458
  function loadChecksums(targetDir) {
9318
- const filePath = path18.join(targetDir, ".claude", CHECKSUM_FILE);
9459
+ const filePath = path19.join(targetDir, ".claude", CHECKSUM_FILE);
9319
9460
  try {
9320
- return JSON.parse(fs22.readFileSync(filePath, "utf-8"));
9461
+ return JSON.parse(fs23.readFileSync(filePath, "utf-8"));
9321
9462
  } catch {
9322
9463
  return {};
9323
9464
  }
9324
9465
  }
9325
9466
  function saveChecksums(targetDir, checksums) {
9326
- const dir = path18.join(targetDir, ".claude");
9467
+ const dir = path19.join(targetDir, ".claude");
9327
9468
  ensureDir3(dir);
9328
- fs22.writeFileSync(
9329
- path18.join(dir, CHECKSUM_FILE),
9469
+ fs23.writeFileSync(
9470
+ path19.join(dir, CHECKSUM_FILE),
9330
9471
  JSON.stringify(checksums, null, 2) + "\n",
9331
9472
  "utf-8"
9332
9473
  );
9333
9474
  }
9334
9475
  function backupFile(filePath) {
9335
9476
  try {
9336
- if (!fs22.existsSync(filePath)) return null;
9337
- const dir = path18.dirname(filePath);
9338
- const ext = path18.extname(filePath);
9339
- const base = path18.basename(filePath, ext);
9477
+ if (!fs23.existsSync(filePath)) return null;
9478
+ const dir = path19.dirname(filePath);
9479
+ const ext = path19.extname(filePath);
9480
+ const base = path19.basename(filePath, ext);
9340
9481
  const timestamp = Date.now();
9341
9482
  const bakName = `${base}.${timestamp}.bak`;
9342
- const bakPath = path18.join(dir, bakName);
9343
- fs22.cpSync(filePath, bakPath, { force: true });
9483
+ const bakPath = path19.join(dir, bakName);
9484
+ fs23.cpSync(filePath, bakPath, { force: true });
9344
9485
  return bakName;
9345
9486
  } catch {
9346
9487
  return null;
@@ -9361,19 +9502,19 @@ function backupModifiedAssets(targetDir, skillIds, toolNames, registry2) {
9361
9502
  const stored = loadChecksums(targetDir);
9362
9503
  const backedUp = [];
9363
9504
  for (const skillId of skillIds) {
9364
- const skillDir = path18.join(targetDir, ".claude", "skills", skillId);
9365
- if (!fs22.existsSync(skillDir)) continue;
9505
+ const skillDir = path19.join(targetDir, ".claude", "skills", skillId);
9506
+ if (!fs23.existsSync(skillDir)) continue;
9366
9507
  const checksums = computeDirChecksums(skillDir);
9367
9508
  for (const [relPath] of Object.entries(checksums)) {
9368
9509
  const key = `skills/${skillId}/${relPath}`;
9369
- checkAndBackup(key, path18.join(skillDir, relPath), stored, backedUp);
9510
+ checkAndBackup(key, path19.join(skillDir, relPath), stored, backedUp);
9370
9511
  }
9371
9512
  }
9372
9513
  const reader = new RegistryReader(registry2);
9373
9514
  for (const tool of toolNames) {
9374
9515
  const agents = reader.getToolAgents(tool);
9375
9516
  for (const agentFile of agents) {
9376
- const filePath = path18.join(targetDir, ".claude", "agents", agentFile.replace(/\.tmpl$/, ""));
9517
+ const filePath = path19.join(targetDir, ".claude", "agents", agentFile.replace(/\.tmpl$/, ""));
9377
9518
  const key = `agents/${agentFile.replace(/\.tmpl$/, "")}`;
9378
9519
  checkAndBackup(key, filePath, stored, backedUp);
9379
9520
  }
@@ -9381,7 +9522,7 @@ function backupModifiedAssets(targetDir, skillIds, toolNames, registry2) {
9381
9522
  for (const tool of toolNames) {
9382
9523
  const hooks = reader.getToolHooks(tool);
9383
9524
  for (const hookFile of hooks) {
9384
- const filePath = path18.join(targetDir, ".claude", "hooks", hookFile);
9525
+ const filePath = path19.join(targetDir, ".claude", "hooks", hookFile);
9385
9526
  const key = `hooks/${hookFile}`;
9386
9527
  checkAndBackup(key, filePath, stored, backedUp);
9387
9528
  }
@@ -9392,7 +9533,7 @@ function storeNewChecksums(targetDir, skillIds, toolNames, registry2) {
9392
9533
  const newChecksums = {};
9393
9534
  const reader = new RegistryReader(registry2);
9394
9535
  for (const skillId of skillIds) {
9395
- const skillDir = path18.join(targetDir, ".claude", "skills", skillId);
9536
+ const skillDir = path19.join(targetDir, ".claude", "skills", skillId);
9396
9537
  const checksums = computeDirChecksums(skillDir);
9397
9538
  for (const [relPath, checksum] of Object.entries(checksums)) {
9398
9539
  newChecksums[`skills/${skillId}/${relPath}`] = checksum;
@@ -9402,7 +9543,7 @@ function storeNewChecksums(targetDir, skillIds, toolNames, registry2) {
9402
9543
  const agents = reader.getToolAgents(tool);
9403
9544
  for (const agentFile of agents) {
9404
9545
  const installedName = agentFile.replace(/\.tmpl$/, "");
9405
- const filePath = path18.join(targetDir, ".claude", "agents", installedName);
9546
+ const filePath = path19.join(targetDir, ".claude", "agents", installedName);
9406
9547
  const chk = computeFileChecksum(filePath);
9407
9548
  if (chk) newChecksums[`agents/${installedName}`] = chk;
9408
9549
  }
@@ -9410,7 +9551,7 @@ function storeNewChecksums(targetDir, skillIds, toolNames, registry2) {
9410
9551
  for (const tool of toolNames) {
9411
9552
  const hooks = reader.getToolHooks(tool);
9412
9553
  for (const hookFile of hooks) {
9413
- const filePath = path18.join(targetDir, ".claude", "hooks", hookFile);
9554
+ const filePath = path19.join(targetDir, ".claude", "hooks", hookFile);
9414
9555
  const chk = computeFileChecksum(filePath);
9415
9556
  if (chk) newChecksums[`hooks/${hookFile}`] = chk;
9416
9557
  }
@@ -9443,7 +9584,7 @@ function detectToolsFromConfig(config, registry2) {
9443
9584
  function readSettingsConfig(targetDir) {
9444
9585
  const settingsPath = getDeepStormConfigPath(targetDir);
9445
9586
  try {
9446
- const raw = fs22.readFileSync(settingsPath, "utf-8");
9587
+ const raw = fs23.readFileSync(settingsPath, "utf-8");
9447
9588
  const config = JSON.parse(raw);
9448
9589
  const metaKeys = /* @__PURE__ */ new Set([
9449
9590
  "installedSkills",
@@ -9473,22 +9614,22 @@ function flattenNestedConfig(obj, prefix, result, skipKeys) {
9473
9614
  }
9474
9615
  }
9475
9616
  function loadRegistryFromCliDir(cliDir2) {
9476
- const registryPath = path18.join(cliDir2, "registry.json");
9617
+ const registryPath = path19.join(cliDir2, "registry.json");
9477
9618
  try {
9478
- const raw = fs22.readFileSync(registryPath, "utf-8");
9619
+ const raw = fs23.readFileSync(registryPath, "utf-8");
9479
9620
  return JSON.parse(raw);
9480
9621
  } catch {
9481
9622
  return null;
9482
9623
  }
9483
9624
  }
9484
9625
  function mergeToolHooksJson(toolNames, cliDir2, targetDir) {
9485
- const hooksSrcDir = path18.join(cliDir2, "hooks");
9486
- const destHooksJson = path18.join(targetDir, ".claude", "hooks.json");
9626
+ const hooksSrcDir = path19.join(cliDir2, "hooks");
9627
+ const destHooksJson = path19.join(targetDir, ".claude", "hooks.json");
9487
9628
  for (const tool of toolNames) {
9488
- const toolHooksJsonPath = path18.join(hooksSrcDir, `${tool}-hooks.json`);
9489
- if (fs22.existsSync(toolHooksJsonPath)) {
9490
- ensureDir3(path18.join(targetDir, ".claude"));
9491
- const incoming = JSON.parse(fs22.readFileSync(toolHooksJsonPath, "utf-8"));
9629
+ const toolHooksJsonPath = path19.join(hooksSrcDir, `${tool}-hooks.json`);
9630
+ if (fs23.existsSync(toolHooksJsonPath)) {
9631
+ ensureDir3(path19.join(targetDir, ".claude"));
9632
+ const incoming = JSON.parse(fs23.readFileSync(toolHooksJsonPath, "utf-8"));
9492
9633
  mergeHooks(destHooksJson, incoming);
9493
9634
  }
9494
9635
  }
@@ -9606,8 +9747,8 @@ function readLocalRegistryFile(url) {
9606
9747
  filePath = filePath.slice(7);
9607
9748
  }
9608
9749
  try {
9609
- if (fs23.existsSync(filePath)) {
9610
- return JSON.parse(fs23.readFileSync(filePath, "utf-8"));
9750
+ if (fs24.existsSync(filePath)) {
9751
+ return JSON.parse(fs24.readFileSync(filePath, "utf-8"));
9611
9752
  }
9612
9753
  } catch {
9613
9754
  }
@@ -9676,7 +9817,7 @@ async function updateCLI(fetchFn) {
9676
9817
  console.log("\u2192 \u6B63\u5728\u81EA\u52A8\u66F4\u65B0...");
9677
9818
  const updateCmd = process.env.DEEPSTORM_UPDATE_CMD || "npm install -g @deepstorm/cli@latest";
9678
9819
  try {
9679
- (0, import_node_child_process.execSync)(updateCmd, { stdio: "inherit" });
9820
+ (0, import_node_child_process2.execSync)(updateCmd, { stdio: "inherit" });
9680
9821
  console.log(`
9681
9822
  \u2714 \u5DF2\u66F4\u65B0\u81F3 v${result.latest}`);
9682
9823
  } catch {
@@ -9691,7 +9832,7 @@ async function updateCLI(fetchFn) {
9691
9832
  function getInstalledSkillIds(targetDir) {
9692
9833
  const settingsPath = getDeepStormConfigPath(targetDir);
9693
9834
  try {
9694
- const raw = fs23.readFileSync(settingsPath, "utf-8");
9835
+ const raw = fs24.readFileSync(settingsPath, "utf-8");
9695
9836
  const config = JSON.parse(raw);
9696
9837
  return config.installedSkills ?? [];
9697
9838
  } catch {
@@ -9718,12 +9859,12 @@ function registerPilotCommands(program2) {
9718
9859
  }
9719
9860
 
9720
9861
  // src/commands/doctor.ts
9721
- var fs24 = __toESM(require("node:fs"));
9722
- var path19 = __toESM(require("node:path"));
9862
+ var fs25 = __toESM(require("node:fs"));
9863
+ var path20 = __toESM(require("node:path"));
9723
9864
  function getInstalledSkills(targetDir) {
9724
9865
  const settingsPath = getDeepStormConfigPath(targetDir);
9725
9866
  try {
9726
- const settings = JSON.parse(fs24.readFileSync(settingsPath, "utf-8"));
9867
+ const settings = JSON.parse(fs25.readFileSync(settingsPath, "utf-8"));
9727
9868
  return settings.installedSkills || [];
9728
9869
  } catch {
9729
9870
  return [];
@@ -9740,7 +9881,7 @@ function runDoctor(targetDir) {
9740
9881
  message: `v${version}\uFF08\u8FD0\u884C deepstorm update --check \u68C0\u67E5\u6700\u65B0\u7248\u672C\uFF09`
9741
9882
  });
9742
9883
  let hasDeepStorm = false;
9743
- if (!fs24.existsSync(settingsPath)) {
9884
+ if (!fs25.existsSync(settingsPath)) {
9744
9885
  checks.push({
9745
9886
  name: "\u914D\u7F6E\u6587\u4EF6",
9746
9887
  status: "warn",
@@ -9748,7 +9889,7 @@ function runDoctor(targetDir) {
9748
9889
  });
9749
9890
  } else {
9750
9891
  try {
9751
- const config = JSON.parse(fs24.readFileSync(settingsPath, "utf-8"));
9892
+ const config = JSON.parse(fs25.readFileSync(settingsPath, "utf-8"));
9752
9893
  if (config && Object.keys(config).length > 0) {
9753
9894
  hasDeepStorm = true;
9754
9895
  checks.push({
@@ -9771,20 +9912,20 @@ function runDoctor(targetDir) {
9771
9912
  });
9772
9913
  }
9773
9914
  }
9774
- const skillsDir = path19.join(targetDir, ".claude", "skills");
9775
- if (fs24.existsSync(skillsDir)) {
9776
- const skillDirs = fs24.readdirSync(skillsDir).filter(
9777
- (n) => fs24.statSync(path19.join(skillsDir, n)).isDirectory()
9915
+ const skillsDir = path20.join(targetDir, ".claude", "skills");
9916
+ if (fs25.existsSync(skillsDir)) {
9917
+ const skillDirs = fs25.readdirSync(skillsDir).filter(
9918
+ (n) => fs25.statSync(path20.join(skillsDir, n)).isDirectory()
9778
9919
  );
9779
9920
  let validCount = 0;
9780
9921
  let invalidCount = 0;
9781
9922
  for (const skillName of skillDirs) {
9782
- const skillMd = path19.join(skillsDir, skillName, "SKILL.md");
9783
- if (!fs24.existsSync(skillMd)) {
9923
+ const skillMd = path20.join(skillsDir, skillName, "SKILL.md");
9924
+ if (!fs25.existsSync(skillMd)) {
9784
9925
  invalidCount++;
9785
9926
  continue;
9786
9927
  }
9787
- const content = fs24.readFileSync(skillMd, "utf-8");
9928
+ const content = fs25.readFileSync(skillMd, "utf-8");
9788
9929
  const frontmatter = parseFrontmatter(content);
9789
9930
  if (frontmatter && frontmatter.name) {
9790
9931
  validCount++;
@@ -9814,7 +9955,7 @@ function runDoctor(targetDir) {
9814
9955
  const installedSkills = getInstalledSkills(targetDir);
9815
9956
  const missingSkills = [];
9816
9957
  for (const skillId of installedSkills) {
9817
- if (!fs24.existsSync(path19.join(skillsDir, skillId))) {
9958
+ if (!fs25.existsSync(path20.join(skillsDir, skillId))) {
9818
9959
  missingSkills.push(skillId);
9819
9960
  }
9820
9961
  }
@@ -9838,10 +9979,10 @@ function runDoctor(targetDir) {
9838
9979
  message: ".claude/skills/ \u4E0D\u5B58\u5728"
9839
9980
  });
9840
9981
  }
9841
- const mcpPath = path19.join(targetDir, ".mcp.json");
9842
- if (fs24.existsSync(mcpPath)) {
9982
+ const mcpPath = path20.join(targetDir, ".mcp.json");
9983
+ if (fs25.existsSync(mcpPath)) {
9843
9984
  try {
9844
- const mcp = JSON.parse(fs24.readFileSync(mcpPath, "utf-8"));
9985
+ const mcp = JSON.parse(fs25.readFileSync(mcpPath, "utf-8"));
9845
9986
  const hasServers = mcp.mcpServers && Object.keys(mcp.mcpServers).length > 0;
9846
9987
  checks.push({
9847
9988
  name: "MCP \u670D\u52A1\u5668",
@@ -9862,12 +10003,12 @@ function runDoctor(targetDir) {
9862
10003
  message: ".mcp.json \u4E0D\u5B58\u5728"
9863
10004
  });
9864
10005
  }
9865
- if (hasDeepStorm && fs24.existsSync(settingsPath)) {
10006
+ if (hasDeepStorm && fs25.existsSync(settingsPath)) {
9866
10007
  try {
9867
- const config = JSON.parse(fs24.readFileSync(settingsPath, "utf-8"));
10008
+ const config = JSON.parse(fs25.readFileSync(settingsPath, "utf-8"));
9868
10009
  const installedMcp = config.installedMcpServers;
9869
10010
  if (installedMcp && installedMcp.length > 0) {
9870
- const mcpExists = fs24.existsSync(mcpPath);
10011
+ const mcpExists = fs25.existsSync(mcpPath);
9871
10012
  if (!mcpExists) {
9872
10013
  checks.push({
9873
10014
  name: "MCP \u4E00\u81F4\u6027",
@@ -9876,7 +10017,7 @@ function runDoctor(targetDir) {
9876
10017
  });
9877
10018
  } else {
9878
10019
  try {
9879
- const mcpConfig = JSON.parse(fs24.readFileSync(mcpPath, "utf-8"));
10020
+ const mcpConfig = JSON.parse(fs25.readFileSync(mcpPath, "utf-8"));
9880
10021
  const servers = mcpConfig.mcpServers || {};
9881
10022
  const missing = [];
9882
10023
  for (const toolName of installedMcp) {
@@ -9904,9 +10045,9 @@ function runDoctor(targetDir) {
9904
10045
  } catch {
9905
10046
  }
9906
10047
  }
9907
- if (hasDeepStorm && fs24.existsSync(settingsPath)) {
10048
+ if (hasDeepStorm && fs25.existsSync(settingsPath)) {
9908
10049
  try {
9909
- const config = JSON.parse(fs24.readFileSync(settingsPath, "utf-8"));
10050
+ const config = JSON.parse(fs25.readFileSync(settingsPath, "utf-8"));
9910
10051
  const validKeys = loadValidConfigKeys();
9911
10052
  if (validKeys.size > 0 && config) {
9912
10053
  const configKeys = [];
@@ -9959,18 +10100,18 @@ function printDoctorReport(report) {
9959
10100
  }
9960
10101
 
9961
10102
  // src/commands/uninstall.ts
9962
- var fs25 = __toESM(require("node:fs"));
9963
- var path20 = __toESM(require("node:path"));
10103
+ var fs26 = __toESM(require("node:fs"));
10104
+ var path21 = __toESM(require("node:path"));
9964
10105
  var import_prompts4 = require("@clack/prompts");
9965
10106
  async function uninstallDeepStorm(targetDir) {
9966
10107
  const settingsPath = getDeepStormConfigPath(targetDir);
9967
- if (!fs25.existsSync(settingsPath)) {
10108
+ if (!fs26.existsSync(settingsPath)) {
9968
10109
  console.log("DeepStorm \u5C1A\u672A\u914D\u7F6E\uFF0C\u65E0\u9700\u5378\u8F7D");
9969
10110
  return;
9970
10111
  }
9971
10112
  let hasDeepStorm = false;
9972
10113
  try {
9973
- const settings = JSON.parse(fs25.readFileSync(settingsPath, "utf-8"));
10114
+ const settings = JSON.parse(fs26.readFileSync(settingsPath, "utf-8"));
9974
10115
  hasDeepStorm = !!settings && Object.keys(settings).length > 0;
9975
10116
  } catch {
9976
10117
  }
@@ -9980,14 +10121,14 @@ async function uninstallDeepStorm(targetDir) {
9980
10121
  }
9981
10122
  cleanInstalled(targetDir);
9982
10123
  resetConfig(targetDir);
9983
- const templatesDir = path20.join(targetDir, ".deepstorm", "templates");
9984
- if (fs25.existsSync(templatesDir)) {
10124
+ const templatesDir = path21.join(targetDir, ".deepstorm", "templates");
10125
+ if (fs26.existsSync(templatesDir)) {
9985
10126
  const shouldDelete = await (0, import_prompts4.confirm)({
9986
10127
  message: "\u662F\u5426\u5220\u9664 .deepstorm/templates/ \u76EE\u5F55\uFF1F",
9987
10128
  initialValue: false
9988
10129
  });
9989
10130
  if (shouldDelete) {
9990
- fs25.rmSync(templatesDir, { recursive: true, force: true });
10131
+ fs26.rmSync(templatesDir, { recursive: true, force: true });
9991
10132
  console.log("\u2714 .deepstorm/templates/ \u5DF2\u5220\u9664");
9992
10133
  } else {
9993
10134
  console.log("\u4FDD\u7559 .deepstorm/templates/");
@@ -10000,9 +10141,9 @@ async function uninstallDeepStorm(targetDir) {
10000
10141
  var program = new import_commander.Command();
10001
10142
  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");
10002
10143
  function loadRegistry() {
10003
- const registryPath = path21.join(__dirname, "registry.json");
10144
+ const registryPath = path22.join(__dirname, "registry.json");
10004
10145
  try {
10005
- const raw = fs26.readFileSync(registryPath, "utf-8");
10146
+ const raw = fs27.readFileSync(registryPath, "utf-8");
10006
10147
  return JSON.parse(raw);
10007
10148
  } catch {
10008
10149
  return { version: "1", tools: {}, wizards: {}, skills: {} };