@deepstorm/cli 0.2.2 → 0.2.4

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 +448 -160
  2. package/package.json +1 -1
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,11 +3110,11 @@ 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
  };
3117
- function relative(aRoot, aPath) {
3117
+ function relative2(aRoot, aPath) {
3118
3118
  if (aRoot === "") {
3119
3119
  aRoot = ".";
3120
3120
  }
@@ -3133,7 +3133,7 @@ var require_util = __commonJS({
3133
3133
  }
3134
3134
  return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1);
3135
3135
  }
3136
- exports2.relative = relative;
3136
+ exports2.relative = relative2;
3137
3137
  var supportsNullProto = (function() {
3138
3138
  var obj = /* @__PURE__ */ Object.create(null);
3139
3139
  return !("__proto__" in obj);
@@ -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 fs24 = require("fs");
5902
- var templateString = fs24.readFileSync(filename, "utf8");
5901
+ var fs25 = require("fs");
5902
+ var templateString = fs25.readFileSync(filename, "utf8");
5903
5903
  module3.exports = handlebars.compile(templateString);
5904
5904
  }
5905
5905
  if (typeof require !== "undefined" && require.extensions) {
@@ -5911,8 +5911,8 @@ var require_lib = __commonJS({
5911
5911
 
5912
5912
  // src/index.ts
5913
5913
  var import_commander = require("commander");
5914
- var fs23 = __toESM(require("node:fs"));
5915
- var path21 = __toESM(require("node:path"));
5914
+ var fs24 = __toESM(require("node:fs"));
5915
+ var path22 = __toESM(require("node:path"));
5916
5916
 
5917
5917
  // src/commands/setup.ts
5918
5918
  var path6 = __toESM(require("node:path"));
@@ -6996,7 +6996,7 @@ async function runSetup(reader, targetDir, cliDir2, options, registry2) {
6996
6996
  enabledMcpJsonServers = Object.keys(servers);
6997
6997
  console.log(`\u2714 \u5DF2\u5B89\u88C5 ${selectedMcpTools.length} \u4E2A MCP \u670D\u52A1`);
6998
6998
  }
6999
- installMcpSkills(tools, reader, cliDir2, targetDir, installedSkillIds);
6999
+ installMcpSkills(tools, reader, cliDir2, targetDir, installedSkillIds, selectedMcpTools);
7000
7000
  for (const tool of tools) {
7001
7001
  const ids = renderToolAssets(tool, reader, cliDir2, targetDir, templateVariables, config, registry2, selectedMcpTools);
7002
7002
  installedSkillIds.push(...ids);
@@ -7092,7 +7092,7 @@ function shouldSkipAgent(agentFile, config) {
7092
7092
  const value = config[configKey];
7093
7093
  return !value || value === "none";
7094
7094
  }
7095
- function renderToolAssets(tool, reader, cliDir2, targetDir, templateVariables, config, registry2, installedMcpTools = [], targetSubDir = ".claude") {
7095
+ function renderToolAssets(tool, reader, cliDir2, targetDir, templateVariables, config, registry2, installedMcpTools = [], targetSubDir = ".claude", skillIdFilter) {
7096
7096
  const installedSkillIds = [];
7097
7097
  const targetSkillsDir = targetSubDir ? path6.join(targetDir, targetSubDir, "skills") : path6.join(targetDir, "skills");
7098
7098
  const toolSkills = reader.getToolSkills(tool);
@@ -7100,6 +7100,7 @@ function renderToolAssets(tool, reader, cliDir2, targetDir, templateVariables, c
7100
7100
  for (const skill of toolSkills) {
7101
7101
  const skillId = getSkillId(skill, registry2);
7102
7102
  if (!skillId) continue;
7103
+ if (skillIdFilter && !skillIdFilter.has(skillId)) continue;
7103
7104
  if (shouldSkipSkill(skill, config)) {
7104
7105
  console.log(` \u23ED ${skillId}\uFF1A\u4F9D\u8D56 ${skill.configKey} \u672A\u914D\u7F6E\uFF0C\u8DF3\u8FC7`);
7105
7106
  continue;
@@ -7180,14 +7181,21 @@ function renderToolAssets(tool, reader, cliDir2, targetDir, templateVariables, c
7180
7181
  }
7181
7182
  return installedSkillIds;
7182
7183
  }
7183
- function installMcpSkills(tools, reader, cliDir2, targetDir, installedSkillIds) {
7184
+ function installMcpSkills(tools, reader, cliDir2, targetDir, installedSkillIds, selectedMcpTools = []) {
7184
7185
  const mcpSkillsDir = path6.join(cliDir2, "mcp-skills");
7185
7186
  const targetSkillsDir = path6.join(targetDir, ".claude", "skills");
7186
7187
  if (!fs10.existsSync(mcpSkillsDir)) return;
7188
+ if (selectedMcpTools.length === 0) {
7189
+ console.log("\u23ED \u672A\u9009\u62E9 MCP \u670D\u52A1\uFF0C\u8DF3\u8FC7 MCP \u6280\u80FD\u5B89\u88C5");
7190
+ return;
7191
+ }
7192
+ const selectedMcpSet = new Set(selectedMcpTools);
7187
7193
  const neededSkills = /* @__PURE__ */ new Set();
7188
7194
  for (const tool of tools) {
7189
7195
  const toolMcpSkills = reader.getToolMcpSkills(tool);
7190
7196
  for (const skillId of toolMcpSkills) {
7197
+ const service = skillId.replace(/^deepstorm-mcp-/, "").replace(/-(read|write)$/, "");
7198
+ if (!selectedMcpSet.has(service)) continue;
7191
7199
  neededSkills.add(skillId);
7192
7200
  }
7193
7201
  }
@@ -8117,6 +8125,8 @@ function registerTemplateCommand(program2, registry2) {
8117
8125
  }
8118
8126
 
8119
8127
  // src/commands/update.ts
8128
+ var fs21 = __toESM(require("node:fs"));
8129
+ var path19 = __toESM(require("node:path"));
8120
8130
  var import_node_child_process = require("node:child_process");
8121
8131
 
8122
8132
  // src/utils/version.ts
@@ -8143,32 +8153,331 @@ function getCliVersion() {
8143
8153
  // src/commands/template-upgrade.ts
8144
8154
  var fs20 = __toESM(require("node:fs"));
8145
8155
  var path18 = __toESM(require("node:path"));
8146
- function upgradeTemplates(cliDir2, targetDir, skillIds) {
8147
- const templatesDir = path18.join(targetDir, ".deepstorm", "templates");
8156
+ var crypto = __toESM(require("node:crypto"));
8157
+ var CHECKSUM_FILE = "deepstorm-checksums.json";
8158
+ function computeFileChecksum(filePath) {
8159
+ try {
8160
+ if (!fs20.existsSync(filePath)) return null;
8161
+ const content = fs20.readFileSync(filePath);
8162
+ return crypto.createHash("sha256").update(content).digest("hex");
8163
+ } catch {
8164
+ return null;
8165
+ }
8166
+ }
8167
+ function computeDirChecksums(dirPath, relativeTo = dirPath) {
8168
+ const result = {};
8169
+ if (!fs20.existsSync(dirPath)) return result;
8170
+ function walk(current) {
8171
+ for (const entry of fs20.readdirSync(current, { withFileTypes: true })) {
8172
+ const fullPath = path18.join(current, entry.name);
8173
+ if (entry.name === ".DS_Store") continue;
8174
+ if (entry.isDirectory()) {
8175
+ walk(fullPath);
8176
+ } else if (entry.isFile()) {
8177
+ const relPath = path18.relative(relativeTo, fullPath);
8178
+ const checksum = computeFileChecksum(fullPath);
8179
+ if (checksum) result[relPath] = checksum;
8180
+ }
8181
+ }
8182
+ }
8183
+ walk(dirPath);
8184
+ return result;
8185
+ }
8186
+ function loadChecksums(targetDir) {
8187
+ const filePath = path18.join(targetDir, ".claude", CHECKSUM_FILE);
8188
+ try {
8189
+ return JSON.parse(fs20.readFileSync(filePath, "utf-8"));
8190
+ } catch {
8191
+ return {};
8192
+ }
8193
+ }
8194
+ function saveChecksums(targetDir, checksums) {
8195
+ const dir = path18.join(targetDir, ".claude");
8196
+ ensureDir(dir);
8197
+ fs20.writeFileSync(
8198
+ path18.join(dir, CHECKSUM_FILE),
8199
+ JSON.stringify(checksums, null, 2) + "\n",
8200
+ "utf-8"
8201
+ );
8202
+ }
8203
+ function backupFile(filePath) {
8204
+ try {
8205
+ if (!fs20.existsSync(filePath)) return null;
8206
+ const dir = path18.dirname(filePath);
8207
+ const ext = path18.extname(filePath);
8208
+ const base = path18.basename(filePath, ext);
8209
+ const timestamp = Date.now();
8210
+ const bakName = `${base}.${timestamp}.bak`;
8211
+ const bakPath = path18.join(dir, bakName);
8212
+ fs20.cpSync(filePath, bakPath, { force: true });
8213
+ return bakName;
8214
+ } catch {
8215
+ return null;
8216
+ }
8217
+ }
8218
+ function checkAndBackup(fileKey, filePath, stored, backedUp) {
8219
+ const lastChecksum = stored[fileKey];
8220
+ if (!lastChecksum) return;
8221
+ const current = computeFileChecksum(filePath);
8222
+ if (current === null) return;
8223
+ if (current === lastChecksum) return;
8224
+ const bakName = backupFile(filePath);
8225
+ if (bakName) {
8226
+ backedUp.push(`${fileKey} \u2192 ${bakName}`);
8227
+ }
8228
+ }
8229
+ function backupModifiedAssets(targetDir, skillIds, toolNames, registry2) {
8230
+ const stored = loadChecksums(targetDir);
8231
+ const backedUp = [];
8232
+ for (const skillId of skillIds) {
8233
+ const skillDir = path18.join(targetDir, ".claude", "skills", skillId);
8234
+ if (!fs20.existsSync(skillDir)) continue;
8235
+ const checksums = computeDirChecksums(skillDir);
8236
+ for (const [relPath] of Object.entries(checksums)) {
8237
+ const key = `skills/${skillId}/${relPath}`;
8238
+ checkAndBackup(key, path18.join(skillDir, relPath), stored, backedUp);
8239
+ }
8240
+ }
8241
+ const reader = new RegistryReader(registry2);
8242
+ for (const tool of toolNames) {
8243
+ const agents = reader.getToolAgents(tool);
8244
+ for (const agentFile of agents) {
8245
+ const filePath = path18.join(targetDir, ".claude", "agents", agentFile.replace(/\.tmpl$/, ""));
8246
+ const key = `agents/${agentFile.replace(/\.tmpl$/, "")}`;
8247
+ checkAndBackup(key, filePath, stored, backedUp);
8248
+ }
8249
+ }
8250
+ for (const tool of toolNames) {
8251
+ const hooks = reader.getToolHooks(tool);
8252
+ for (const hookFile of hooks) {
8253
+ const filePath = path18.join(targetDir, ".claude", "hooks", hookFile);
8254
+ const key = `hooks/${hookFile}`;
8255
+ checkAndBackup(key, filePath, stored, backedUp);
8256
+ }
8257
+ }
8258
+ return backedUp;
8259
+ }
8260
+ function storeNewChecksums(targetDir, skillIds, toolNames, registry2) {
8261
+ const newChecksums = {};
8262
+ const reader = new RegistryReader(registry2);
8148
8263
  for (const skillId of skillIds) {
8149
- const userTemplate = path18.join(templatesDir, skillId);
8150
- if (fs20.existsSync(userTemplate)) {
8151
- console.log(`${skillId}\uFF1A\u68C0\u6D4B\u5230\u7528\u6237\u4FEE\u6539\uFF0C\u8DF3\u8FC7\u3002\u5982\u9700\u540C\u6B65\u8BF7\u8FD0\u884C deepstorm template apply ${skillId}`);
8264
+ const skillDir = path18.join(targetDir, ".claude", "skills", skillId);
8265
+ const checksums = computeDirChecksums(skillDir);
8266
+ for (const [relPath, checksum] of Object.entries(checksums)) {
8267
+ newChecksums[`skills/${skillId}/${relPath}`] = checksum;
8268
+ }
8269
+ }
8270
+ for (const tool of toolNames) {
8271
+ const agents = reader.getToolAgents(tool);
8272
+ for (const agentFile of agents) {
8273
+ const installedName = agentFile.replace(/\.tmpl$/, "");
8274
+ const filePath = path18.join(targetDir, ".claude", "agents", installedName);
8275
+ const chk = computeFileChecksum(filePath);
8276
+ if (chk) newChecksums[`agents/${installedName}`] = chk;
8277
+ }
8278
+ }
8279
+ for (const tool of toolNames) {
8280
+ const hooks = reader.getToolHooks(tool);
8281
+ for (const hookFile of hooks) {
8282
+ const filePath = path18.join(targetDir, ".claude", "hooks", hookFile);
8283
+ const chk = computeFileChecksum(filePath);
8284
+ if (chk) newChecksums[`hooks/${hookFile}`] = chk;
8285
+ }
8286
+ }
8287
+ saveChecksums(targetDir, newChecksums);
8288
+ }
8289
+ function skillIdsToTools(skillIds, registry2) {
8290
+ const toolSet = /* @__PURE__ */ new Set();
8291
+ for (const skillId of skillIds) {
8292
+ const skill = registry2.skills[skillId];
8293
+ if (skill?.tool) {
8294
+ toolSet.add(skill.tool);
8295
+ }
8296
+ }
8297
+ return [...toolSet];
8298
+ }
8299
+ function readSettingsConfig(targetDir) {
8300
+ const settingsPath = path18.join(targetDir, ".claude", "settings.json");
8301
+ try {
8302
+ const raw = fs20.readFileSync(settingsPath, "utf-8");
8303
+ const settings = JSON.parse(raw);
8304
+ const deepstorm = settings.deepstorm || {};
8305
+ const metaKeys = /* @__PURE__ */ new Set([
8306
+ "installedSkills",
8307
+ "installedMcpServers",
8308
+ "installedAt",
8309
+ "mcpCapabilities"
8310
+ ]);
8311
+ const config = {};
8312
+ flattenNestedConfig(deepstorm, "", config, metaKeys);
8313
+ const installedMcpTools = deepstorm.installedMcpServers ?? [];
8314
+ return { config, installedMcpTools };
8315
+ } catch {
8316
+ return { config: {}, installedMcpTools: [] };
8317
+ }
8318
+ }
8319
+ function flattenNestedConfig(obj, prefix, result, skipKeys) {
8320
+ for (const [key, value] of Object.entries(obj)) {
8321
+ if (skipKeys.has(key)) continue;
8322
+ const fullKey = prefix ? `${prefix}.${key}` : key;
8323
+ if (value !== null && typeof value === "object" && !Array.isArray(value)) {
8324
+ flattenNestedConfig(value, fullKey, result, skipKeys);
8325
+ } else if (typeof value === "string") {
8326
+ result[fullKey] = value;
8327
+ }
8328
+ }
8329
+ }
8330
+ function loadRegistryFromCliDir(cliDir2) {
8331
+ const registryPath = path18.join(cliDir2, "registry.json");
8332
+ try {
8333
+ const raw = fs20.readFileSync(registryPath, "utf-8");
8334
+ return JSON.parse(raw);
8335
+ } catch {
8336
+ return null;
8337
+ }
8338
+ }
8339
+ function mergeToolHooksJson(toolNames, cliDir2, targetDir) {
8340
+ const hooksSrcDir = path18.join(cliDir2, "hooks");
8341
+ const targetHooksDir = path18.join(targetDir, ".claude", "hooks");
8342
+ const destHooksJson = path18.join(targetHooksDir, "hooks.json");
8343
+ for (const tool of toolNames) {
8344
+ const toolHooksJsonPath = path18.join(hooksSrcDir, `${tool}-hooks.json`);
8345
+ if (fs20.existsSync(toolHooksJsonPath)) {
8346
+ ensureDir(targetHooksDir);
8347
+ const incoming = JSON.parse(fs20.readFileSync(toolHooksJsonPath, "utf-8"));
8348
+ mergeHooks(destHooksJson, incoming);
8349
+ }
8350
+ }
8351
+ }
8352
+ function syncToolAssets(cliDir2, targetDir, installedSkillIds) {
8353
+ const registry2 = loadRegistryFromCliDir(cliDir2);
8354
+ if (!registry2) {
8355
+ console.log("\u26A0 \u65E0\u6CD5\u52A0\u8F7D registry.json\uFF0C\u8DF3\u8FC7\u8D44\u4EA7\u540C\u6B65");
8356
+ return { syncedSkills: [], syncedAgents: [], syncedHooks: [], backedUpFiles: [] };
8357
+ }
8358
+ const reader = new RegistryReader(registry2);
8359
+ const toolNames = skillIdsToTools(installedSkillIds, registry2);
8360
+ if (toolNames.length === 0) {
8361
+ console.log("\u26A0 \u65E0\u6CD5\u4ECE\u5DF2\u5B89\u88C5 skill \u89E3\u6790\u5DE5\u5177\u540D\u79F0\uFF0C\u8DF3\u8FC7\u8D44\u4EA7\u540C\u6B65");
8362
+ return { syncedSkills: [], syncedAgents: [], syncedHooks: [], backedUpFiles: [] };
8363
+ }
8364
+ const { config, installedMcpTools } = readSettingsConfig(targetDir);
8365
+ const templateVariables = buildTemplateVariables(registry2, config, installedMcpTools);
8366
+ const mcpSkillSet = /* @__PURE__ */ new Set();
8367
+ if (installedMcpTools.length > 0) {
8368
+ const selectedMcpSet = new Set(installedMcpTools);
8369
+ for (const tool of toolNames) {
8370
+ for (const skillId of reader.getToolMcpSkills(tool)) {
8371
+ const service = skillId.replace(/^deepstorm-mcp-/, "").replace(/-(read|write)$/, "");
8372
+ if (selectedMcpSet.has(service)) mcpSkillSet.add(skillId);
8373
+ }
8374
+ }
8375
+ }
8376
+ const mcpSkillIds = [...mcpSkillSet];
8377
+ const allSkillIdsForBackup = [.../* @__PURE__ */ new Set([...installedSkillIds, ...mcpSkillIds])];
8378
+ const backedUpFiles = backupModifiedAssets(targetDir, allSkillIdsForBackup, toolNames, registry2);
8379
+ if (backedUpFiles.length > 0) {
8380
+ console.log("\n\u26A0 \u68C0\u6D4B\u5230\u7528\u6237\u4FEE\u6539\u7684\u6587\u4EF6\uFF1A");
8381
+ for (const info of backedUpFiles) {
8382
+ console.log(` \u5DF2\u5907\u4EFD ${info}`);
8383
+ }
8384
+ console.log("");
8385
+ }
8386
+ const actualSkillIds = [];
8387
+ const syncedAgents = [];
8388
+ const syncedHooks = [];
8389
+ let hasWarning = false;
8390
+ for (const tool of toolNames) {
8391
+ try {
8392
+ reader.getToolEntry(tool);
8393
+ } catch {
8152
8394
  continue;
8153
8395
  }
8154
- const src = path18.join(cliDir2, "skills", skillId);
8155
- const dest = path18.join(targetDir, ".claude", "skills", skillId);
8156
- if (fs20.existsSync(src)) {
8157
- ensureDir(path18.dirname(dest));
8158
- copyDir(src, dest);
8159
- console.log(`\u2714 ${skillId} \u5DF2\u66F4\u65B0`);
8396
+ const beforeAgents = reader.getToolAgents(tool);
8397
+ const beforeHooks = reader.getToolHooks(tool);
8398
+ try {
8399
+ const ids = renderToolAssets(
8400
+ tool,
8401
+ reader,
8402
+ cliDir2,
8403
+ targetDir,
8404
+ templateVariables,
8405
+ config,
8406
+ registry2,
8407
+ installedMcpTools,
8408
+ ".claude"
8409
+ );
8410
+ actualSkillIds.push(...ids);
8411
+ syncedAgents.push(...beforeAgents);
8412
+ syncedHooks.push(...beforeHooks);
8413
+ } catch (err) {
8414
+ hasWarning = true;
8415
+ console.log(` \u26A0 ${tool} \u540C\u6B65\u51FA\u9519: ${err instanceof Error ? err.message : String(err)}`);
8416
+ }
8417
+ }
8418
+ const syncedSkills = actualSkillIds.length > 0 ? actualSkillIds : [...installedSkillIds];
8419
+ const syncedMcpSkillIds = [];
8420
+ if (installedMcpTools.length > 0) {
8421
+ installMcpSkills(toolNames, reader, cliDir2, targetDir, syncedMcpSkillIds, installedMcpTools);
8422
+ }
8423
+ mergeToolHooksJson(toolNames, cliDir2, targetDir);
8424
+ const allSkillIds = [...installedSkillIds, ...syncedMcpSkillIds];
8425
+ storeNewChecksums(targetDir, allSkillIds, toolNames, registry2);
8426
+ if (hasWarning) {
8427
+ console.log("\n\u26A0 \u90E8\u5206\u5DE5\u5177\u540C\u6B65\u51FA\u9519\uFF0C\u8BF7\u68C0\u67E5\u540E\u91CD\u8BD5");
8428
+ }
8429
+ const uniqueAgents = [...new Set(syncedAgents)];
8430
+ const uniqueHooks = [...new Set(syncedHooks)];
8431
+ return {
8432
+ syncedSkills: [...syncedSkills, ...syncedMcpSkillIds],
8433
+ syncedAgents: uniqueAgents,
8434
+ syncedHooks: uniqueHooks,
8435
+ backedUpFiles
8436
+ };
8437
+ }
8438
+ function upgradeTemplates(cliDir2, targetDir, skillIds) {
8439
+ const report = syncToolAssets(cliDir2, targetDir, skillIds);
8440
+ if (report.syncedSkills.length > 0) {
8441
+ const count = report.syncedSkills.length;
8442
+ const agentCount = report.syncedAgents.length;
8443
+ const hookCount = report.syncedHooks.length;
8444
+ console.log(`
8445
+ \u2714 \u540C\u6B65\u5B8C\u6210\uFF1A${count} \u4E2A skill${agentCount > 0 ? `\u3001${agentCount} \u4E2A agent` : ""}${hookCount > 0 ? `\u3001${hookCount} \u4E2A hook` : ""}`);
8446
+ if (report.backedUpFiles.length > 0) {
8447
+ console.log(` \u5DF2\u5907\u4EFD ${report.backedUpFiles.length} \u4E2A\u4FEE\u6539\u8FC7\u7684\u6587\u4EF6`);
8160
8448
  }
8161
8449
  }
8162
8450
  }
8163
8451
 
8164
8452
  // src/commands/update.ts
8165
8453
  var NPM_REGISTRY_URL = "https://registry.npmjs.org/@deepstorm/cli/latest";
8454
+ function getRegistryUrl() {
8455
+ return process.env.DEEPSTORM_REGISTRY_URL || NPM_REGISTRY_URL;
8456
+ }
8457
+ function readLocalRegistryFile(url) {
8458
+ let filePath = url;
8459
+ if (filePath.startsWith("file://")) {
8460
+ filePath = filePath.slice(7);
8461
+ }
8462
+ try {
8463
+ if (fs21.existsSync(filePath)) {
8464
+ return JSON.parse(fs21.readFileSync(filePath, "utf-8"));
8465
+ }
8466
+ } catch {
8467
+ }
8468
+ return null;
8469
+ }
8166
8470
  async function checkNpmVersion(fetchFn = globalThis.fetch) {
8167
8471
  const current = getCliVersion();
8472
+ const url = getRegistryUrl();
8168
8473
  try {
8474
+ const localData = readLocalRegistryFile(url);
8475
+ if (localData) {
8476
+ return parseVersionResponse(localData, current);
8477
+ }
8169
8478
  const controller = new AbortController();
8170
8479
  const timeout = setTimeout(() => controller.abort(), 5e3);
8171
- const response = await fetchFn(NPM_REGISTRY_URL, {
8480
+ const response = await fetchFn(url, {
8172
8481
  signal: controller.signal
8173
8482
  });
8174
8483
  clearTimeout(timeout);
@@ -8176,47 +8485,52 @@ async function checkNpmVersion(fetchFn = globalThis.fetch) {
8176
8485
  return {
8177
8486
  current,
8178
8487
  latest: null,
8179
- error: `npm registry \u8FD4\u56DE\u72B6\u6001\u7801 ${response.status}`
8488
+ error: `registry \u8FD4\u56DE\u72B6\u6001\u7801 ${response.status}`
8180
8489
  };
8181
8490
  }
8182
8491
  const data = await response.json();
8183
- const latest = data.version;
8184
- if (!latest) {
8185
- return {
8186
- current,
8187
- latest: null,
8188
- error: "\u65E0\u6CD5\u89E3\u6790 registry \u54CD\u5E94\u4E2D\u7684\u7248\u672C\u53F7"
8189
- };
8190
- }
8191
- const isUpToDate = current === latest;
8192
- const hasUpdate = !isUpToDate && latest !== null;
8492
+ return parseVersionResponse(data, current);
8493
+ } catch (err) {
8494
+ const message = err instanceof Error ? err.message : String(err);
8495
+ const hint = message.includes("abort") ? "\u8FDE\u63A5\u8D85\u65F6" : message.includes("fetch failed") || message.includes("ECONNREFUSED") || message.includes("ENOTFOUND") ? `\u65E0\u6CD5\u8FDE\u63A5 registry\uFF08${url}\uFF09\uFF0C\u8BF7\u68C0\u67E5\u7F51\u7EDC` : message;
8193
8496
  return {
8194
8497
  current,
8195
- latest,
8196
- isUpToDate,
8197
- hasUpdate
8498
+ latest: null,
8499
+ error: hint
8198
8500
  };
8199
- } catch (err) {
8200
- const message = err instanceof Error ? err.message : String(err);
8501
+ }
8502
+ }
8503
+ function parseVersionResponse(data, current) {
8504
+ const latest = data.version;
8505
+ if (!latest) {
8201
8506
  return {
8202
8507
  current,
8203
8508
  latest: null,
8204
- error: message
8509
+ error: "\u65E0\u6CD5\u89E3\u6790 registry \u54CD\u5E94\u4E2D\u7684\u7248\u672C\u53F7"
8205
8510
  };
8206
8511
  }
8512
+ const isUpToDate = current === latest;
8513
+ const hasUpdate = !isUpToDate && latest !== null;
8514
+ return {
8515
+ current,
8516
+ latest,
8517
+ isUpToDate,
8518
+ hasUpdate
8519
+ };
8207
8520
  }
8208
8521
  async function updateCLI(fetchFn) {
8209
8522
  const result = await checkNpmVersion(fetchFn);
8210
8523
  if (result.error) {
8211
8524
  console.log(`\u26A0 \u65E0\u6CD5\u68C0\u67E5\u66F4\u65B0\uFF1A${result.error}`);
8212
- return;
8525
+ return result;
8213
8526
  }
8214
8527
  console.log(`\u2714 \u5F53\u524D\u7248\u672C: v${result.current}`);
8215
8528
  console.log(`\u2714 \u6700\u65B0\u7248\u672C: v${result.latest}`);
8216
8529
  if (result.hasUpdate) {
8217
8530
  console.log("\u2192 \u6B63\u5728\u81EA\u52A8\u66F4\u65B0...");
8531
+ const updateCmd = process.env.DEEPSTORM_UPDATE_CMD || "npm install -g @deepstorm/cli@latest";
8218
8532
  try {
8219
- (0, import_node_child_process.execSync)("npm install -g @deepstorm/cli@latest", { stdio: "inherit" });
8533
+ (0, import_node_child_process.execSync)(updateCmd, { stdio: "inherit" });
8220
8534
  console.log(`
8221
8535
  \u2714 \u5DF2\u66F4\u65B0\u81F3 v${result.latest}`);
8222
8536
  } catch {
@@ -8226,63 +8540,37 @@ async function updateCLI(fetchFn) {
8226
8540
  } else {
8227
8541
  console.log("\u2713 \u5DF2\u662F\u6700\u65B0\u7248\u672C");
8228
8542
  }
8543
+ return result;
8229
8544
  }
8230
- function updateSkills(cliDir2, targetDir, skillIds) {
8231
- upgradeTemplates(cliDir2, targetDir, skillIds);
8545
+ function getInstalledSkillIds(targetDir) {
8546
+ const settingsPath = path19.join(targetDir, ".claude", "settings.json");
8547
+ try {
8548
+ const raw = fs21.readFileSync(settingsPath, "utf-8");
8549
+ const settings = JSON.parse(raw);
8550
+ return settings.deepstorm?.installedSkills ?? [];
8551
+ } catch {
8552
+ return [];
8553
+ }
8232
8554
  }
8233
- function registerUpdateCommand(program2, registry2) {
8555
+ function registerUpdateCommand(program2) {
8234
8556
  const cliDir2 = __dirname;
8235
- const updateCmd = program2.command("update").description("\u68C0\u67E5\u66F4\u65B0\u5E76\u540C\u6B65 skill \u6A21\u677F");
8236
- updateCmd.option("--check", "\u4EC5\u68C0\u67E5 npm \u6700\u65B0\u7248\u672C").option("--cli", "\u66F4\u65B0 CLI \u81EA\u8EAB").option("--skills", "\u540C\u6B65 skill \u6A21\u677F\u5230\u672C\u5730").action(async (options) => {
8237
- const { check, cli, skills } = options;
8238
- if (!check && !cli && !skills) {
8239
- await updateCLI();
8240
- console.log("");
8241
- upgradeTemplates(cliDir2, process.cwd(), Object.keys(registry2.skills));
8242
- return;
8243
- }
8244
- if (check) {
8245
- const result = await checkNpmVersion();
8246
- printVersionInfo(result);
8247
- if (result.error) process.exit(1);
8248
- return;
8249
- }
8250
- if (cli) {
8251
- await updateCLI();
8252
- return;
8253
- }
8254
- if (skills) {
8255
- const skillIds = Object.keys(registry2.skills);
8256
- if (skillIds.length === 0) {
8257
- console.log("registry \u4E2D\u65E0\u5DF2\u6CE8\u518C skill");
8258
- return;
8259
- }
8260
- updateSkills(cliDir2, process.cwd(), skillIds);
8261
- return;
8557
+ 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 () => {
8558
+ const installedIds = getInstalledSkillIds(process.cwd());
8559
+ if (installedIds.length === 0) {
8560
+ console.log("\u672A\u68C0\u6D4B\u5230\u5DF2\u5B89\u88C5\u7684 skill\uFF0C\u8DF3\u8FC7\u540C\u6B65");
8561
+ } else {
8562
+ upgradeTemplates(cliDir2, process.cwd(), installedIds);
8262
8563
  }
8564
+ await updateCLI();
8263
8565
  });
8264
8566
  }
8265
- function printVersionInfo(result) {
8266
- if (result.error) {
8267
- console.log(`\u26A0 \u65E0\u6CD5\u68C0\u67E5\u66F4\u65B0\uFF1A${result.error}`);
8268
- return;
8269
- }
8270
- console.log(`\u2714 \u5F53\u524D\u7248\u672C: v${result.current}`);
8271
- console.log(`\u2714 \u6700\u65B0\u7248\u672C: v${result.latest}`);
8272
- if (result.hasUpdate) {
8273
- console.log("");
8274
- console.log('\u2192 \u6709\u65B0\u7248\u672C\u53EF\u7528\uFF01\u8FD0\u884C "deepstorm update --cli" \u66F4\u65B0');
8275
- } else {
8276
- console.log("\u2713 \u5DF2\u662F\u6700\u65B0\u7248\u672C");
8277
- }
8278
- }
8279
8567
 
8280
8568
  // src/commands/doctor.ts
8281
- var fs21 = __toESM(require("node:fs"));
8282
- var path19 = __toESM(require("node:path"));
8569
+ var fs22 = __toESM(require("node:fs"));
8570
+ var path20 = __toESM(require("node:path"));
8283
8571
  function getInstalledSkills(settingsPath) {
8284
8572
  try {
8285
- const settings = JSON.parse(fs21.readFileSync(settingsPath, "utf-8"));
8573
+ const settings = JSON.parse(fs22.readFileSync(settingsPath, "utf-8"));
8286
8574
  return settings.deepstorm?.installedSkills || [];
8287
8575
  } catch {
8288
8576
  return [];
@@ -8291,7 +8579,7 @@ function getInstalledSkills(settingsPath) {
8291
8579
  function runDoctor(targetDir) {
8292
8580
  const checks = [];
8293
8581
  const version = getCliVersion();
8294
- const settingsPath = path19.join(targetDir, ".claude", "settings.json");
8582
+ const settingsPath = path20.join(targetDir, ".claude", "settings.json");
8295
8583
  readDeepStormConfig(settingsPath);
8296
8584
  checks.push({
8297
8585
  name: "CLI \u7248\u672C",
@@ -8299,7 +8587,7 @@ function runDoctor(targetDir) {
8299
8587
  message: `v${version}\uFF08\u8FD0\u884C deepstorm update --check \u68C0\u67E5\u6700\u65B0\u7248\u672C\uFF09`
8300
8588
  });
8301
8589
  let hasDeepStorm = false;
8302
- if (!fs21.existsSync(settingsPath)) {
8590
+ if (!fs22.existsSync(settingsPath)) {
8303
8591
  checks.push({
8304
8592
  name: "\u914D\u7F6E\u6587\u4EF6",
8305
8593
  status: "warn",
@@ -8307,7 +8595,7 @@ function runDoctor(targetDir) {
8307
8595
  });
8308
8596
  } else {
8309
8597
  try {
8310
- const settings = JSON.parse(fs21.readFileSync(settingsPath, "utf-8"));
8598
+ const settings = JSON.parse(fs22.readFileSync(settingsPath, "utf-8"));
8311
8599
  if (settings.deepstorm) {
8312
8600
  hasDeepStorm = true;
8313
8601
  checks.push({
@@ -8330,20 +8618,20 @@ function runDoctor(targetDir) {
8330
8618
  });
8331
8619
  }
8332
8620
  }
8333
- const skillsDir = path19.join(targetDir, ".claude", "skills");
8334
- if (fs21.existsSync(skillsDir)) {
8335
- const skillDirs = fs21.readdirSync(skillsDir).filter(
8336
- (n) => fs21.statSync(path19.join(skillsDir, n)).isDirectory()
8621
+ const skillsDir = path20.join(targetDir, ".claude", "skills");
8622
+ if (fs22.existsSync(skillsDir)) {
8623
+ const skillDirs = fs22.readdirSync(skillsDir).filter(
8624
+ (n) => fs22.statSync(path20.join(skillsDir, n)).isDirectory()
8337
8625
  );
8338
8626
  let validCount = 0;
8339
8627
  let invalidCount = 0;
8340
8628
  for (const skillName of skillDirs) {
8341
- const skillMd = path19.join(skillsDir, skillName, "SKILL.md");
8342
- if (!fs21.existsSync(skillMd)) {
8629
+ const skillMd = path20.join(skillsDir, skillName, "SKILL.md");
8630
+ if (!fs22.existsSync(skillMd)) {
8343
8631
  invalidCount++;
8344
8632
  continue;
8345
8633
  }
8346
- const content = fs21.readFileSync(skillMd, "utf-8");
8634
+ const content = fs22.readFileSync(skillMd, "utf-8");
8347
8635
  const frontmatter = parseFrontmatter(content);
8348
8636
  if (frontmatter && frontmatter.name) {
8349
8637
  validCount++;
@@ -8373,7 +8661,7 @@ function runDoctor(targetDir) {
8373
8661
  const installedSkills = getInstalledSkills(settingsPath);
8374
8662
  const missingSkills = [];
8375
8663
  for (const skillId of installedSkills) {
8376
- if (!fs21.existsSync(path19.join(skillsDir, skillId))) {
8664
+ if (!fs22.existsSync(path20.join(skillsDir, skillId))) {
8377
8665
  missingSkills.push(skillId);
8378
8666
  }
8379
8667
  }
@@ -8397,10 +8685,10 @@ function runDoctor(targetDir) {
8397
8685
  message: ".claude/skills/ \u4E0D\u5B58\u5728"
8398
8686
  });
8399
8687
  }
8400
- const mcpPath = path19.join(targetDir, ".mcp.json");
8401
- if (fs21.existsSync(mcpPath)) {
8688
+ const mcpPath = path20.join(targetDir, ".mcp.json");
8689
+ if (fs22.existsSync(mcpPath)) {
8402
8690
  try {
8403
- const mcp = JSON.parse(fs21.readFileSync(mcpPath, "utf-8"));
8691
+ const mcp = JSON.parse(fs22.readFileSync(mcpPath, "utf-8"));
8404
8692
  const hasServers = mcp.mcpServers && Object.keys(mcp.mcpServers).length > 0;
8405
8693
  checks.push({
8406
8694
  name: "MCP \u670D\u52A1\u5668",
@@ -8421,12 +8709,12 @@ function runDoctor(targetDir) {
8421
8709
  message: ".mcp.json \u4E0D\u5B58\u5728"
8422
8710
  });
8423
8711
  }
8424
- if (hasDeepStorm && fs21.existsSync(settingsPath)) {
8712
+ if (hasDeepStorm && fs22.existsSync(settingsPath)) {
8425
8713
  try {
8426
- const settings = JSON.parse(fs21.readFileSync(settingsPath, "utf-8"));
8714
+ const settings = JSON.parse(fs22.readFileSync(settingsPath, "utf-8"));
8427
8715
  const installedMcp = settings.deepstorm?.installedMcpServers;
8428
8716
  if (installedMcp && installedMcp.length > 0) {
8429
- const mcpExists = fs21.existsSync(mcpPath);
8717
+ const mcpExists = fs22.existsSync(mcpPath);
8430
8718
  if (!mcpExists) {
8431
8719
  checks.push({
8432
8720
  name: "MCP \u4E00\u81F4\u6027",
@@ -8435,7 +8723,7 @@ function runDoctor(targetDir) {
8435
8723
  });
8436
8724
  } else {
8437
8725
  try {
8438
- const mcpConfig = JSON.parse(fs21.readFileSync(mcpPath, "utf-8"));
8726
+ const mcpConfig = JSON.parse(fs22.readFileSync(mcpPath, "utf-8"));
8439
8727
  const servers = mcpConfig.mcpServers || {};
8440
8728
  const missing = [];
8441
8729
  for (const toolName of installedMcp) {
@@ -8463,9 +8751,9 @@ function runDoctor(targetDir) {
8463
8751
  } catch {
8464
8752
  }
8465
8753
  }
8466
- if (hasDeepStorm && fs21.existsSync(settingsPath)) {
8754
+ if (hasDeepStorm && fs22.existsSync(settingsPath)) {
8467
8755
  try {
8468
- const settings = JSON.parse(fs21.readFileSync(settingsPath, "utf-8"));
8756
+ const settings = JSON.parse(fs22.readFileSync(settingsPath, "utf-8"));
8469
8757
  const config = settings.deepstorm;
8470
8758
  const validKeys = loadValidConfigKeys();
8471
8759
  if (validKeys.size > 0 && config) {
@@ -8519,18 +8807,18 @@ function printDoctorReport(report) {
8519
8807
  }
8520
8808
 
8521
8809
  // src/commands/uninstall.ts
8522
- var fs22 = __toESM(require("node:fs"));
8523
- var path20 = __toESM(require("node:path"));
8810
+ var fs23 = __toESM(require("node:fs"));
8811
+ var path21 = __toESM(require("node:path"));
8524
8812
  var import_prompts4 = require("@clack/prompts");
8525
8813
  async function uninstallDeepStorm(targetDir) {
8526
- const settingsPath = path20.join(targetDir, ".claude", "settings.json");
8527
- if (!fs22.existsSync(settingsPath)) {
8814
+ const settingsPath = path21.join(targetDir, ".claude", "settings.json");
8815
+ if (!fs23.existsSync(settingsPath)) {
8528
8816
  console.log("DeepStorm \u5C1A\u672A\u914D\u7F6E\uFF0C\u65E0\u9700\u5378\u8F7D");
8529
8817
  return;
8530
8818
  }
8531
8819
  let hasDeepStorm = false;
8532
8820
  try {
8533
- const settings = JSON.parse(fs22.readFileSync(settingsPath, "utf-8"));
8821
+ const settings = JSON.parse(fs23.readFileSync(settingsPath, "utf-8"));
8534
8822
  hasDeepStorm = !!settings.deepstorm;
8535
8823
  } catch {
8536
8824
  }
@@ -8540,14 +8828,14 @@ async function uninstallDeepStorm(targetDir) {
8540
8828
  }
8541
8829
  cleanInstalled(targetDir);
8542
8830
  resetConfig(targetDir);
8543
- const templatesDir = path20.join(targetDir, ".deepstorm", "templates");
8544
- if (fs22.existsSync(templatesDir)) {
8831
+ const templatesDir = path21.join(targetDir, ".deepstorm", "templates");
8832
+ if (fs23.existsSync(templatesDir)) {
8545
8833
  const shouldDelete = await (0, import_prompts4.confirm)({
8546
8834
  message: "\u662F\u5426\u5220\u9664 .deepstorm/templates/ \u76EE\u5F55\uFF1F",
8547
8835
  initialValue: false
8548
8836
  });
8549
8837
  if (shouldDelete) {
8550
- fs22.rmSync(templatesDir, { recursive: true, force: true });
8838
+ fs23.rmSync(templatesDir, { recursive: true, force: true });
8551
8839
  console.log("\u2714 .deepstorm/templates/ \u5DF2\u5220\u9664");
8552
8840
  } else {
8553
8841
  console.log("\u4FDD\u7559 .deepstorm/templates/");
@@ -8560,9 +8848,9 @@ async function uninstallDeepStorm(targetDir) {
8560
8848
  var program = new import_commander.Command();
8561
8849
  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");
8562
8850
  function loadRegistry() {
8563
- const registryPath = path21.join(__dirname, "registry.json");
8851
+ const registryPath = path22.join(__dirname, "registry.json");
8564
8852
  try {
8565
- const raw = fs23.readFileSync(registryPath, "utf-8");
8853
+ const raw = fs24.readFileSync(registryPath, "utf-8");
8566
8854
  return JSON.parse(raw);
8567
8855
  } catch {
8568
8856
  return { version: "1", tools: {}, wizards: {}, skills: {} };
@@ -8573,7 +8861,7 @@ registerSetupCommand(program, registry);
8573
8861
  registerPluginBuildCommand(program, registry);
8574
8862
  registerConfigCommand(program, registry);
8575
8863
  registerTemplateCommand(program, registry);
8576
- registerUpdateCommand(program, registry);
8864
+ registerUpdateCommand(program);
8577
8865
  program.command("doctor").description("\u8BCA\u65AD\u9879\u76EE DeepStorm \u914D\u7F6E\u72B6\u6001").action(() => {
8578
8866
  const report = runDoctor(process.cwd());
8579
8867
  printDoctorReport(report);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deepstorm/cli",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "DeepStorm CLI — 一键配置项目开发环境",
5
5
  "license": "MIT",
6
6
  "author": "billkang",