@deepstorm/cli 0.2.1 → 0.2.3
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/build-registry.js +3 -3
- package/dist/cli.js +388 -148
- package/dist/registry.json +94 -1
- package/package.json +1 -1
package/dist/build-registry.js
CHANGED
|
@@ -125,11 +125,11 @@ function buildRegistry(cliDir) {
|
|
|
125
125
|
console.log(` \u26A0 ${pkg}/${skillName}: frontmatter \u89E3\u6790\u5931\u8D25\uFF0C\u8DF3\u8FC7`);
|
|
126
126
|
continue;
|
|
127
127
|
}
|
|
128
|
-
if (!fm.
|
|
129
|
-
console.log(` - ${pkg}/${skillName}: \u65E0
|
|
128
|
+
if (!fm.deepstorm) {
|
|
129
|
+
console.log(` - ${pkg}/${skillName}: \u65E0 deepstorm \u5B57\u6BB5\uFF0C\u8DF3\u8FC7\u6CE8\u518C`);
|
|
130
130
|
continue;
|
|
131
131
|
}
|
|
132
|
-
const df = fm.
|
|
132
|
+
const df = fm.deepstorm;
|
|
133
133
|
const entry = {
|
|
134
134
|
tool: df.tool,
|
|
135
135
|
configKey: df.configKey,
|
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(
|
|
1191
|
-
return /^\.|this\b/.test(
|
|
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(
|
|
1196
|
-
return
|
|
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(
|
|
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:
|
|
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),
|
|
2589
|
+
var params = this.setupFullMustacheParams(decorator, program2, void 0), path23 = decorator.path;
|
|
2590
2590
|
this.useDecorators = true;
|
|
2591
|
-
this.opcode("registerDecorator", params.length,
|
|
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
|
|
2656
|
-
this.opcode("getContext",
|
|
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
|
-
|
|
2660
|
-
this.accept(
|
|
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
|
|
2665
|
-
|
|
2666
|
-
this.accept(
|
|
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),
|
|
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
|
-
|
|
2677
|
-
|
|
2678
|
-
this.accept(
|
|
2679
|
-
this.opcode("invokeHelper", params.length,
|
|
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(
|
|
2683
|
-
this.addDepth(
|
|
2684
|
-
this.opcode("getContext",
|
|
2685
|
-
var 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,
|
|
2687
|
+
this.opcode("lookupBlockParam", blockParamId, path23.parts);
|
|
2688
2688
|
} else if (!name) {
|
|
2689
2689
|
this.opcode("pushContext");
|
|
2690
|
-
} else if (
|
|
2690
|
+
} else if (path23.data) {
|
|
2691
2691
|
this.options.data = true;
|
|
2692
|
-
this.opcode("lookupData",
|
|
2692
|
+
this.opcode("lookupData", path23.depth, path23.parts, path23.strict);
|
|
2693
2693
|
} else {
|
|
2694
|
-
this.opcode("lookupOnContext",
|
|
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
|
|
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
|
-
|
|
3050
|
+
path23 = url.path;
|
|
3051
3051
|
}
|
|
3052
|
-
var isAbsolute = exports2.isAbsolute(
|
|
3053
|
-
var parts =
|
|
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
|
-
|
|
3071
|
-
if (
|
|
3072
|
-
|
|
3070
|
+
path23 = parts.join("/");
|
|
3071
|
+
if (path23 === "") {
|
|
3072
|
+
path23 = isAbsolute ? "/" : ".";
|
|
3073
3073
|
}
|
|
3074
3074
|
if (url) {
|
|
3075
|
-
url.path =
|
|
3075
|
+
url.path = path23;
|
|
3076
3076
|
return urlGenerate(url);
|
|
3077
3077
|
}
|
|
3078
|
-
return
|
|
3078
|
+
return path23;
|
|
3079
3079
|
}
|
|
3080
3080
|
exports2.normalize = normalize;
|
|
3081
|
-
function
|
|
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 =
|
|
3113
|
+
exports2.join = join21;
|
|
3114
3114
|
exports2.isAbsolute = function(aPath) {
|
|
3115
3115
|
return aPath.charAt(0) === "/" || urlRegexp.test(aPath);
|
|
3116
3116
|
};
|
|
3117
|
-
function
|
|
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 =
|
|
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 =
|
|
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
|
|
5862
|
-
return (id.data ? "@" : "") + "PATH:" +
|
|
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
|
|
5902
|
-
var templateString =
|
|
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
|
|
5915
|
-
var
|
|
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"));
|
|
@@ -6609,7 +6609,7 @@ function buildMcpCapabilities(mcpCapabilities, installedMcpServers, mcpTools) {
|
|
|
6609
6609
|
return JSON.stringify(result);
|
|
6610
6610
|
}
|
|
6611
6611
|
function deriveVariableName(frontmatter) {
|
|
6612
|
-
const deepstorm = frontmatter.
|
|
6612
|
+
const deepstorm = frontmatter.deepstorm;
|
|
6613
6613
|
const tool = deepstorm?.tool;
|
|
6614
6614
|
if (tool && /^[a-z_]+$/.test(tool)) {
|
|
6615
6615
|
return `${tool}_capabilities`;
|
|
@@ -8116,6 +8116,11 @@ function registerTemplateCommand(program2, registry2) {
|
|
|
8116
8116
|
});
|
|
8117
8117
|
}
|
|
8118
8118
|
|
|
8119
|
+
// src/commands/update.ts
|
|
8120
|
+
var fs21 = __toESM(require("node:fs"));
|
|
8121
|
+
var path19 = __toESM(require("node:path"));
|
|
8122
|
+
var import_node_child_process = require("node:child_process");
|
|
8123
|
+
|
|
8119
8124
|
// src/utils/version.ts
|
|
8120
8125
|
var fs19 = __toESM(require("node:fs"));
|
|
8121
8126
|
var path17 = __toESM(require("node:path"));
|
|
@@ -8140,20 +8145,281 @@ function getCliVersion() {
|
|
|
8140
8145
|
// src/commands/template-upgrade.ts
|
|
8141
8146
|
var fs20 = __toESM(require("node:fs"));
|
|
8142
8147
|
var path18 = __toESM(require("node:path"));
|
|
8143
|
-
|
|
8144
|
-
|
|
8148
|
+
var crypto = __toESM(require("node:crypto"));
|
|
8149
|
+
var CHECKSUM_FILE = "deepstorm-checksums.json";
|
|
8150
|
+
function computeFileChecksum(filePath) {
|
|
8151
|
+
try {
|
|
8152
|
+
if (!fs20.existsSync(filePath)) return null;
|
|
8153
|
+
const content = fs20.readFileSync(filePath);
|
|
8154
|
+
return crypto.createHash("sha256").update(content).digest("hex");
|
|
8155
|
+
} catch {
|
|
8156
|
+
return null;
|
|
8157
|
+
}
|
|
8158
|
+
}
|
|
8159
|
+
function computeDirChecksums(dirPath, relativeTo = dirPath) {
|
|
8160
|
+
const result = {};
|
|
8161
|
+
if (!fs20.existsSync(dirPath)) return result;
|
|
8162
|
+
function walk(current) {
|
|
8163
|
+
for (const entry of fs20.readdirSync(current, { withFileTypes: true })) {
|
|
8164
|
+
const fullPath = path18.join(current, entry.name);
|
|
8165
|
+
if (entry.name === ".DS_Store") continue;
|
|
8166
|
+
if (entry.isDirectory()) {
|
|
8167
|
+
walk(fullPath);
|
|
8168
|
+
} else if (entry.isFile()) {
|
|
8169
|
+
const relPath = path18.relative(relativeTo, fullPath);
|
|
8170
|
+
const checksum = computeFileChecksum(fullPath);
|
|
8171
|
+
if (checksum) result[relPath] = checksum;
|
|
8172
|
+
}
|
|
8173
|
+
}
|
|
8174
|
+
}
|
|
8175
|
+
walk(dirPath);
|
|
8176
|
+
return result;
|
|
8177
|
+
}
|
|
8178
|
+
function loadChecksums(targetDir) {
|
|
8179
|
+
const filePath = path18.join(targetDir, ".claude", CHECKSUM_FILE);
|
|
8180
|
+
try {
|
|
8181
|
+
return JSON.parse(fs20.readFileSync(filePath, "utf-8"));
|
|
8182
|
+
} catch {
|
|
8183
|
+
return {};
|
|
8184
|
+
}
|
|
8185
|
+
}
|
|
8186
|
+
function saveChecksums(targetDir, checksums) {
|
|
8187
|
+
const dir = path18.join(targetDir, ".claude");
|
|
8188
|
+
ensureDir(dir);
|
|
8189
|
+
fs20.writeFileSync(
|
|
8190
|
+
path18.join(dir, CHECKSUM_FILE),
|
|
8191
|
+
JSON.stringify(checksums, null, 2) + "\n",
|
|
8192
|
+
"utf-8"
|
|
8193
|
+
);
|
|
8194
|
+
}
|
|
8195
|
+
function backupFile(filePath) {
|
|
8196
|
+
try {
|
|
8197
|
+
if (!fs20.existsSync(filePath)) return null;
|
|
8198
|
+
const dir = path18.dirname(filePath);
|
|
8199
|
+
const ext = path18.extname(filePath);
|
|
8200
|
+
const base = path18.basename(filePath, ext);
|
|
8201
|
+
const timestamp = Date.now();
|
|
8202
|
+
const bakName = `${base}.${timestamp}.bak`;
|
|
8203
|
+
const bakPath = path18.join(dir, bakName);
|
|
8204
|
+
fs20.cpSync(filePath, bakPath, { force: true });
|
|
8205
|
+
return bakName;
|
|
8206
|
+
} catch {
|
|
8207
|
+
return null;
|
|
8208
|
+
}
|
|
8209
|
+
}
|
|
8210
|
+
function checkAndBackup(fileKey, filePath, stored, backedUp) {
|
|
8211
|
+
const lastChecksum = stored[fileKey];
|
|
8212
|
+
if (!lastChecksum) return;
|
|
8213
|
+
const current = computeFileChecksum(filePath);
|
|
8214
|
+
if (current === null) return;
|
|
8215
|
+
if (current === lastChecksum) return;
|
|
8216
|
+
const bakName = backupFile(filePath);
|
|
8217
|
+
if (bakName) {
|
|
8218
|
+
backedUp.push(`${fileKey} \u2192 ${bakName}`);
|
|
8219
|
+
}
|
|
8220
|
+
}
|
|
8221
|
+
function backupModifiedAssets(targetDir, skillIds, toolNames, registry2) {
|
|
8222
|
+
const stored = loadChecksums(targetDir);
|
|
8223
|
+
const backedUp = [];
|
|
8145
8224
|
for (const skillId of skillIds) {
|
|
8146
|
-
const
|
|
8147
|
-
if (fs20.existsSync(
|
|
8148
|
-
|
|
8225
|
+
const skillDir = path18.join(targetDir, ".claude", "skills", skillId);
|
|
8226
|
+
if (!fs20.existsSync(skillDir)) continue;
|
|
8227
|
+
const checksums = computeDirChecksums(skillDir);
|
|
8228
|
+
for (const [relPath] of Object.entries(checksums)) {
|
|
8229
|
+
const key = `skills/${skillId}/${relPath}`;
|
|
8230
|
+
checkAndBackup(key, path18.join(skillDir, relPath), stored, backedUp);
|
|
8231
|
+
}
|
|
8232
|
+
}
|
|
8233
|
+
const reader = new RegistryReader(registry2);
|
|
8234
|
+
for (const tool of toolNames) {
|
|
8235
|
+
const agents = reader.getToolAgents(tool);
|
|
8236
|
+
for (const agentFile of agents) {
|
|
8237
|
+
const filePath = path18.join(targetDir, ".claude", "agents", agentFile.replace(/\.tmpl$/, ""));
|
|
8238
|
+
const key = `agents/${agentFile.replace(/\.tmpl$/, "")}`;
|
|
8239
|
+
checkAndBackup(key, filePath, stored, backedUp);
|
|
8240
|
+
}
|
|
8241
|
+
}
|
|
8242
|
+
for (const tool of toolNames) {
|
|
8243
|
+
const hooks = reader.getToolHooks(tool);
|
|
8244
|
+
for (const hookFile of hooks) {
|
|
8245
|
+
const filePath = path18.join(targetDir, ".claude", "hooks", hookFile);
|
|
8246
|
+
const key = `hooks/${hookFile}`;
|
|
8247
|
+
checkAndBackup(key, filePath, stored, backedUp);
|
|
8248
|
+
}
|
|
8249
|
+
}
|
|
8250
|
+
return backedUp;
|
|
8251
|
+
}
|
|
8252
|
+
function storeNewChecksums(targetDir, skillIds, toolNames, registry2) {
|
|
8253
|
+
const newChecksums = {};
|
|
8254
|
+
const reader = new RegistryReader(registry2);
|
|
8255
|
+
for (const skillId of skillIds) {
|
|
8256
|
+
const skillDir = path18.join(targetDir, ".claude", "skills", skillId);
|
|
8257
|
+
const checksums = computeDirChecksums(skillDir);
|
|
8258
|
+
for (const [relPath, checksum] of Object.entries(checksums)) {
|
|
8259
|
+
newChecksums[`skills/${skillId}/${relPath}`] = checksum;
|
|
8260
|
+
}
|
|
8261
|
+
}
|
|
8262
|
+
for (const tool of toolNames) {
|
|
8263
|
+
const agents = reader.getToolAgents(tool);
|
|
8264
|
+
for (const agentFile of agents) {
|
|
8265
|
+
const installedName = agentFile.replace(/\.tmpl$/, "");
|
|
8266
|
+
const filePath = path18.join(targetDir, ".claude", "agents", installedName);
|
|
8267
|
+
const chk = computeFileChecksum(filePath);
|
|
8268
|
+
if (chk) newChecksums[`agents/${installedName}`] = chk;
|
|
8269
|
+
}
|
|
8270
|
+
}
|
|
8271
|
+
for (const tool of toolNames) {
|
|
8272
|
+
const hooks = reader.getToolHooks(tool);
|
|
8273
|
+
for (const hookFile of hooks) {
|
|
8274
|
+
const filePath = path18.join(targetDir, ".claude", "hooks", hookFile);
|
|
8275
|
+
const chk = computeFileChecksum(filePath);
|
|
8276
|
+
if (chk) newChecksums[`hooks/${hookFile}`] = chk;
|
|
8277
|
+
}
|
|
8278
|
+
}
|
|
8279
|
+
saveChecksums(targetDir, newChecksums);
|
|
8280
|
+
}
|
|
8281
|
+
function skillIdsToTools(skillIds, registry2) {
|
|
8282
|
+
const toolSet = /* @__PURE__ */ new Set();
|
|
8283
|
+
for (const skillId of skillIds) {
|
|
8284
|
+
const skill = registry2.skills[skillId];
|
|
8285
|
+
if (skill?.tool) {
|
|
8286
|
+
toolSet.add(skill.tool);
|
|
8287
|
+
}
|
|
8288
|
+
}
|
|
8289
|
+
return [...toolSet];
|
|
8290
|
+
}
|
|
8291
|
+
function readSettingsConfig(targetDir) {
|
|
8292
|
+
const settingsPath = path18.join(targetDir, ".claude", "settings.json");
|
|
8293
|
+
try {
|
|
8294
|
+
const raw = fs20.readFileSync(settingsPath, "utf-8");
|
|
8295
|
+
const settings = JSON.parse(raw);
|
|
8296
|
+
const deepstorm = settings.deepstorm || {};
|
|
8297
|
+
const metaKeys = /* @__PURE__ */ new Set([
|
|
8298
|
+
"installedSkills",
|
|
8299
|
+
"installedMcpServers",
|
|
8300
|
+
"installedAt",
|
|
8301
|
+
"mcpCapabilities"
|
|
8302
|
+
]);
|
|
8303
|
+
const config = {};
|
|
8304
|
+
flattenNestedConfig(deepstorm, "", config, metaKeys);
|
|
8305
|
+
const installedMcpTools = deepstorm.installedMcpServers ?? [];
|
|
8306
|
+
return { config, installedMcpTools };
|
|
8307
|
+
} catch {
|
|
8308
|
+
return { config: {}, installedMcpTools: [] };
|
|
8309
|
+
}
|
|
8310
|
+
}
|
|
8311
|
+
function flattenNestedConfig(obj, prefix, result, skipKeys) {
|
|
8312
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
8313
|
+
if (skipKeys.has(key)) continue;
|
|
8314
|
+
const fullKey = prefix ? `${prefix}.${key}` : key;
|
|
8315
|
+
if (value !== null && typeof value === "object" && !Array.isArray(value)) {
|
|
8316
|
+
flattenNestedConfig(value, fullKey, result, skipKeys);
|
|
8317
|
+
} else if (typeof value === "string") {
|
|
8318
|
+
result[fullKey] = value;
|
|
8319
|
+
}
|
|
8320
|
+
}
|
|
8321
|
+
}
|
|
8322
|
+
function loadRegistryFromCliDir(cliDir2) {
|
|
8323
|
+
const registryPath = path18.join(cliDir2, "registry.json");
|
|
8324
|
+
try {
|
|
8325
|
+
const raw = fs20.readFileSync(registryPath, "utf-8");
|
|
8326
|
+
return JSON.parse(raw);
|
|
8327
|
+
} catch {
|
|
8328
|
+
return null;
|
|
8329
|
+
}
|
|
8330
|
+
}
|
|
8331
|
+
function mergeToolHooksJson(toolNames, cliDir2, targetDir) {
|
|
8332
|
+
const hooksSrcDir = path18.join(cliDir2, "hooks");
|
|
8333
|
+
const targetHooksDir = path18.join(targetDir, ".claude", "hooks");
|
|
8334
|
+
const destHooksJson = path18.join(targetHooksDir, "hooks.json");
|
|
8335
|
+
for (const tool of toolNames) {
|
|
8336
|
+
const toolHooksJsonPath = path18.join(hooksSrcDir, `${tool}-hooks.json`);
|
|
8337
|
+
if (fs20.existsSync(toolHooksJsonPath)) {
|
|
8338
|
+
ensureDir(targetHooksDir);
|
|
8339
|
+
const incoming = JSON.parse(fs20.readFileSync(toolHooksJsonPath, "utf-8"));
|
|
8340
|
+
mergeHooks(destHooksJson, incoming);
|
|
8341
|
+
}
|
|
8342
|
+
}
|
|
8343
|
+
}
|
|
8344
|
+
function syncToolAssets(cliDir2, targetDir, installedSkillIds) {
|
|
8345
|
+
const registry2 = loadRegistryFromCliDir(cliDir2);
|
|
8346
|
+
if (!registry2) {
|
|
8347
|
+
console.log("\u26A0 \u65E0\u6CD5\u52A0\u8F7D registry.json\uFF0C\u8DF3\u8FC7\u8D44\u4EA7\u540C\u6B65");
|
|
8348
|
+
return { syncedSkills: [], syncedAgents: [], syncedHooks: [], backedUpFiles: [] };
|
|
8349
|
+
}
|
|
8350
|
+
const reader = new RegistryReader(registry2);
|
|
8351
|
+
const toolNames = skillIdsToTools(installedSkillIds, registry2);
|
|
8352
|
+
if (toolNames.length === 0) {
|
|
8353
|
+
console.log("\u26A0 \u65E0\u6CD5\u4ECE\u5DF2\u5B89\u88C5 skill \u89E3\u6790\u5DE5\u5177\u540D\u79F0\uFF0C\u8DF3\u8FC7\u8D44\u4EA7\u540C\u6B65");
|
|
8354
|
+
return { syncedSkills: [], syncedAgents: [], syncedHooks: [], backedUpFiles: [] };
|
|
8355
|
+
}
|
|
8356
|
+
const { config, installedMcpTools } = readSettingsConfig(targetDir);
|
|
8357
|
+
const templateVariables = buildTemplateVariables(registry2, config, installedMcpTools);
|
|
8358
|
+
const backedUpFiles = backupModifiedAssets(targetDir, installedSkillIds, toolNames, registry2);
|
|
8359
|
+
if (backedUpFiles.length > 0) {
|
|
8360
|
+
console.log("\n\u26A0 \u68C0\u6D4B\u5230\u7528\u6237\u4FEE\u6539\u7684\u6587\u4EF6\uFF1A");
|
|
8361
|
+
for (const info of backedUpFiles) {
|
|
8362
|
+
console.log(` \u5DF2\u5907\u4EFD ${info}`);
|
|
8363
|
+
}
|
|
8364
|
+
console.log("");
|
|
8365
|
+
}
|
|
8366
|
+
const actualSkillIds = [];
|
|
8367
|
+
const syncedAgents = [];
|
|
8368
|
+
const syncedHooks = [];
|
|
8369
|
+
let hasWarning = false;
|
|
8370
|
+
for (const tool of toolNames) {
|
|
8371
|
+
try {
|
|
8372
|
+
reader.getToolEntry(tool);
|
|
8373
|
+
} catch {
|
|
8149
8374
|
continue;
|
|
8150
8375
|
}
|
|
8151
|
-
const
|
|
8152
|
-
const
|
|
8153
|
-
|
|
8154
|
-
|
|
8155
|
-
|
|
8156
|
-
|
|
8376
|
+
const beforeAgents = reader.getToolAgents(tool);
|
|
8377
|
+
const beforeHooks = reader.getToolHooks(tool);
|
|
8378
|
+
try {
|
|
8379
|
+
const ids = renderToolAssets(
|
|
8380
|
+
tool,
|
|
8381
|
+
reader,
|
|
8382
|
+
cliDir2,
|
|
8383
|
+
targetDir,
|
|
8384
|
+
templateVariables,
|
|
8385
|
+
config,
|
|
8386
|
+
registry2,
|
|
8387
|
+
installedMcpTools,
|
|
8388
|
+
".claude"
|
|
8389
|
+
);
|
|
8390
|
+
actualSkillIds.push(...ids);
|
|
8391
|
+
syncedAgents.push(...beforeAgents);
|
|
8392
|
+
syncedHooks.push(...beforeHooks);
|
|
8393
|
+
} catch (err) {
|
|
8394
|
+
hasWarning = true;
|
|
8395
|
+
console.log(` \u26A0 ${tool} \u540C\u6B65\u51FA\u9519: ${err instanceof Error ? err.message : String(err)}`);
|
|
8396
|
+
}
|
|
8397
|
+
}
|
|
8398
|
+
const syncedSkills = actualSkillIds.length > 0 ? actualSkillIds : [...installedSkillIds];
|
|
8399
|
+
mergeToolHooksJson(toolNames, cliDir2, targetDir);
|
|
8400
|
+
storeNewChecksums(targetDir, installedSkillIds, toolNames, registry2);
|
|
8401
|
+
if (hasWarning) {
|
|
8402
|
+
console.log("\n\u26A0 \u90E8\u5206\u5DE5\u5177\u540C\u6B65\u51FA\u9519\uFF0C\u8BF7\u68C0\u67E5\u540E\u91CD\u8BD5");
|
|
8403
|
+
}
|
|
8404
|
+
const uniqueAgents = [...new Set(syncedAgents)];
|
|
8405
|
+
const uniqueHooks = [...new Set(syncedHooks)];
|
|
8406
|
+
return {
|
|
8407
|
+
syncedSkills,
|
|
8408
|
+
syncedAgents: uniqueAgents,
|
|
8409
|
+
syncedHooks: uniqueHooks,
|
|
8410
|
+
backedUpFiles
|
|
8411
|
+
};
|
|
8412
|
+
}
|
|
8413
|
+
function upgradeTemplates(cliDir2, targetDir, skillIds) {
|
|
8414
|
+
const report = syncToolAssets(cliDir2, targetDir, skillIds);
|
|
8415
|
+
if (report.syncedSkills.length > 0) {
|
|
8416
|
+
const count = report.syncedSkills.length;
|
|
8417
|
+
const agentCount = report.syncedAgents.length;
|
|
8418
|
+
const hookCount = report.syncedHooks.length;
|
|
8419
|
+
console.log(`
|
|
8420
|
+
\u2714 \u540C\u6B65\u5B8C\u6210\uFF1A${count} \u4E2A skill${agentCount > 0 ? `\u3001${agentCount} \u4E2A agent` : ""}${hookCount > 0 ? `\u3001${hookCount} \u4E2A hook` : ""}`);
|
|
8421
|
+
if (report.backedUpFiles.length > 0) {
|
|
8422
|
+
console.log(` \u5DF2\u5907\u4EFD ${report.backedUpFiles.length} \u4E2A\u4FEE\u6539\u8FC7\u7684\u6587\u4EF6`);
|
|
8157
8423
|
}
|
|
8158
8424
|
}
|
|
8159
8425
|
}
|
|
@@ -8211,75 +8477,49 @@ async function updateCLI(fetchFn) {
|
|
|
8211
8477
|
console.log(`\u2714 \u5F53\u524D\u7248\u672C: v${result.current}`);
|
|
8212
8478
|
console.log(`\u2714 \u6700\u65B0\u7248\u672C: v${result.latest}`);
|
|
8213
8479
|
if (result.hasUpdate) {
|
|
8214
|
-
console.log("");
|
|
8215
|
-
|
|
8216
|
-
|
|
8480
|
+
console.log("\u2192 \u6B63\u5728\u81EA\u52A8\u66F4\u65B0...");
|
|
8481
|
+
try {
|
|
8482
|
+
(0, import_node_child_process.execSync)("npm install -g @deepstorm/cli@latest", { stdio: "inherit" });
|
|
8483
|
+
console.log(`
|
|
8484
|
+
\u2714 \u5DF2\u66F4\u65B0\u81F3 v${result.latest}`);
|
|
8485
|
+
} catch {
|
|
8486
|
+
console.log("\n\u26A0 \u81EA\u52A8\u66F4\u65B0\u5931\u8D25\uFF0C\u8BF7\u624B\u52A8\u6267\u884C\uFF1A");
|
|
8487
|
+
console.log(" npm install -g @deepstorm/cli@latest");
|
|
8488
|
+
}
|
|
8217
8489
|
} else {
|
|
8218
8490
|
console.log("\u2713 \u5DF2\u662F\u6700\u65B0\u7248\u672C");
|
|
8219
8491
|
}
|
|
8220
8492
|
}
|
|
8221
|
-
function
|
|
8222
|
-
|
|
8493
|
+
function getInstalledSkillIds(targetDir) {
|
|
8494
|
+
const settingsPath = path19.join(targetDir, ".claude", "settings.json");
|
|
8495
|
+
try {
|
|
8496
|
+
const raw = fs21.readFileSync(settingsPath, "utf-8");
|
|
8497
|
+
const settings = JSON.parse(raw);
|
|
8498
|
+
return settings.deepstorm?.installedSkills ?? [];
|
|
8499
|
+
} catch {
|
|
8500
|
+
return [];
|
|
8501
|
+
}
|
|
8223
8502
|
}
|
|
8224
|
-
function registerUpdateCommand(program2
|
|
8503
|
+
function registerUpdateCommand(program2) {
|
|
8225
8504
|
const cliDir2 = __dirname;
|
|
8226
|
-
|
|
8227
|
-
|
|
8228
|
-
|
|
8229
|
-
|
|
8230
|
-
|
|
8231
|
-
|
|
8232
|
-
|
|
8233
|
-
|
|
8234
|
-
upgradeTemplates(cliDir2, process.cwd(), Object.keys(registry2.skills));
|
|
8235
|
-
} else {
|
|
8236
|
-
console.log("");
|
|
8237
|
-
console.log("\u8DF3\u8FC7 skill \u540C\u6B65\uFF08\u7248\u672C\u68C0\u67E5\u5931\u8D25\u65F6\u4FDD\u7559\u73B0\u6709\u6A21\u677F\uFF09");
|
|
8238
|
-
}
|
|
8239
|
-
return;
|
|
8240
|
-
}
|
|
8241
|
-
if (check) {
|
|
8242
|
-
const result = await checkNpmVersion();
|
|
8243
|
-
printVersionInfo(result);
|
|
8244
|
-
if (result.error) process.exit(1);
|
|
8245
|
-
return;
|
|
8246
|
-
}
|
|
8247
|
-
if (cli) {
|
|
8248
|
-
await updateCLI();
|
|
8249
|
-
return;
|
|
8250
|
-
}
|
|
8251
|
-
if (skills) {
|
|
8252
|
-
const skillIds = Object.keys(registry2.skills);
|
|
8253
|
-
if (skillIds.length === 0) {
|
|
8254
|
-
console.log("registry \u4E2D\u65E0\u5DF2\u6CE8\u518C skill");
|
|
8255
|
-
return;
|
|
8256
|
-
}
|
|
8257
|
-
updateSkills(cliDir2, process.cwd(), skillIds);
|
|
8258
|
-
return;
|
|
8505
|
+
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 () => {
|
|
8506
|
+
await updateCLI();
|
|
8507
|
+
console.log("");
|
|
8508
|
+
const installedIds = getInstalledSkillIds(process.cwd());
|
|
8509
|
+
if (installedIds.length === 0) {
|
|
8510
|
+
console.log("\u672A\u68C0\u6D4B\u5230\u5DF2\u5B89\u88C5\u7684 skill\uFF0C\u8DF3\u8FC7\u540C\u6B65");
|
|
8511
|
+
} else {
|
|
8512
|
+
upgradeTemplates(cliDir2, process.cwd(), installedIds);
|
|
8259
8513
|
}
|
|
8260
8514
|
});
|
|
8261
8515
|
}
|
|
8262
|
-
function printVersionInfo(result) {
|
|
8263
|
-
if (result.error) {
|
|
8264
|
-
console.log(`\u26A0 \u65E0\u6CD5\u68C0\u67E5\u66F4\u65B0\uFF1A${result.error}`);
|
|
8265
|
-
return;
|
|
8266
|
-
}
|
|
8267
|
-
console.log(`\u2714 \u5F53\u524D\u7248\u672C: v${result.current}`);
|
|
8268
|
-
console.log(`\u2714 \u6700\u65B0\u7248\u672C: v${result.latest}`);
|
|
8269
|
-
if (result.hasUpdate) {
|
|
8270
|
-
console.log("");
|
|
8271
|
-
console.log('\u2192 \u6709\u65B0\u7248\u672C\u53EF\u7528\uFF01\u8FD0\u884C "deepstorm update --cli" \u66F4\u65B0');
|
|
8272
|
-
} else {
|
|
8273
|
-
console.log("\u2713 \u5DF2\u662F\u6700\u65B0\u7248\u672C");
|
|
8274
|
-
}
|
|
8275
|
-
}
|
|
8276
8516
|
|
|
8277
8517
|
// src/commands/doctor.ts
|
|
8278
|
-
var
|
|
8279
|
-
var
|
|
8518
|
+
var fs22 = __toESM(require("node:fs"));
|
|
8519
|
+
var path20 = __toESM(require("node:path"));
|
|
8280
8520
|
function getInstalledSkills(settingsPath) {
|
|
8281
8521
|
try {
|
|
8282
|
-
const settings = JSON.parse(
|
|
8522
|
+
const settings = JSON.parse(fs22.readFileSync(settingsPath, "utf-8"));
|
|
8283
8523
|
return settings.deepstorm?.installedSkills || [];
|
|
8284
8524
|
} catch {
|
|
8285
8525
|
return [];
|
|
@@ -8288,7 +8528,7 @@ function getInstalledSkills(settingsPath) {
|
|
|
8288
8528
|
function runDoctor(targetDir) {
|
|
8289
8529
|
const checks = [];
|
|
8290
8530
|
const version = getCliVersion();
|
|
8291
|
-
const settingsPath =
|
|
8531
|
+
const settingsPath = path20.join(targetDir, ".claude", "settings.json");
|
|
8292
8532
|
readDeepStormConfig(settingsPath);
|
|
8293
8533
|
checks.push({
|
|
8294
8534
|
name: "CLI \u7248\u672C",
|
|
@@ -8296,7 +8536,7 @@ function runDoctor(targetDir) {
|
|
|
8296
8536
|
message: `v${version}\uFF08\u8FD0\u884C deepstorm update --check \u68C0\u67E5\u6700\u65B0\u7248\u672C\uFF09`
|
|
8297
8537
|
});
|
|
8298
8538
|
let hasDeepStorm = false;
|
|
8299
|
-
if (!
|
|
8539
|
+
if (!fs22.existsSync(settingsPath)) {
|
|
8300
8540
|
checks.push({
|
|
8301
8541
|
name: "\u914D\u7F6E\u6587\u4EF6",
|
|
8302
8542
|
status: "warn",
|
|
@@ -8304,7 +8544,7 @@ function runDoctor(targetDir) {
|
|
|
8304
8544
|
});
|
|
8305
8545
|
} else {
|
|
8306
8546
|
try {
|
|
8307
|
-
const settings = JSON.parse(
|
|
8547
|
+
const settings = JSON.parse(fs22.readFileSync(settingsPath, "utf-8"));
|
|
8308
8548
|
if (settings.deepstorm) {
|
|
8309
8549
|
hasDeepStorm = true;
|
|
8310
8550
|
checks.push({
|
|
@@ -8327,20 +8567,20 @@ function runDoctor(targetDir) {
|
|
|
8327
8567
|
});
|
|
8328
8568
|
}
|
|
8329
8569
|
}
|
|
8330
|
-
const skillsDir =
|
|
8331
|
-
if (
|
|
8332
|
-
const skillDirs =
|
|
8333
|
-
(n) =>
|
|
8570
|
+
const skillsDir = path20.join(targetDir, ".claude", "skills");
|
|
8571
|
+
if (fs22.existsSync(skillsDir)) {
|
|
8572
|
+
const skillDirs = fs22.readdirSync(skillsDir).filter(
|
|
8573
|
+
(n) => fs22.statSync(path20.join(skillsDir, n)).isDirectory()
|
|
8334
8574
|
);
|
|
8335
8575
|
let validCount = 0;
|
|
8336
8576
|
let invalidCount = 0;
|
|
8337
8577
|
for (const skillName of skillDirs) {
|
|
8338
|
-
const skillMd =
|
|
8339
|
-
if (!
|
|
8578
|
+
const skillMd = path20.join(skillsDir, skillName, "SKILL.md");
|
|
8579
|
+
if (!fs22.existsSync(skillMd)) {
|
|
8340
8580
|
invalidCount++;
|
|
8341
8581
|
continue;
|
|
8342
8582
|
}
|
|
8343
|
-
const content =
|
|
8583
|
+
const content = fs22.readFileSync(skillMd, "utf-8");
|
|
8344
8584
|
const frontmatter = parseFrontmatter(content);
|
|
8345
8585
|
if (frontmatter && frontmatter.name) {
|
|
8346
8586
|
validCount++;
|
|
@@ -8370,7 +8610,7 @@ function runDoctor(targetDir) {
|
|
|
8370
8610
|
const installedSkills = getInstalledSkills(settingsPath);
|
|
8371
8611
|
const missingSkills = [];
|
|
8372
8612
|
for (const skillId of installedSkills) {
|
|
8373
|
-
if (!
|
|
8613
|
+
if (!fs22.existsSync(path20.join(skillsDir, skillId))) {
|
|
8374
8614
|
missingSkills.push(skillId);
|
|
8375
8615
|
}
|
|
8376
8616
|
}
|
|
@@ -8394,10 +8634,10 @@ function runDoctor(targetDir) {
|
|
|
8394
8634
|
message: ".claude/skills/ \u4E0D\u5B58\u5728"
|
|
8395
8635
|
});
|
|
8396
8636
|
}
|
|
8397
|
-
const mcpPath =
|
|
8398
|
-
if (
|
|
8637
|
+
const mcpPath = path20.join(targetDir, ".mcp.json");
|
|
8638
|
+
if (fs22.existsSync(mcpPath)) {
|
|
8399
8639
|
try {
|
|
8400
|
-
const mcp = JSON.parse(
|
|
8640
|
+
const mcp = JSON.parse(fs22.readFileSync(mcpPath, "utf-8"));
|
|
8401
8641
|
const hasServers = mcp.mcpServers && Object.keys(mcp.mcpServers).length > 0;
|
|
8402
8642
|
checks.push({
|
|
8403
8643
|
name: "MCP \u670D\u52A1\u5668",
|
|
@@ -8418,12 +8658,12 @@ function runDoctor(targetDir) {
|
|
|
8418
8658
|
message: ".mcp.json \u4E0D\u5B58\u5728"
|
|
8419
8659
|
});
|
|
8420
8660
|
}
|
|
8421
|
-
if (hasDeepStorm &&
|
|
8661
|
+
if (hasDeepStorm && fs22.existsSync(settingsPath)) {
|
|
8422
8662
|
try {
|
|
8423
|
-
const settings = JSON.parse(
|
|
8663
|
+
const settings = JSON.parse(fs22.readFileSync(settingsPath, "utf-8"));
|
|
8424
8664
|
const installedMcp = settings.deepstorm?.installedMcpServers;
|
|
8425
8665
|
if (installedMcp && installedMcp.length > 0) {
|
|
8426
|
-
const mcpExists =
|
|
8666
|
+
const mcpExists = fs22.existsSync(mcpPath);
|
|
8427
8667
|
if (!mcpExists) {
|
|
8428
8668
|
checks.push({
|
|
8429
8669
|
name: "MCP \u4E00\u81F4\u6027",
|
|
@@ -8432,7 +8672,7 @@ function runDoctor(targetDir) {
|
|
|
8432
8672
|
});
|
|
8433
8673
|
} else {
|
|
8434
8674
|
try {
|
|
8435
|
-
const mcpConfig = JSON.parse(
|
|
8675
|
+
const mcpConfig = JSON.parse(fs22.readFileSync(mcpPath, "utf-8"));
|
|
8436
8676
|
const servers = mcpConfig.mcpServers || {};
|
|
8437
8677
|
const missing = [];
|
|
8438
8678
|
for (const toolName of installedMcp) {
|
|
@@ -8460,9 +8700,9 @@ function runDoctor(targetDir) {
|
|
|
8460
8700
|
} catch {
|
|
8461
8701
|
}
|
|
8462
8702
|
}
|
|
8463
|
-
if (hasDeepStorm &&
|
|
8703
|
+
if (hasDeepStorm && fs22.existsSync(settingsPath)) {
|
|
8464
8704
|
try {
|
|
8465
|
-
const settings = JSON.parse(
|
|
8705
|
+
const settings = JSON.parse(fs22.readFileSync(settingsPath, "utf-8"));
|
|
8466
8706
|
const config = settings.deepstorm;
|
|
8467
8707
|
const validKeys = loadValidConfigKeys();
|
|
8468
8708
|
if (validKeys.size > 0 && config) {
|
|
@@ -8516,18 +8756,18 @@ function printDoctorReport(report) {
|
|
|
8516
8756
|
}
|
|
8517
8757
|
|
|
8518
8758
|
// src/commands/uninstall.ts
|
|
8519
|
-
var
|
|
8520
|
-
var
|
|
8759
|
+
var fs23 = __toESM(require("node:fs"));
|
|
8760
|
+
var path21 = __toESM(require("node:path"));
|
|
8521
8761
|
var import_prompts4 = require("@clack/prompts");
|
|
8522
8762
|
async function uninstallDeepStorm(targetDir) {
|
|
8523
|
-
const settingsPath =
|
|
8524
|
-
if (!
|
|
8763
|
+
const settingsPath = path21.join(targetDir, ".claude", "settings.json");
|
|
8764
|
+
if (!fs23.existsSync(settingsPath)) {
|
|
8525
8765
|
console.log("DeepStorm \u5C1A\u672A\u914D\u7F6E\uFF0C\u65E0\u9700\u5378\u8F7D");
|
|
8526
8766
|
return;
|
|
8527
8767
|
}
|
|
8528
8768
|
let hasDeepStorm = false;
|
|
8529
8769
|
try {
|
|
8530
|
-
const settings = JSON.parse(
|
|
8770
|
+
const settings = JSON.parse(fs23.readFileSync(settingsPath, "utf-8"));
|
|
8531
8771
|
hasDeepStorm = !!settings.deepstorm;
|
|
8532
8772
|
} catch {
|
|
8533
8773
|
}
|
|
@@ -8537,14 +8777,14 @@ async function uninstallDeepStorm(targetDir) {
|
|
|
8537
8777
|
}
|
|
8538
8778
|
cleanInstalled(targetDir);
|
|
8539
8779
|
resetConfig(targetDir);
|
|
8540
|
-
const templatesDir =
|
|
8541
|
-
if (
|
|
8780
|
+
const templatesDir = path21.join(targetDir, ".deepstorm", "templates");
|
|
8781
|
+
if (fs23.existsSync(templatesDir)) {
|
|
8542
8782
|
const shouldDelete = await (0, import_prompts4.confirm)({
|
|
8543
8783
|
message: "\u662F\u5426\u5220\u9664 .deepstorm/templates/ \u76EE\u5F55\uFF1F",
|
|
8544
8784
|
initialValue: false
|
|
8545
8785
|
});
|
|
8546
8786
|
if (shouldDelete) {
|
|
8547
|
-
|
|
8787
|
+
fs23.rmSync(templatesDir, { recursive: true, force: true });
|
|
8548
8788
|
console.log("\u2714 .deepstorm/templates/ \u5DF2\u5220\u9664");
|
|
8549
8789
|
} else {
|
|
8550
8790
|
console.log("\u4FDD\u7559 .deepstorm/templates/");
|
|
@@ -8555,11 +8795,11 @@ async function uninstallDeepStorm(targetDir) {
|
|
|
8555
8795
|
|
|
8556
8796
|
// src/index.ts
|
|
8557
8797
|
var program = new import_commander.Command();
|
|
8558
|
-
program.name("deepstorm").description("DeepStorm CLI \u2014 \u4E00\u952E\u914D\u7F6E\u9879\u76EE\u5F00\u53D1\u73AF\u5883").version(getCliVersion());
|
|
8798
|
+
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");
|
|
8559
8799
|
function loadRegistry() {
|
|
8560
|
-
const registryPath =
|
|
8800
|
+
const registryPath = path22.join(__dirname, "registry.json");
|
|
8561
8801
|
try {
|
|
8562
|
-
const raw =
|
|
8802
|
+
const raw = fs24.readFileSync(registryPath, "utf-8");
|
|
8563
8803
|
return JSON.parse(raw);
|
|
8564
8804
|
} catch {
|
|
8565
8805
|
return { version: "1", tools: {}, wizards: {}, skills: {} };
|
|
@@ -8570,7 +8810,7 @@ registerSetupCommand(program, registry);
|
|
|
8570
8810
|
registerPluginBuildCommand(program, registry);
|
|
8571
8811
|
registerConfigCommand(program, registry);
|
|
8572
8812
|
registerTemplateCommand(program, registry);
|
|
8573
|
-
registerUpdateCommand(program
|
|
8813
|
+
registerUpdateCommand(program);
|
|
8574
8814
|
program.command("doctor").description("\u8BCA\u65AD\u9879\u76EE DeepStorm \u914D\u7F6E\u72B6\u6001").action(() => {
|
|
8575
8815
|
const report = runDoctor(process.cwd());
|
|
8576
8816
|
printDoctorReport(report);
|
package/dist/registry.json
CHANGED
|
@@ -807,7 +807,100 @@
|
|
|
807
807
|
"questions": []
|
|
808
808
|
}
|
|
809
809
|
},
|
|
810
|
-
"skills": {
|
|
810
|
+
"skills": {
|
|
811
|
+
"tide-discuss": {
|
|
812
|
+
"tool": "tide",
|
|
813
|
+
"name": "tide-discuss",
|
|
814
|
+
"description": "BMAD 多角色需求讨论 → PRD 自动生成 → 知识库推送 → 任务拆分 → Issue 创建。当用户讨论产品需求、新功能、改进建议时自动激活,引导用户通过结构化的 BMAD 工作流(分析师→产品经理→架构师→UX设计师→产品负责人)收敛需求并输出 PRD 文档。",
|
|
815
|
+
"hasTemplate": true
|
|
816
|
+
},
|
|
817
|
+
"reef-commit": {
|
|
818
|
+
"tool": "reef",
|
|
819
|
+
"name": "reef-commit",
|
|
820
|
+
"description": "根据当前变更和 OpenSpec 上下文,生成规范的提交信息并创建新提交。用户说「提交代码」「commit」「git push」「提交」「推送」等触发"
|
|
821
|
+
},
|
|
822
|
+
"reef-gen-backend": {
|
|
823
|
+
"tool": "reef",
|
|
824
|
+
"configKey": "reef.backend.language",
|
|
825
|
+
"name": "reef-gen-backend",
|
|
826
|
+
"description": "后端代码编写流程({{reef.backend.language.label}})。编写或生成后端代码时自动加载,编码规范详情引用 reef:reef-style-backend。",
|
|
827
|
+
"hasTemplate": true
|
|
828
|
+
},
|
|
829
|
+
"reef-gen-frontend": {
|
|
830
|
+
"tool": "reef",
|
|
831
|
+
"configKey": "reef.frontend.framework",
|
|
832
|
+
"name": "reef-gen-frontend",
|
|
833
|
+
"description": "前端代码编写流程({{reef.frontend.framework.label}})。编写或生成前端代码时自动加载,编码规范详情引用 reef:reef-style-frontend。",
|
|
834
|
+
"hasTemplate": true
|
|
835
|
+
},
|
|
836
|
+
"reef-harden": {
|
|
837
|
+
"tool": "reef",
|
|
838
|
+
"name": "reef-harden",
|
|
839
|
+
"description": "对 AI 生成的 spec、proposal、design、tasks 等 SDD 文档进行系统性加固。使用四道筛 + 反向 grill + Known Limitations 沉淀。当 AI 刚写完或用户想审查 spec/proposal/design/tasks 文档时触发,尤其当用户说\"加固spec\"、\"按四道筛过\"、\"补不做什么\"、\"补known limitation\" 或需要改进 SDD 文档质量时。"
|
|
840
|
+
},
|
|
841
|
+
"reef-pr": {
|
|
842
|
+
"tool": "reef",
|
|
843
|
+
"name": "reef-pr",
|
|
844
|
+
"description": "将当前分支的变更创建为 GitHub PR。读取 commits 和 OpenSpec 上下文,生成 PR 描述并提交。用户说「创建 PR」「发起 PR」「pull request」「提 PR」「提交 PR」时触发。"
|
|
845
|
+
},
|
|
846
|
+
"reef-review": {
|
|
847
|
+
"tool": "reef",
|
|
848
|
+
"name": "reef-review",
|
|
849
|
+
"description": "对当前分支变更执行前后端代码审查。自动检测变更范围,派发 Sub‑Agent 执行审查并生成结构化报告。",
|
|
850
|
+
"hasTemplate": true
|
|
851
|
+
},
|
|
852
|
+
"reef-scope": {
|
|
853
|
+
"tool": "reef",
|
|
854
|
+
"name": "reef-scope",
|
|
855
|
+
"description": "分支范围检查与拆分 — 在提交代码时验证分支是否涉及多个业务领域,以及自动拆分"
|
|
856
|
+
},
|
|
857
|
+
"reef-start": {
|
|
858
|
+
"tool": "reef",
|
|
859
|
+
"name": "reef-start",
|
|
860
|
+
"description": "从 Issue 跟踪系统或从零需求讨论启动开发生命周期。用户提供 Issue 编号时获取 Issue 详情和相关上下文(PRD 设计稿);无 Issue 时直接走 OpenSpec 自由讨论流程。通过 SDD 工作流生成高质量 spec 文档并进入 TDD 实现阶段。",
|
|
861
|
+
"hasTemplate": true
|
|
862
|
+
},
|
|
863
|
+
"reef-style-backend": {
|
|
864
|
+
"tool": "reef",
|
|
865
|
+
"configKey": "reef.backend.language",
|
|
866
|
+
"name": "reef-style-backend",
|
|
867
|
+
"description": "后端编码规范({{reef.backend.language.label}})。包含实体层次、DTO、Service/Controller/Repository 模式、MapStruct、多租户安全等完整规范。创建/修改后端代码时必须按本技能输出。",
|
|
868
|
+
"hasTemplate": true
|
|
869
|
+
},
|
|
870
|
+
"reef-style-frontend": {
|
|
871
|
+
"tool": "reef",
|
|
872
|
+
"configKey": "reef.frontend.framework",
|
|
873
|
+
"name": "reef-style-frontend",
|
|
874
|
+
"description": "前端编码规范({{reef.frontend.framework.label}})。创建/修改前端代码时必须按本技能输出。",
|
|
875
|
+
"hasTemplate": true
|
|
876
|
+
},
|
|
877
|
+
"reef-testcase": {
|
|
878
|
+
"tool": "reef",
|
|
879
|
+
"name": "reef-testcase",
|
|
880
|
+
"description": "基于 Jira Issue 生成结构化测试用例清单。从 Jira 功能描述和 PRD 上下文中提取测试场景,覆盖正常流程、边界条件、异常场景、验收标准四维。输出格式兼容 superpowers,可辅助生成更完备的单元测试。"
|
|
881
|
+
},
|
|
882
|
+
"sweep-init": {
|
|
883
|
+
"tool": "sweep",
|
|
884
|
+
"name": "sweep-init",
|
|
885
|
+
"description": "初始化 E2E 测试项目骨架。创建目录结构、根据 setup 配置生成对应测试框架配置、读取 MCP 配置、设置多环境变量,标志项目可被 flow-create 和 flow-run 使用。"
|
|
886
|
+
},
|
|
887
|
+
"sweep-plan": {
|
|
888
|
+
"tool": "sweep",
|
|
889
|
+
"name": "sweep-plan",
|
|
890
|
+
"description": "交互式生成 .flow.md 测试意图文档。从 Issue 或 PRD 提取验收标准,通过结构化对话覆盖功能流程、边界条件、异常场景,输出 Markdown 格式的测试流程。",
|
|
891
|
+
"hasTemplate": true
|
|
892
|
+
},
|
|
893
|
+
"sweep-run": {
|
|
894
|
+
"tool": "sweep",
|
|
895
|
+
"name": "sweep-run",
|
|
896
|
+
"description": "执行 .flow.md 测试意图文档。根据项目配置的 E2E 框架(如 Playwright),默认使用混合执行模式(Hybrid Execution):先通过预编译的 .flow.spec.ts 原生 Playwright 执行获得 ~20x 加速,失败后由 AI 驱动诊断和自动修复。支持交互式模块选择、直接参数指定、多环境切换、批量执行、多 Agent 并行。"
|
|
897
|
+
},
|
|
898
|
+
"atoll-ops": {
|
|
899
|
+
"tool": "atoll",
|
|
900
|
+
"name": "atoll-ops",
|
|
901
|
+
"description": "运维辅助 — 部署策略、监控查询、故障排查"
|
|
902
|
+
}
|
|
903
|
+
},
|
|
811
904
|
"mcpTools": {
|
|
812
905
|
"github": {
|
|
813
906
|
"domain": "code-hosting",
|