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