@markus-global/cli 0.5.1 → 0.5.2

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 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 skills = found.map(({ manifest, path: p }) => {
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);