@markus-global/cli 0.5.1 → 0.5.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/markus.mjs +137 -17
- package/dist/web-ui/assets/index-fbfYqEhh.js +351 -0
- package/dist/web-ui/index.html +1 -1
- package/package.json +1 -1
- package/templates/skills/agent-building/skill.json +6 -0
- package/templates/skills/chrome-devtools/skill.json +6 -0
- package/templates/skills/markitdown/skill.json +6 -0
- package/templates/skills/markus-admin-cli/skill.json +6 -0
- package/templates/skills/markus-agent-cli/skill.json +7 -0
- package/templates/skills/markus-cli/skill.json +6 -0
- package/templates/skills/markus-hub-connector/skill.json +6 -0
- package/templates/skills/markus-project-cli/skill.json +7 -0
- package/templates/skills/markus-skill-cli/skill.json +7 -0
- package/templates/skills/markus-team-cli/skill.json +7 -0
- package/templates/skills/self-evolution/skill.json +6 -0
- package/templates/skills/skill-building/skill.json +6 -0
- package/templates/skills/team-building/skill.json +6 -0
- package/templates/teams/content-team/team.json +12 -0
- package/templates/teams/dev-squad/team.json +13 -0
- package/templates/teams/engineering-pod/team.json +13 -0
- package/templates/teams/research-lab/team.json +12 -0
- package/templates/teams/startup-team/team.json +11 -0
- package/dist/web-ui/assets/index-CAyBdTj8.js +0 -351
package/dist/markus.mjs
CHANGED
|
@@ -58883,7 +58883,8 @@ function createDefaultTemplateRegistry() {
|
|
|
58883
58883
|
skills: [],
|
|
58884
58884
|
tags: ["development", "coding", "fullstack", "backend", "frontend"],
|
|
58885
58885
|
category: "development",
|
|
58886
|
-
icon: "code"
|
|
58886
|
+
icon: "code",
|
|
58887
|
+
i18n: { "zh-CN": { name: "\u5168\u6808\u5F00\u53D1\u8005", description: "\u5168\u6808\u5F00\u53D1\u667A\u80FD\u4F53\uFF0C\u64C5\u957F\u4EE3\u7801\u7F16\u5199\u3001\u5BA1\u67E5\u548C\u8C03\u8BD5\uFF0C\u7CBE\u901A\u591A\u79CD\u7F16\u7A0B\u8BED\u8A00\u548C\u6846\u67B6\u3002" } }
|
|
58887
58888
|
},
|
|
58888
58889
|
{
|
|
58889
58890
|
id: "tpl-reviewer",
|
|
@@ -58897,7 +58898,8 @@ function createDefaultTemplateRegistry() {
|
|
|
58897
58898
|
skills: [],
|
|
58898
58899
|
tags: ["review", "quality", "best-practices"],
|
|
58899
58900
|
category: "development",
|
|
58900
|
-
icon: "search"
|
|
58901
|
+
icon: "search",
|
|
58902
|
+
i18n: { "zh-CN": { name: "\u4EE3\u7801\u5BA1\u67E5\u5458", description: "\u4E13\u6CE8\u4E8E\u4EE3\u7801\u5BA1\u67E5\u3001\u8D28\u91CF\u4FDD\u8BC1\u548C\u6700\u4F73\u5B9E\u8DF5\u6267\u884C\uFF0C\u5BA1\u67E5 PR \u5E76\u63D0\u51FA\u6539\u8FDB\u5EFA\u8BAE\u3002" } }
|
|
58901
58903
|
},
|
|
58902
58904
|
{
|
|
58903
58905
|
id: "tpl-project-manager",
|
|
@@ -58912,7 +58914,8 @@ function createDefaultTemplateRegistry() {
|
|
|
58912
58914
|
tags: ["management", "planning", "coordination", "tracking"],
|
|
58913
58915
|
category: "management",
|
|
58914
58916
|
heartbeatIntervalMs: 15 * 60 * 1e3,
|
|
58915
|
-
icon: "clipboard"
|
|
58917
|
+
icon: "clipboard",
|
|
58918
|
+
i18n: { "zh-CN": { name: "\u9879\u76EE\u7ECF\u7406", description: "\u7BA1\u7406\u4EFB\u52A1\u3001\u534F\u8C03\u56E2\u961F\u6210\u5458\u3001\u8DDF\u8E2A\u8FDB\u5EA6\uFF0C\u786E\u4FDD\u9879\u76EE\u91CC\u7A0B\u7891\u6309\u65F6\u5B8C\u6210\u3002" } }
|
|
58916
58919
|
},
|
|
58917
58920
|
{
|
|
58918
58921
|
id: "tpl-qa-engineer",
|
|
@@ -58926,7 +58929,8 @@ function createDefaultTemplateRegistry() {
|
|
|
58926
58929
|
skills: [],
|
|
58927
58930
|
tags: ["testing", "qa", "automation", "quality"],
|
|
58928
58931
|
category: "development",
|
|
58929
|
-
icon: "check-circle"
|
|
58932
|
+
icon: "check-circle",
|
|
58933
|
+
i18n: { "zh-CN": { name: "\u8D28\u91CF\u5DE5\u7A0B\u5E08", description: "\u81EA\u52A8\u5316\u6D4B\u8BD5\u4E13\u5BB6\uFF0C\u7F16\u5199\u6D4B\u8BD5\u7528\u4F8B\u3001\u6267\u884C\u96C6\u6210\u6D4B\u8BD5\uFF0C\u786E\u4FDD\u8F6F\u4EF6\u8D28\u91CF\u3002" } }
|
|
58930
58934
|
},
|
|
58931
58935
|
{
|
|
58932
58936
|
id: "tpl-devops",
|
|
@@ -58940,7 +58944,8 @@ function createDefaultTemplateRegistry() {
|
|
|
58940
58944
|
skills: [],
|
|
58941
58945
|
tags: ["devops", "ci-cd", "infrastructure", "deployment", "monitoring"],
|
|
58942
58946
|
category: "devops",
|
|
58943
|
-
icon: "server"
|
|
58947
|
+
icon: "server",
|
|
58948
|
+
i18n: { "zh-CN": { name: "DevOps \u5DE5\u7A0B\u5E08", description: "\u57FA\u7840\u8BBE\u65BD\u3001CI/CD\u3001\u90E8\u7F72\u548C\u76D1\u63A7\u4E13\u5BB6\uFF0C\u7BA1\u7406\u6784\u5EFA\u6D41\u6C34\u7EBF\u548C\u8FD0\u884C\u73AF\u5883\u3002" } }
|
|
58944
58949
|
},
|
|
58945
58950
|
{
|
|
58946
58951
|
id: "tpl-tech-writer",
|
|
@@ -58954,7 +58959,8 @@ function createDefaultTemplateRegistry() {
|
|
|
58954
58959
|
skills: [],
|
|
58955
58960
|
tags: ["documentation", "writing", "api-docs"],
|
|
58956
58961
|
category: "productivity",
|
|
58957
|
-
icon: "file-text"
|
|
58962
|
+
icon: "file-text",
|
|
58963
|
+
i18n: { "zh-CN": { name: "\u6280\u672F\u6587\u6863\u5DE5\u7A0B\u5E08", description: "\u6587\u6863\u4E13\u5BB6\uFF0C\u521B\u5EFA\u548C\u7EF4\u62A4\u6280\u672F\u6587\u6863\u3001API \u53C2\u8003\u548C\u7528\u6237\u6307\u5357\u3002" } }
|
|
58958
58964
|
},
|
|
58959
58965
|
{
|
|
58960
58966
|
id: "tpl-research-assistant",
|
|
@@ -58968,7 +58974,8 @@ function createDefaultTemplateRegistry() {
|
|
|
58968
58974
|
skills: [],
|
|
58969
58975
|
tags: ["research", "analysis", "information-gathering"],
|
|
58970
58976
|
category: "general",
|
|
58971
|
-
icon: "book-open"
|
|
58977
|
+
icon: "book-open",
|
|
58978
|
+
i18n: { "zh-CN": { name: "\u7814\u7A76\u52A9\u7406", description: "\u6536\u96C6\u4FE1\u606F\u3001\u5206\u6790\u6570\u636E\u3001\u603B\u7ED3\u53D1\u73B0\uFF0C\u4EE5\u5FAA\u8BC1\u7814\u7A76\u652F\u6301\u51B3\u7B56\u5236\u5B9A\u3002" } }
|
|
58972
58979
|
},
|
|
58973
58980
|
{
|
|
58974
58981
|
id: "tpl-hr-specialist",
|
|
@@ -58982,7 +58989,8 @@ function createDefaultTemplateRegistry() {
|
|
|
58982
58989
|
skills: [],
|
|
58983
58990
|
tags: ["hr", "recruitment", "onboarding", "people", "culture"],
|
|
58984
58991
|
category: "management",
|
|
58985
|
-
icon: "users"
|
|
58992
|
+
icon: "users",
|
|
58993
|
+
i18n: { "zh-CN": { name: "\u4EBA\u529B\u8D44\u6E90\u4E13\u5458", description: "\u4EBA\u529B\u8D44\u6E90\u4E13\u5BB6\uFF0C\u8D1F\u8D23\u62DB\u8058\u3001\u5165\u804C\u3001\u5236\u5EA6\u7BA1\u7406\u3001\u5458\u5DE5\u5173\u7CFB\u548C\u7EC4\u7EC7\u53D1\u5C55\u3002" } }
|
|
58986
58994
|
},
|
|
58987
58995
|
{
|
|
58988
58996
|
id: "tpl-finance-analyst",
|
|
@@ -58996,7 +59004,8 @@ function createDefaultTemplateRegistry() {
|
|
|
58996
59004
|
skills: [],
|
|
58997
59005
|
tags: ["finance", "budget", "accounting", "forecasting", "reporting"],
|
|
58998
59006
|
category: "management",
|
|
58999
|
-
icon: "dollar-sign"
|
|
59007
|
+
icon: "dollar-sign",
|
|
59008
|
+
i18n: { "zh-CN": { name: "\u8D22\u52A1\u5206\u6790\u5E08", description: "\u8D22\u52A1\u5206\u6790\u3001\u9884\u7B97\u7F16\u5236\u3001\u8D22\u52A1\u9884\u6D4B\u3001\u8D39\u7528\u8FFD\u8E2A\u548C\u8D22\u52A1\u62A5\u544A\u4E13\u5BB6\u3002" } }
|
|
59000
59009
|
},
|
|
59001
59010
|
{
|
|
59002
59011
|
id: "tpl-marketing-specialist",
|
|
@@ -59010,7 +59019,8 @@ function createDefaultTemplateRegistry() {
|
|
|
59010
59019
|
skills: [],
|
|
59011
59020
|
tags: ["marketing", "content", "seo", "social-media", "campaigns"],
|
|
59012
59021
|
category: "productivity",
|
|
59013
|
-
icon: "megaphone"
|
|
59022
|
+
icon: "megaphone",
|
|
59023
|
+
i18n: { "zh-CN": { name: "\u5E02\u573A\u8425\u9500\u4E13\u5458", description: "\u5E02\u573A\u8425\u9500\u7B56\u7565\u3001\u5185\u5BB9\u521B\u4F5C\u3001\u6D3B\u52A8\u7BA1\u7406\u3001SEO/SEM\u3001\u793E\u4EA4\u5A92\u4F53\u548C\u5E02\u573A\u5206\u6790\u3002" } }
|
|
59014
59024
|
},
|
|
59015
59025
|
{
|
|
59016
59026
|
id: "tpl-content-writer",
|
|
@@ -59024,7 +59034,8 @@ function createDefaultTemplateRegistry() {
|
|
|
59024
59034
|
skills: [],
|
|
59025
59035
|
tags: ["writing", "content", "blog", "copywriting", "seo"],
|
|
59026
59036
|
category: "productivity",
|
|
59027
|
-
icon: "edit"
|
|
59037
|
+
icon: "edit",
|
|
59038
|
+
i18n: { "zh-CN": { name: "\u5185\u5BB9\u521B\u4F5C\u8005", description: "\u521B\u4F5C\u535A\u5BA2\u6587\u7AE0\u3001\u793E\u4EA4\u5A92\u4F53\u5185\u5BB9\u3001\u65B0\u95FB\u901A\u8BAF\u548C\u8425\u9500\u6587\u6848\uFF0C\u5177\u5907 SEO \u610F\u8BC6\u3002" } }
|
|
59028
59039
|
},
|
|
59029
59040
|
{
|
|
59030
59041
|
id: "tpl-customer-support",
|
|
@@ -59038,7 +59049,8 @@ function createDefaultTemplateRegistry() {
|
|
|
59038
59049
|
skills: [],
|
|
59039
59050
|
tags: ["support", "customer-service", "helpdesk", "tickets"],
|
|
59040
59051
|
category: "general",
|
|
59041
|
-
icon: "headphones"
|
|
59052
|
+
icon: "headphones",
|
|
59053
|
+
i18n: { "zh-CN": { name: "\u5BA2\u6237\u652F\u6301", description: "\u5904\u7406\u5BA2\u6237\u54A8\u8BE2\u3001\u6545\u969C\u6392\u9664\u3001\u5DE5\u5355\u7BA1\u7406\u548C\u4EA4\u4ED8\u7269\u7BA1\u7406\u3002" } }
|
|
59042
59054
|
},
|
|
59043
59055
|
{
|
|
59044
59056
|
id: "tpl-operations-manager",
|
|
@@ -59053,7 +59065,8 @@ function createDefaultTemplateRegistry() {
|
|
|
59053
59065
|
tags: ["operations", "process", "efficiency", "coordination"],
|
|
59054
59066
|
category: "management",
|
|
59055
59067
|
heartbeatIntervalMs: 15 * 60 * 1e3,
|
|
59056
|
-
icon: "settings"
|
|
59068
|
+
icon: "settings",
|
|
59069
|
+
i18n: { "zh-CN": { name: "\u8FD0\u8425\u7ECF\u7406", description: "\u76D1\u7763\u65E5\u5E38\u8FD0\u8425\u3001\u6D41\u7A0B\u4F18\u5316\u3001\u8D44\u6E90\u8C03\u914D\u548C\u8DE8\u90E8\u95E8\u534F\u8C03\u3002" } }
|
|
59057
59070
|
},
|
|
59058
59071
|
{
|
|
59059
59072
|
id: "tpl-product-manager",
|
|
@@ -59068,7 +59081,8 @@ function createDefaultTemplateRegistry() {
|
|
|
59068
59081
|
tags: ["product", "strategy", "roadmap", "user-research"],
|
|
59069
59082
|
category: "management",
|
|
59070
59083
|
heartbeatIntervalMs: 15 * 60 * 1e3,
|
|
59071
|
-
icon: "target"
|
|
59084
|
+
icon: "target",
|
|
59085
|
+
i18n: { "zh-CN": { name: "\u4EA7\u54C1\u7ECF\u7406", description: "\u4EA7\u54C1\u7B56\u7565\u3001\u8DEF\u7EBF\u56FE\u89C4\u5212\u3001\u7528\u6237\u7814\u7A76\u3001\u529F\u80FD\u4F18\u5148\u7EA7\u6392\u5E8F\u548C\u5229\u76CA\u76F8\u5173\u8005\u6C9F\u901A\u3002" } }
|
|
59072
59086
|
}
|
|
59073
59087
|
];
|
|
59074
59088
|
for (const tpl of builtins) {
|
|
@@ -59696,7 +59710,8 @@ function loadTeamTemplateFromDir(dirPath) {
|
|
|
59696
59710
|
category: manifest.category,
|
|
59697
59711
|
icon: manifest.icon,
|
|
59698
59712
|
announcements: existsSync21(annPath) ? readFileSync16(annPath, "utf-8") : void 0,
|
|
59699
|
-
norms: existsSync21(normsPath) ? readFileSync16(normsPath, "utf-8") : void 0
|
|
59713
|
+
norms: existsSync21(normsPath) ? readFileSync16(normsPath, "utf-8") : void 0,
|
|
59714
|
+
i18n: manifest.i18n
|
|
59700
59715
|
};
|
|
59701
59716
|
} catch (err) {
|
|
59702
59717
|
log46.warn(`Failed to load team template from ${dirPath}`, { error: String(err) });
|
|
@@ -69953,8 +69968,28 @@ EXPLANATION_END`;
|
|
|
69953
69968
|
const builtinDir = resolve13(process.cwd(), "templates", "skills");
|
|
69954
69969
|
const found = discoverSkillsInDir(builtinDir);
|
|
69955
69970
|
const installedSkills = new Map((this.skillRegistry?.list() ?? []).map((s) => [s.name, s]));
|
|
69956
|
-
const
|
|
69971
|
+
const rawManifests = /* @__PURE__ */ new Map();
|
|
69972
|
+
try {
|
|
69973
|
+
const { readdirSync: readdirSync13, readFileSync: readFileSync26, existsSync: existsSync36 } = await import("node:fs");
|
|
69974
|
+
for (const entry of readdirSync13(builtinDir, { withFileTypes: true })) {
|
|
69975
|
+
if (!entry.isDirectory())
|
|
69976
|
+
continue;
|
|
69977
|
+
const sjPath = resolve13(builtinDir, entry.name, "skill.json");
|
|
69978
|
+
if (existsSync36(sjPath)) {
|
|
69979
|
+
try {
|
|
69980
|
+
rawManifests.set(entry.name, JSON.parse(readFileSync26(sjPath, "utf-8")));
|
|
69981
|
+
} catch {
|
|
69982
|
+
}
|
|
69983
|
+
}
|
|
69984
|
+
}
|
|
69985
|
+
} catch {
|
|
69986
|
+
}
|
|
69987
|
+
const skills = found.filter(({ manifest }) => {
|
|
69988
|
+
const raw = rawManifests.get(manifest.name);
|
|
69989
|
+
return !raw?.hidden;
|
|
69990
|
+
}).map(({ manifest, path: p }) => {
|
|
69957
69991
|
const inst = installedSkills.get(manifest.name);
|
|
69992
|
+
const raw = rawManifests.get(manifest.name);
|
|
69958
69993
|
return {
|
|
69959
69994
|
name: manifest.name,
|
|
69960
69995
|
version: manifest.version,
|
|
@@ -69964,10 +69999,12 @@ EXPLANATION_END`;
|
|
|
69964
69999
|
tags: manifest.tags ?? [],
|
|
69965
70000
|
hasMcpServers: !!manifest.mcpServers && Object.keys(manifest.mcpServers).length > 0,
|
|
69966
70001
|
hasInstructions: !!manifest.instructions,
|
|
70002
|
+
instructions: manifest.instructions ?? void 0,
|
|
69967
70003
|
requiredPermissions: manifest.requiredPermissions ?? [],
|
|
69968
70004
|
sourcePath: p,
|
|
69969
70005
|
installed: !!inst,
|
|
69970
|
-
installedVersion: inst?.version ?? null
|
|
70006
|
+
installedVersion: inst?.version ?? null,
|
|
70007
|
+
i18n: raw?.i18n ?? void 0
|
|
69971
70008
|
};
|
|
69972
70009
|
});
|
|
69973
70010
|
this.json(res, 200, { skills });
|
|
@@ -70799,6 +70836,47 @@ EXPLANATION_END`;
|
|
|
70799
70836
|
this.json(res, 200, { template });
|
|
70800
70837
|
return;
|
|
70801
70838
|
}
|
|
70839
|
+
if (path.match(/^\/api\/templates\/[^/]+\/files$/) && req.method === "GET") {
|
|
70840
|
+
if (!this.templateRegistry) {
|
|
70841
|
+
this.json(res, 404, { error: "Template registry not configured" });
|
|
70842
|
+
return;
|
|
70843
|
+
}
|
|
70844
|
+
const templateId = path.split("/")[3];
|
|
70845
|
+
const template = this.templateRegistry.get(templateId);
|
|
70846
|
+
if (!template) {
|
|
70847
|
+
this.json(res, 404, { error: `Template not found: ${templateId}` });
|
|
70848
|
+
return;
|
|
70849
|
+
}
|
|
70850
|
+
const { existsSync: ex, readFileSync: rf, readdirSync: rd } = await import("node:fs");
|
|
70851
|
+
const roleId = template.roleId;
|
|
70852
|
+
const candidates = [
|
|
70853
|
+
resolve13(process.cwd(), "templates", "roles", roleId)
|
|
70854
|
+
];
|
|
70855
|
+
try {
|
|
70856
|
+
const thisFile = (await import("node:url")).fileURLToPath(import.meta.url);
|
|
70857
|
+
const thisDir = (await import("node:path")).dirname(thisFile);
|
|
70858
|
+
candidates.unshift(resolve13(thisDir, "..", "templates", "roles", roleId));
|
|
70859
|
+
candidates.push(resolve13(thisDir, "..", "..", "..", "..", "templates", "roles", roleId));
|
|
70860
|
+
} catch {
|
|
70861
|
+
}
|
|
70862
|
+
const roleDir = candidates.find((d) => ex(d));
|
|
70863
|
+
const files = {};
|
|
70864
|
+
if (roleDir) {
|
|
70865
|
+
try {
|
|
70866
|
+
for (const entry of rd(roleDir, { withFileTypes: true })) {
|
|
70867
|
+
if (entry.isFile() && !entry.name.endsWith(".json")) {
|
|
70868
|
+
try {
|
|
70869
|
+
files[entry.name] = rf(resolve13(roleDir, entry.name), "utf-8");
|
|
70870
|
+
} catch {
|
|
70871
|
+
}
|
|
70872
|
+
}
|
|
70873
|
+
}
|
|
70874
|
+
} catch {
|
|
70875
|
+
}
|
|
70876
|
+
}
|
|
70877
|
+
this.json(res, 200, { files });
|
|
70878
|
+
return;
|
|
70879
|
+
}
|
|
70802
70880
|
if (path === "/api/templates/instantiate" && req.method === "POST") {
|
|
70803
70881
|
const body = await this.readBody(req);
|
|
70804
70882
|
const templateId = body["templateId"];
|
|
@@ -72563,6 +72641,48 @@ EXPLANATION_END`;
|
|
|
72563
72641
|
this.json(res, 201, { template: tpl });
|
|
72564
72642
|
return;
|
|
72565
72643
|
}
|
|
72644
|
+
if (path.match(/^\/api\/team-templates\/[^/]+\/files$/) && req.method === "GET") {
|
|
72645
|
+
const id = path.split("/")[3];
|
|
72646
|
+
const tpl = this.teamTemplateRegistry.get(id);
|
|
72647
|
+
if (!tpl) {
|
|
72648
|
+
this.json(res, 404, { error: "Team template not found" });
|
|
72649
|
+
return;
|
|
72650
|
+
}
|
|
72651
|
+
const { existsSync: ex, readFileSync: rf, readdirSync: rd } = await import("node:fs");
|
|
72652
|
+
const rolesDir = resolve13(process.cwd(), "templates", "roles");
|
|
72653
|
+
const rolesCandidates = [rolesDir];
|
|
72654
|
+
try {
|
|
72655
|
+
const thisFile = (await import("node:url")).fileURLToPath(import.meta.url);
|
|
72656
|
+
const thisDir = (await import("node:path")).dirname(thisFile);
|
|
72657
|
+
rolesCandidates.unshift(resolve13(thisDir, "..", "templates", "roles"));
|
|
72658
|
+
rolesCandidates.push(resolve13(thisDir, "..", "..", "..", "..", "templates", "roles"));
|
|
72659
|
+
} catch {
|
|
72660
|
+
}
|
|
72661
|
+
const rolesRoot = rolesCandidates.find((d) => ex(d)) ?? rolesDir;
|
|
72662
|
+
const files = {};
|
|
72663
|
+
for (const member of tpl.members) {
|
|
72664
|
+
const roleName = member.roleName;
|
|
72665
|
+
if (!roleName)
|
|
72666
|
+
continue;
|
|
72667
|
+
const memberSlug = (member.name ?? roleName).toLowerCase().replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, "").replace(/-{2,}/g, "-").replace(/^-|-$/g, "");
|
|
72668
|
+
const roleDir = resolve13(rolesRoot, roleName);
|
|
72669
|
+
if (!ex(roleDir))
|
|
72670
|
+
continue;
|
|
72671
|
+
try {
|
|
72672
|
+
for (const entry of rd(roleDir, { withFileTypes: true })) {
|
|
72673
|
+
if (entry.isFile() && !entry.name.endsWith(".json")) {
|
|
72674
|
+
try {
|
|
72675
|
+
files[`members/${memberSlug}/${entry.name}`] = rf(resolve13(roleDir, entry.name), "utf-8");
|
|
72676
|
+
} catch {
|
|
72677
|
+
}
|
|
72678
|
+
}
|
|
72679
|
+
}
|
|
72680
|
+
} catch {
|
|
72681
|
+
}
|
|
72682
|
+
}
|
|
72683
|
+
this.json(res, 200, { files });
|
|
72684
|
+
return;
|
|
72685
|
+
}
|
|
72566
72686
|
if (path.startsWith("/api/team-templates/") && req.method === "GET") {
|
|
72567
72687
|
const id = path.split("/")[3];
|
|
72568
72688
|
const tpl = this.teamTemplateRegistry.get(id);
|