@deepstorm/cli 0.9.0 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -1187,13 +1187,13 @@ var require_ast = __commonJS({
1187
1187
  helperExpression: function helperExpression(node) {
1188
1188
  return node.type === "SubExpression" || (node.type === "MustacheStatement" || node.type === "BlockStatement") && !!(node.params && node.params.length || node.hash);
1189
1189
  },
1190
- scopedId: function scopedId(path23) {
1191
- return /^\.|this\b/.test(path23.original);
1190
+ scopedId: function scopedId(path24) {
1191
+ return /^\.|this\b/.test(path24.original);
1192
1192
  },
1193
1193
  // an ID is simple if it only has one part, and that part is not
1194
1194
  // `..` or `this`.
1195
- simpleId: function simpleId(path23) {
1196
- return path23.parts.length === 1 && !AST.helpers.scopedId(path23) && !path23.depth;
1195
+ simpleId: function simpleId(path24) {
1196
+ return path24.parts.length === 1 && !AST.helpers.scopedId(path24) && !path24.depth;
1197
1197
  }
1198
1198
  }
1199
1199
  };
@@ -2263,12 +2263,12 @@ var require_helpers2 = __commonJS({
2263
2263
  loc
2264
2264
  };
2265
2265
  }
2266
- function prepareMustache(path23, params, hash, open, strip, locInfo) {
2266
+ function prepareMustache(path24, params, hash, open, strip, locInfo) {
2267
2267
  var escapeFlag = open.charAt(3) || open.charAt(2), escaped = escapeFlag !== "{" && escapeFlag !== "&";
2268
2268
  var decorator = /\*/.test(open);
2269
2269
  return {
2270
2270
  type: decorator ? "Decorator" : "MustacheStatement",
2271
- path: path23,
2271
+ path: path24,
2272
2272
  params,
2273
2273
  hash,
2274
2274
  escaped,
@@ -2586,9 +2586,9 @@ var require_compiler = __commonJS({
2586
2586
  },
2587
2587
  DecoratorBlock: function DecoratorBlock(decorator) {
2588
2588
  var program2 = decorator.program && this.compileProgram(decorator.program);
2589
- var params = this.setupFullMustacheParams(decorator, program2, void 0), path23 = decorator.path;
2589
+ var params = this.setupFullMustacheParams(decorator, program2, void 0), path24 = decorator.path;
2590
2590
  this.useDecorators = true;
2591
- this.opcode("registerDecorator", params.length, path23.original);
2591
+ this.opcode("registerDecorator", params.length, path24.original);
2592
2592
  },
2593
2593
  PartialStatement: function PartialStatement(partial) {
2594
2594
  this.usePartial = true;
@@ -2652,46 +2652,46 @@ var require_compiler = __commonJS({
2652
2652
  }
2653
2653
  },
2654
2654
  ambiguousSexpr: function ambiguousSexpr(sexpr, program2, inverse) {
2655
- var path23 = sexpr.path, name = path23.parts[0], isBlock = program2 != null || inverse != null;
2656
- this.opcode("getContext", path23.depth);
2655
+ var path24 = sexpr.path, name = path24.parts[0], isBlock = program2 != null || inverse != null;
2656
+ this.opcode("getContext", path24.depth);
2657
2657
  this.opcode("pushProgram", program2);
2658
2658
  this.opcode("pushProgram", inverse);
2659
- path23.strict = true;
2660
- this.accept(path23);
2659
+ path24.strict = true;
2660
+ this.accept(path24);
2661
2661
  this.opcode("invokeAmbiguous", name, isBlock);
2662
2662
  },
2663
2663
  simpleSexpr: function simpleSexpr(sexpr) {
2664
- var path23 = sexpr.path;
2665
- path23.strict = true;
2666
- this.accept(path23);
2664
+ var path24 = sexpr.path;
2665
+ path24.strict = true;
2666
+ this.accept(path24);
2667
2667
  this.opcode("resolvePossibleLambda");
2668
2668
  },
2669
2669
  helperSexpr: function helperSexpr(sexpr, program2, inverse) {
2670
- var params = this.setupFullMustacheParams(sexpr, program2, inverse), path23 = sexpr.path, name = path23.parts[0];
2670
+ var params = this.setupFullMustacheParams(sexpr, program2, inverse), path24 = sexpr.path, name = path24.parts[0];
2671
2671
  if (this.options.knownHelpers[name]) {
2672
2672
  this.opcode("invokeKnownHelper", params.length, name);
2673
2673
  } else if (this.options.knownHelpersOnly) {
2674
2674
  throw new _exception2["default"]("You specified knownHelpersOnly, but used the unknown helper " + name, sexpr);
2675
2675
  } else {
2676
- path23.strict = true;
2677
- path23.falsy = true;
2678
- this.accept(path23);
2679
- this.opcode("invokeHelper", params.length, path23.original, _ast2["default"].helpers.simpleId(path23));
2676
+ path24.strict = true;
2677
+ path24.falsy = true;
2678
+ this.accept(path24);
2679
+ this.opcode("invokeHelper", params.length, path24.original, _ast2["default"].helpers.simpleId(path24));
2680
2680
  }
2681
2681
  },
2682
- PathExpression: function PathExpression(path23) {
2683
- this.addDepth(path23.depth);
2684
- this.opcode("getContext", path23.depth);
2685
- var name = path23.parts[0], scoped = _ast2["default"].helpers.scopedId(path23), blockParamId = !path23.depth && !scoped && this.blockParamIndex(name);
2682
+ PathExpression: function PathExpression(path24) {
2683
+ this.addDepth(path24.depth);
2684
+ this.opcode("getContext", path24.depth);
2685
+ var name = path24.parts[0], scoped = _ast2["default"].helpers.scopedId(path24), blockParamId = !path24.depth && !scoped && this.blockParamIndex(name);
2686
2686
  if (blockParamId) {
2687
- this.opcode("lookupBlockParam", blockParamId, path23.parts);
2687
+ this.opcode("lookupBlockParam", blockParamId, path24.parts);
2688
2688
  } else if (!name) {
2689
2689
  this.opcode("pushContext");
2690
- } else if (path23.data) {
2690
+ } else if (path24.data) {
2691
2691
  this.options.data = true;
2692
- this.opcode("lookupData", path23.depth, path23.parts, path23.strict);
2692
+ this.opcode("lookupData", path24.depth, path24.parts, path24.strict);
2693
2693
  } else {
2694
- this.opcode("lookupOnContext", path23.parts, path23.falsy, path23.strict, scoped);
2694
+ this.opcode("lookupOnContext", path24.parts, path24.falsy, path24.strict, scoped);
2695
2695
  }
2696
2696
  },
2697
2697
  StringLiteral: function StringLiteral(string) {
@@ -3041,16 +3041,16 @@ var require_util = __commonJS({
3041
3041
  }
3042
3042
  exports2.urlGenerate = urlGenerate;
3043
3043
  function normalize(aPath) {
3044
- var path23 = aPath;
3044
+ var path24 = aPath;
3045
3045
  var url = urlParse(aPath);
3046
3046
  if (url) {
3047
3047
  if (!url.path) {
3048
3048
  return aPath;
3049
3049
  }
3050
- path23 = url.path;
3050
+ path24 = url.path;
3051
3051
  }
3052
- var isAbsolute = exports2.isAbsolute(path23);
3053
- var parts = path23.split(/\/+/);
3052
+ var isAbsolute = exports2.isAbsolute(path24);
3053
+ var parts = path24.split(/\/+/);
3054
3054
  for (var part, up = 0, i = parts.length - 1; i >= 0; i--) {
3055
3055
  part = parts[i];
3056
3056
  if (part === ".") {
@@ -3067,18 +3067,18 @@ var require_util = __commonJS({
3067
3067
  }
3068
3068
  }
3069
3069
  }
3070
- path23 = parts.join("/");
3071
- if (path23 === "") {
3072
- path23 = isAbsolute ? "/" : ".";
3070
+ path24 = parts.join("/");
3071
+ if (path24 === "") {
3072
+ path24 = isAbsolute ? "/" : ".";
3073
3073
  }
3074
3074
  if (url) {
3075
- url.path = path23;
3075
+ url.path = path24;
3076
3076
  return urlGenerate(url);
3077
3077
  }
3078
- return path23;
3078
+ return path24;
3079
3079
  }
3080
3080
  exports2.normalize = normalize;
3081
- function join21(aRoot, aPath) {
3081
+ function join22(aRoot, aPath) {
3082
3082
  if (aRoot === "") {
3083
3083
  aRoot = ".";
3084
3084
  }
@@ -3110,7 +3110,7 @@ var require_util = __commonJS({
3110
3110
  }
3111
3111
  return joined;
3112
3112
  }
3113
- exports2.join = join21;
3113
+ exports2.join = join22;
3114
3114
  exports2.isAbsolute = function(aPath) {
3115
3115
  return aPath.charAt(0) === "/" || urlRegexp.test(aPath);
3116
3116
  };
@@ -3283,7 +3283,7 @@ var require_util = __commonJS({
3283
3283
  parsed.path = parsed.path.substring(0, index + 1);
3284
3284
  }
3285
3285
  }
3286
- sourceURL = join21(urlGenerate(parsed), sourceURL);
3286
+ sourceURL = join22(urlGenerate(parsed), sourceURL);
3287
3287
  }
3288
3288
  return normalize(sourceURL);
3289
3289
  }
@@ -5858,8 +5858,8 @@ var require_printer = __commonJS({
5858
5858
  return this.accept(sexpr.path) + " " + params + hash;
5859
5859
  };
5860
5860
  PrintVisitor.prototype.PathExpression = function(id) {
5861
- var path23 = id.parts.join("/");
5862
- return (id.data ? "@" : "") + "PATH:" + path23;
5861
+ var path24 = id.parts.join("/");
5862
+ return (id.data ? "@" : "") + "PATH:" + path24;
5863
5863
  };
5864
5864
  PrintVisitor.prototype.StringLiteral = function(string) {
5865
5865
  return '"' + string.value + '"';
@@ -5912,7 +5912,7 @@ var require_lib = __commonJS({
5912
5912
  // src/index.ts
5913
5913
  var import_commander = require("commander");
5914
5914
  var fs27 = __toESM(require("node:fs"));
5915
- var path22 = __toESM(require("node:path"));
5915
+ var path23 = __toESM(require("node:path"));
5916
5916
 
5917
5917
  // src/commands/setup.ts
5918
5918
  var path9 = __toESM(require("node:path"));
@@ -9383,6 +9383,7 @@ function registerTemplateCommand(program2, registry2) {
9383
9383
 
9384
9384
  // src/commands/update.ts
9385
9385
  var fs24 = __toESM(require("node:fs"));
9386
+ var path20 = __toESM(require("node:path"));
9386
9387
  var import_node_child_process2 = require("node:child_process");
9387
9388
 
9388
9389
  // src/utils/version.ts
@@ -9814,23 +9815,139 @@ async function updateCLI(fetchFn) {
9814
9815
  return result;
9815
9816
  }
9816
9817
  function getInstalledSkillIds(targetDir) {
9817
- const settingsPath = getDeepStormConfigPath(targetDir);
9818
+ const config = readDeepStormConfig(targetDir);
9819
+ if (!config) return [];
9820
+ const ids = config.installedSkills;
9821
+ return Array.isArray(ids) ? ids : [];
9822
+ }
9823
+ function migrateOldDataSources(targetDir) {
9824
+ const migrated = [];
9818
9825
  try {
9819
- const raw = fs24.readFileSync(settingsPath, "utf-8");
9820
- const config = JSON.parse(raw);
9821
- return config.installedSkills ?? [];
9822
- } catch {
9823
- return [];
9826
+ const claudeSettingsPath = path20.join(targetDir, ".claude", "settings.json");
9827
+ if (fs24.existsSync(claudeSettingsPath)) {
9828
+ const raw = fs24.readFileSync(claudeSettingsPath, "utf-8");
9829
+ const claudeConfig = JSON.parse(raw);
9830
+ if (claudeConfig.deepstorm && typeof claudeConfig.deepstorm === "object" && Object.keys(claudeConfig.deepstorm).length > 0) {
9831
+ writeDeepStormConfig(targetDir, claudeConfig.deepstorm);
9832
+ delete claudeConfig.deepstorm;
9833
+ fs24.writeFileSync(claudeSettingsPath, JSON.stringify(claudeConfig, null, 2) + "\n", "utf-8");
9834
+ migrated.push(".claude/settings.json \u2192 .deepstorm/settings.json");
9835
+ console.log(" \u2714 \u5DF2\u8FC1\u79FB .claude/settings.json \u4E2D\u7684 DeepStorm \u914D\u7F6E");
9836
+ }
9837
+ }
9838
+ } catch (err) {
9839
+ console.log(` \u26A0 deepstorm \u914D\u7F6E\u8FC1\u79FB\u5931\u8D25: ${err instanceof Error ? err.message : String(err)}`);
9840
+ }
9841
+ try {
9842
+ const sweepInitPath = path20.join(targetDir, ".sweep-init");
9843
+ if (fs24.existsSync(sweepInitPath)) {
9844
+ const existing = readDeepStormConfig(targetDir);
9845
+ const hasE2ePath = existing && existing.sweep?.e2eProjectPath;
9846
+ if (!hasE2ePath) {
9847
+ writeDeepStormConfig(targetDir, { sweep: { e2eProjectPath: "." } });
9848
+ migrated.push(".sweep-init \u2192 sweep.e2eProjectPath");
9849
+ console.log(' \u2714 \u5DF2\u8FC1\u79FB .sweep-init \u2192 sweep.e2eProjectPath = "."');
9850
+ }
9851
+ fs24.rmSync(sweepInitPath, { force: true });
9852
+ if (hasE2ePath) {
9853
+ console.log(" \u2139 .sweep-init \u5DF2\u5220\u9664\uFF08sweep.e2eProjectPath \u5DF2\u5B58\u5728\uFF0C\u672A\u8986\u76D6\uFF09");
9854
+ }
9855
+ }
9856
+ } catch (err) {
9857
+ console.log(` \u26A0 .sweep-init \u8FC1\u79FB\u5931\u8D25: ${err instanceof Error ? err.message : String(err)}`);
9858
+ }
9859
+ try {
9860
+ const envPath = path20.join(targetDir, ".env");
9861
+ if (fs24.existsSync(envPath)) {
9862
+ const raw = fs24.readFileSync(envPath, "utf-8");
9863
+ const lines = raw.split("\n");
9864
+ const baseUrlVars = {};
9865
+ let defaultEnv = "test";
9866
+ let hasDefaultEnv = false;
9867
+ const remainingLines = [];
9868
+ for (const line of lines) {
9869
+ const trimmed = line.trim();
9870
+ const baseMatch = trimmed.match(/^BASE_URL_(\w+)=(.+)$/);
9871
+ if (baseMatch) {
9872
+ const envName = baseMatch[1].toLowerCase();
9873
+ let url = baseMatch[2].trim();
9874
+ if (url.startsWith('"') && url.endsWith('"') || url.startsWith("'") && url.endsWith("'")) {
9875
+ url = url.slice(1, -1);
9876
+ }
9877
+ baseUrlVars[envName] = url;
9878
+ continue;
9879
+ }
9880
+ const defaultMatch = trimmed.match(/^DEFAULT_ENV=(.+)$/);
9881
+ if (defaultMatch) {
9882
+ hasDefaultEnv = true;
9883
+ defaultEnv = defaultMatch[1].trim();
9884
+ continue;
9885
+ }
9886
+ remainingLines.push(line);
9887
+ }
9888
+ if (Object.keys(baseUrlVars).length > 0) {
9889
+ const environments = {};
9890
+ for (const [envName, url] of Object.entries(baseUrlVars)) {
9891
+ environments[envName] = { baseUrl: url };
9892
+ }
9893
+ environments.default = defaultEnv;
9894
+ const existing = readDeepStormConfig(targetDir);
9895
+ const hasEnvs = existing && existing.sweep?.environments;
9896
+ if (!hasEnvs) {
9897
+ writeDeepStormConfig(targetDir, { sweep: { environments } });
9898
+ migrated.push(".env BASE_URL \u2192 sweep.environments");
9899
+ console.log(` \u2714 \u5DF2\u8FC1\u79FB .env \u4E2D ${Object.keys(baseUrlVars).length} \u4E2A\u73AF\u5883\u914D\u7F6E`);
9900
+ }
9901
+ const cleaned = remainingLines.join("\n").trimEnd();
9902
+ if (cleaned === "") {
9903
+ fs24.writeFileSync(envPath, "# \u73AF\u5883 baseURL \u914D\u7F6E\u5DF2\u8FC1\u79FB\u81F3 .deepstorm/settings.json\n# \u8BF7\u52FF\u5728\u6B64\u5904\u91CD\u590D\u5B9A\u4E49 BASE_URL_* \u914D\u7F6E\n", "utf-8");
9904
+ } else if (hasDefaultEnv || Object.keys(baseUrlVars).length > 0) {
9905
+ fs24.writeFileSync(envPath, cleaned + "\n", "utf-8");
9906
+ }
9907
+ }
9908
+ }
9909
+ } catch (err) {
9910
+ console.log(` \u26A0 .env baseURL \u8FC1\u79FB\u5931\u8D25: ${err instanceof Error ? err.message : String(err)}`);
9824
9911
  }
9912
+ try {
9913
+ const scopeConfigPath = path20.join(targetDir, ".deepstorm", "scope-config.json");
9914
+ if (fs24.existsSync(scopeConfigPath)) {
9915
+ const raw = fs24.readFileSync(scopeConfigPath, "utf-8");
9916
+ const scopeData = JSON.parse(raw);
9917
+ const scope = {};
9918
+ if ("enabled" in scopeData) scope.enabled = scopeData.enabled;
9919
+ if ("ciEnabled" in scopeData) scope.ciEnabled = scopeData.ciEnabled;
9920
+ if ("domains" in scopeData) scope.domains = scopeData.domains;
9921
+ const existing = readDeepStormConfig(targetDir);
9922
+ const hasReefScope = existing && existing.reef?.scope;
9923
+ if (!hasReefScope) {
9924
+ writeDeepStormConfig(targetDir, { reef: { scope } });
9925
+ migrated.push("scope-config.json \u2192 reef.scope");
9926
+ console.log(" \u2714 \u5DF2\u8FC1\u79FB .deepstorm/scope-config.json \u2192 reef.scope");
9927
+ }
9928
+ fs24.rmSync(scopeConfigPath, { force: true });
9929
+ if (hasReefScope) {
9930
+ console.log(" \u2139 scope-config.json \u5DF2\u5220\u9664\uFF08reef.scope \u5DF2\u5B58\u5728\uFF0C\u672A\u8986\u76D6\uFF09");
9931
+ }
9932
+ }
9933
+ } catch (err) {
9934
+ console.log(` \u26A0 scope-config.json \u8FC1\u79FB\u5931\u8D25: ${err instanceof Error ? err.message : String(err)}`);
9935
+ }
9936
+ return { migrated };
9825
9937
  }
9826
9938
  function registerUpdateCommand(program2) {
9827
9939
  const cliDir2 = __dirname;
9828
9940
  program2.command("update").description("\u68C0\u67E5 CLI \u66F4\u65B0\u5E76\u540C\u6B65\u5DF2\u5B89\u88C5 skill \u7684\u5B98\u65B9\u6700\u65B0\u6A21\u677F").action(async () => {
9829
- const installedIds = getInstalledSkillIds(process.cwd());
9941
+ const targetDir = process.cwd();
9942
+ const { migrated } = migrateOldDataSources(targetDir);
9943
+ if (migrated.length > 0) {
9944
+ console.log(`\u2714 \u5DF2\u5B8C\u6210 ${migrated.length} \u9879\u65E7\u6570\u636E\u6E90\u8FC1\u79FB`);
9945
+ }
9946
+ const installedIds = getInstalledSkillIds(targetDir);
9830
9947
  if (installedIds.length === 0) {
9831
9948
  console.log("\u672A\u68C0\u6D4B\u5230\u5DF2\u5B89\u88C5\u7684 skill\uFF0C\u8DF3\u8FC7\u540C\u6B65");
9832
9949
  } else {
9833
- upgradeTemplates(cliDir2, process.cwd(), installedIds);
9950
+ upgradeTemplates(cliDir2, targetDir, installedIds);
9834
9951
  }
9835
9952
  await updateCLI();
9836
9953
  });
@@ -9844,7 +9961,7 @@ function registerPilotCommands(program2) {
9844
9961
 
9845
9962
  // src/commands/doctor.ts
9846
9963
  var fs25 = __toESM(require("node:fs"));
9847
- var path20 = __toESM(require("node:path"));
9964
+ var path21 = __toESM(require("node:path"));
9848
9965
  function getInstalledSkills(targetDir) {
9849
9966
  const settingsPath = getDeepStormConfigPath(targetDir);
9850
9967
  try {
@@ -9896,15 +10013,15 @@ function runDoctor(targetDir) {
9896
10013
  });
9897
10014
  }
9898
10015
  }
9899
- const skillsDir = path20.join(targetDir, ".claude", "skills");
10016
+ const skillsDir = path21.join(targetDir, ".claude", "skills");
9900
10017
  if (fs25.existsSync(skillsDir)) {
9901
10018
  const skillDirs = fs25.readdirSync(skillsDir).filter(
9902
- (n) => fs25.statSync(path20.join(skillsDir, n)).isDirectory()
10019
+ (n) => fs25.statSync(path21.join(skillsDir, n)).isDirectory()
9903
10020
  );
9904
10021
  let validCount = 0;
9905
10022
  let invalidCount = 0;
9906
10023
  for (const skillName of skillDirs) {
9907
- const skillMd = path20.join(skillsDir, skillName, "SKILL.md");
10024
+ const skillMd = path21.join(skillsDir, skillName, "SKILL.md");
9908
10025
  if (!fs25.existsSync(skillMd)) {
9909
10026
  invalidCount++;
9910
10027
  continue;
@@ -9939,7 +10056,7 @@ function runDoctor(targetDir) {
9939
10056
  const installedSkills = getInstalledSkills(targetDir);
9940
10057
  const missingSkills = [];
9941
10058
  for (const skillId of installedSkills) {
9942
- if (!fs25.existsSync(path20.join(skillsDir, skillId))) {
10059
+ if (!fs25.existsSync(path21.join(skillsDir, skillId))) {
9943
10060
  missingSkills.push(skillId);
9944
10061
  }
9945
10062
  }
@@ -9963,7 +10080,7 @@ function runDoctor(targetDir) {
9963
10080
  message: ".claude/skills/ \u4E0D\u5B58\u5728"
9964
10081
  });
9965
10082
  }
9966
- const mcpPath = path20.join(targetDir, ".mcp.json");
10083
+ const mcpPath = path21.join(targetDir, ".mcp.json");
9967
10084
  if (fs25.existsSync(mcpPath)) {
9968
10085
  try {
9969
10086
  const mcp = JSON.parse(fs25.readFileSync(mcpPath, "utf-8"));
@@ -10085,7 +10202,7 @@ function printDoctorReport(report) {
10085
10202
 
10086
10203
  // src/commands/uninstall.ts
10087
10204
  var fs26 = __toESM(require("node:fs"));
10088
- var path21 = __toESM(require("node:path"));
10205
+ var path22 = __toESM(require("node:path"));
10089
10206
  var import_prompts4 = require("@clack/prompts");
10090
10207
  async function uninstallDeepStorm(targetDir) {
10091
10208
  const settingsPath = getDeepStormConfigPath(targetDir);
@@ -10105,7 +10222,7 @@ async function uninstallDeepStorm(targetDir) {
10105
10222
  }
10106
10223
  cleanInstalled(targetDir);
10107
10224
  resetConfig(targetDir);
10108
- const templatesDir = path21.join(targetDir, ".deepstorm", "templates");
10225
+ const templatesDir = path22.join(targetDir, ".deepstorm", "templates");
10109
10226
  if (fs26.existsSync(templatesDir)) {
10110
10227
  const shouldDelete = await (0, import_prompts4.confirm)({
10111
10228
  message: "\u662F\u5426\u5220\u9664 .deepstorm/templates/ \u76EE\u5F55\uFF1F",
@@ -10125,7 +10242,7 @@ async function uninstallDeepStorm(targetDir) {
10125
10242
  var program = new import_commander.Command();
10126
10243
  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");
10127
10244
  function loadRegistry() {
10128
- const registryPath = path22.join(__dirname, "registry.json");
10245
+ const registryPath = path23.join(__dirname, "registry.json");
10129
10246
  try {
10130
10247
  const raw = fs27.readFileSync(registryPath, "utf-8");
10131
10248
  return JSON.parse(raw);
@@ -137,7 +137,7 @@ if [ -f "$SCOPE_HOOK" ]; then
137
137
  bash "$SCOPE_HOOK" || {
138
138
  echo ""
139
139
  echo "提示:如需继续提交,请使用 'reef-scope-split.sh' 拆分分支"
140
- echo "或临时禁用 scope 检查(不推荐):deepstorm/scope-config.json → enabled: false"
140
+ echo "或临时禁用 scope 检查(不推荐):settings.json → reef.scope.enabled: false"
141
141
  exit 1
142
142
  }
143
143
  fi
@@ -89,8 +89,6 @@ bash packages/reef/hooks/reef-scope-split.sh
89
89
  - `ciEnabled`: CI 门禁开关(独立控制)
90
90
  - `domains`: 项目业务领域列表(空 = AI 自由分类,非空 = AI 对齐到这些领域)
91
91
 
92
- > **注意:** 旧版 `.deepstorm/scope-config.json` 已不再使用。如果存在该文件,运行 `deepstorm scope setup` 会自动迁移到 `settings.json`。
93
-
94
92
  ## 使用流程
95
93
 
96
94
  1. **安装**: 运行一次 `reef-scope-setup.sh install`
@@ -128,7 +126,7 @@ scope-check:
128
126
  ## 常见问题
129
127
 
130
128
  **Q: 我不想在所有项目上都启用这个检查?**
131
- A: 每个项目独立安装和配置,`scope-config.json` 中的 `enabled: false` 可关闭。
129
+ A: 每个项目独立安装和配置,settings.json `reef.scope.enabled: false` 可关闭。
132
130
 
133
131
  **Q: 我改了文档也要被阻断吗?**
134
132
  A: 不会。文档(markdown、README 等)变更会被归类为 `documentation` 领域,不计入多领域阻断判断。
@@ -93,18 +93,12 @@ E2E_PATH=$(cat .deepstorm/settings.json 2>/dev/null | grep -o '"e2eProjectPath"[
93
93
 
94
94
  #### 1.2 已初始化 → 退出
95
95
 
96
- - **WHEN** `sweep.e2eProjectPath` 已设置(或旧 `.sweep-init` 文件存在)
97
- - **THEN** 提示"当前项目已初始化为 Sweep 测试项目。如需重新初始化,请删除 `sweep.e2eProjectPath` 配置或 `.sweep-init` 文件后重试。"并退出
96
+ - **WHEN** `sweep.e2eProjectPath` 已设置
97
+ - **THEN** 提示"当前项目已初始化为 Sweep 测试项目。如需重新初始化,请删除 `sweep.e2eProjectPath` 配置后重试。"并退出
98
98
 
99
- #### 1.3 向后兼容:旧 .sweep-init 文件检测
99
+ #### 1.3 未初始化 继续
100
100
 
101
- - **WHEN** `settings.json` 中 `sweep.e2eProjectPath` 未设置,但 `.sweep-init` 文件存在
102
- - **THEN** 提示"ℹ️ 检测到旧版 .sweep-init 标记。建议删除该文件后重新运行 /sweep-init 以使用新版配置。"
103
- - **THEN** 提示已初始化,退出
104
-
105
- #### 1.4 未初始化 → 继续
106
-
107
- - **WHEN** 以上均不满足
101
+ - **WHEN** `sweep.e2eProjectPath` 未设置
108
102
  - **THEN** 继续执行初始化流程
109
103
 
110
104
  ---
@@ -375,7 +369,7 @@ fi
375
369
 
376
370
  - [ ] 已读取框架配置(`deepstorm.sweep.e2eFramework`)
377
371
  - [ ] 步骤 0A:已选择目标目录(`TARGET_DIR` 已确定)
378
- - [ ] 步骤 1:检查通过(`e2eProjectPath` 未设置,且 `.sweep-init` 不存在)
372
+ - [ ] 步骤 1:检查通过(`e2eProjectPath` 未设置)
379
373
  - [ ] 项目目录结构已创建(`{TARGET_DIR}/flows/`、`{TARGET_DIR}/flows/reports/`、`{TARGET_DIR}/scripts/`)
380
374
  - [ ] package.json 已写入(含对应框架的依赖)
381
375
  - [ ] 框架配置文件已生成(如 playwright.config.ts)
@@ -90,21 +90,10 @@ fi
90
90
  fi
91
91
  ```
92
92
 
93
- #### 1.3 配置不存在 → 向后兼容检查
93
+ #### 1.3 配置不存在 → 报错退出
94
94
 
95
95
  - **WHEN** `E2E_PATH` 为空
96
- - **THEN** 检查旧 `.sweep-init` 文件是否存在(从当前目录和 DEEPSTORM_DIR 向上查找):
97
- ```bash
98
- if [ -f ".sweep-init" ]; then
99
- echo "ℹ️ 检测到旧版 .sweep-init 标记。建议运行 /sweep-init 刷新配置。"
100
- # 继续执行(兼容旧项目)
101
- elif [ -n "$DEEPSTORM_DIR" ] && [ -f "$DEEPSTORM_DIR/.sweep-init" ]; then
102
- echo "ℹ️ 检测到旧版 .sweep-init 标记(项目根: $DEEPSTORM_DIR)。建议运行 /sweep-init 刷新配置。"
103
- else
104
- echo "❌ 未检测到 E2E 项目。请先运行 /sweep-init 初始化。"
105
- exit 1
106
- fi
107
- ```
96
+ - **THEN** 提示"❌ 未检测到 E2E 项目。请先运行 /sweep-init 初始化。"并退出
108
97
 
109
98
  ### 步骤 2:获取测试需求上下文(MCP 动态适配)
110
99
 
@@ -102,21 +102,10 @@ fi
102
102
  fi
103
103
  ```
104
104
 
105
- #### 1.2 配置不存在 → 向后兼容检查
105
+ #### 1.2 配置不存在 → 报错退出
106
106
 
107
107
  - **WHEN** `E2E_PATH` 为空
108
- - **THEN** 检查旧 `.sweep-init` 文件是否存在(从当前目录和 DEEPSTORM_DIR 向上查找):
109
- ```bash
110
- if [ -f ".sweep-init" ]; then
111
- echo "ℹ️ 检测到旧版 .sweep-init 标记。建议运行 /sweep-init 刷新配置。"
112
- # 继续执行(兼容旧项目)
113
- elif [ -n "$DEEPSTORM_DIR" ] && [ -f "$DEEPSTORM_DIR/.sweep-init" ]; then
114
- echo "ℹ️ 检测到旧版 .sweep-init 标记(项目根: $DEEPSTORM_DIR)。建议运行 /sweep-init 刷新配置。"
115
- else
116
- echo "❌ 未检测到 E2E 项目。请先运行 /sweep-init 初始化。"
117
- exit 1
118
- fi
119
- ```
108
+ - **THEN** 提示"❌ 未检测到 E2E 项目。请先运行 /sweep-init 初始化。"并退出
120
109
 
121
110
  ---
122
111
 
@@ -217,9 +206,9 @@ node scripts/env-manager.mjs --env staging
217
206
  ]}
218
207
  ```
219
208
 
220
- - `--env staging` → 从 `settings.json` 的 `sweep.environments.staging` 读取(回退到 `.env`)
221
- - `--env test` → 从 `settings.json` 的 `sweep.environments.test` 读取(回退到 `.env`)
222
- - 不传参 → 使用 `settings.json` 的 `sweep.environments.default`(回退到 `.env` 的 `DEFAULT_ENV`),未设置则默认 `test`
209
+ - `--env staging` → 从 `settings.json` 的 `sweep.environments.staging` 读取
210
+ - `--env test` → 从 `settings.json` 的 `sweep.environments.test` 读取
211
+ - 不传参 → 使用 `settings.json` 的 `sweep.environments.default`,未设置则默认 `test`
223
212
 
224
213
  #### 4.2 设置环境变量
225
214
 
@@ -234,7 +223,7 @@ BASE_URL=$(node scripts/env-manager.mjs --env test | node -pe "JSON.parse(requir
234
223
 
235
224
  #### 4.3 环境不存在处理
236
225
 
237
- 如果 `baseUrl` 为 `null`(指定的环境在 `.env` 中找不到对应配置):
226
+ 如果 `baseUrl` 为 `null`(指定的环境在 settings.json 中找不到对应配置):
238
227
 
239
228
  - 提示"未找到 [{env}] 环境的 baseURL 配置"
240
229
  - 列出 `availableEnvs` 中已有的环境
@@ -3,9 +3,13 @@
3
3
  /**
4
4
  * Env Manager — 测试环境配置管理
5
5
  *
6
- * 读取 .env 文件,解析目标环境的 BASE_URL,输出结构化结果。
6
+ * .deepstorm/settings.json 读取目标环境配置,输出结构化结果。
7
7
  * 支持检查 E2E 框架配置和 MCP 可用性。
8
8
  *
9
+ * 所有旧数据源(.env BASE_URL、.sweep-init、scope-config.json 等)
10
+ * 已由 `deepstorm update` 统一迁移到 .deepstorm/settings.json,
11
+ * 本文件无需再做兼容处理。
12
+ *
9
13
  * Usage:
10
14
  * node env-manager.mjs --env test # 解析指定环境
11
15
  * node env-manager.mjs --env test --print # 输出 export 语句
@@ -126,49 +130,35 @@ export function readDotEnv() {
126
130
  }
127
131
 
128
132
  /**
129
- * Get the default environment name.
130
- * Priority: settings.json > .env
133
+ * Get the default environment name from .deepstorm/settings.json.
131
134
  * Falls back to 'test' if not configured.
132
135
  */
133
- export function getDefaultEnv(envMap) {
136
+ export function getDefaultEnv() {
134
137
  const dsEnvs = readDeepstormEnvironments();
135
138
  if (dsEnvs && dsEnvs.default) {
136
139
  return dsEnvs.default;
137
140
  }
138
- return envMap.DEFAULT_ENV || 'test';
141
+ return 'test';
139
142
  }
140
143
 
141
144
  /**
142
- * List all available environments.
143
- * Priority: settings.json > .env
144
- * Detects BASE_URL_{ENV} patterns and returns their names.
145
+ * List all available environments from .deepstorm/settings.json.
146
+ *
147
+ * Reads sweep.environments and returns environment name + URL pairs.
148
+ * Returns empty array if not configured.
145
149
  */
146
- export function listEnvs(envMap) {
150
+ export function listEnvs() {
147
151
  const dsEnvs = readDeepstormEnvironments();
148
- if (dsEnvs) {
149
- const envs = [];
150
- for (const [name, config] of Object.entries(dsEnvs)) {
151
- if (name === 'default') continue;
152
- if (config && config.baseUrl) {
153
- envs.push({
154
- name: name.toLowerCase(),
155
- key: `BASE_URL_${name.toUpperCase()}`,
156
- url: config.baseUrl,
157
- });
158
- }
159
- }
160
- return envs;
161
- }
152
+ if (!dsEnvs) return [];
162
153
 
163
- // Fallback to .env-based envMap
164
154
  const envs = [];
165
- for (const key of Object.keys(envMap)) {
166
- const match = key.match(/^BASE_URL_(.+)$/);
167
- if (match) {
155
+ for (const [name, config] of Object.entries(dsEnvs)) {
156
+ if (name === 'default') continue;
157
+ if (config && config.baseUrl) {
168
158
  envs.push({
169
- name: match[1].toLowerCase(),
170
- key: key,
171
- url: envMap[key],
159
+ name: name.toLowerCase(),
160
+ key: `BASE_URL_${name.toUpperCase()}`,
161
+ url: config.baseUrl,
172
162
  });
173
163
  }
174
164
  }
@@ -176,36 +166,27 @@ export function listEnvs(envMap) {
176
166
  }
177
167
 
178
168
  /**
179
- * Resolve target environment config.
180
- *
181
- * Priority: settings.json > .env
169
+ * Resolve target environment config from .deepstorm/settings.json.
182
170
  *
183
171
  * @param {string} [envName] - Target environment name (e.g. 'staging', 'test')
184
172
  * @returns {{ env: string, baseUrl: string|null, availableEnvs: Array<{name:string,url:string}> }}
185
173
  *
186
174
  * If envName is omitted, uses DEFAULT_ENV (or 'test').
175
+ * If settings.json has no environments config, baseUrl is null and availableEnvs is empty.
187
176
  * If the environment is not found, baseUrl is null and availableEnvs lists alternatives.
188
177
  */
189
178
  export function resolveEnv(envName) {
190
- // Try settings.json first
191
179
  const dsEnvs = readDeepstormEnvironments();
192
- if (dsEnvs) {
193
- const { envMap, defaultEnv } = deepstormEnvsToEnvMap(dsEnvs);
194
- const name = envName || defaultEnv;
195
- const availableEnvs = listEnvs(envMap);
196
- const baseUrlKey = `BASE_URL_${name.toUpperCase()}`;
197
- const baseUrl = envMap[baseUrlKey] || null;
198
- return { env: name, baseUrl, availableEnvs };
180
+ if (!dsEnvs) {
181
+ const name = envName || 'test';
182
+ return { env: name, baseUrl: null, availableEnvs: [] };
199
183
  }
200
184
 
201
- // Fallback to .env
202
- const envMap = readDotEnv();
203
- const name = envName || getDefaultEnv(envMap);
204
- const availableEnvs = listEnvs(envMap);
205
-
185
+ const { envMap, defaultEnv } = deepstormEnvsToEnvMap(dsEnvs);
186
+ const name = envName || defaultEnv;
187
+ const availableEnvs = listEnvs();
206
188
  const baseUrlKey = `BASE_URL_${name.toUpperCase()}`;
207
189
  const baseUrl = envMap[baseUrlKey] || null;
208
-
209
190
  return { env: name, baseUrl, availableEnvs };
210
191
  }
211
192
 
@@ -263,9 +244,8 @@ if (process.argv[1] === import.meta.filename) {
263
244
  const args = process.argv.slice(2);
264
245
 
265
246
  if (args.includes('--list')) {
266
- const envMap = readDotEnv();
267
- const envs = listEnvs(envMap);
268
- const defaultEnv = getDefaultEnv(envMap);
247
+ const envs = listEnvs();
248
+ const defaultEnv = getDefaultEnv();
269
249
  console.log(JSON.stringify({ default: defaultEnv, environments: envs }));
270
250
  process.exit(0);
271
251
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deepstorm/cli",
3
- "version": "0.9.0",
3
+ "version": "0.9.1",
4
4
  "description": "DeepStorm CLI — 一键配置项目开发环境",
5
5
  "license": "MIT",
6
6
  "author": "billkang",
@@ -16,7 +16,7 @@
16
16
  "dotenv": "^17.4.2",
17
17
  "handlebars": "^4.7.8",
18
18
  "js-yaml": "^4.1.0",
19
- "@deepstorm/pilot": "^0.9.0"
19
+ "@deepstorm/pilot": "^0.9.1"
20
20
  },
21
21
  "devDependencies": {
22
22
  "@types/node": "^22.0.0",