mrvn-cli 0.1.3 → 0.2.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.
@@ -16534,7 +16534,9 @@ function getPluginTools(plugin, store, marvinDir) {
16534
16534
  // src/skills/registry.ts
16535
16535
  import * as fs7 from "fs";
16536
16536
  import * as path7 from "path";
16537
+ import { fileURLToPath } from "url";
16537
16538
  import * as YAML5 from "yaml";
16539
+ import matter2 from "gray-matter";
16538
16540
 
16539
16541
  // src/skills/builtin/governance-review.ts
16540
16542
  var governanceReviewSkill = {
@@ -16542,6 +16544,7 @@ var governanceReviewSkill = {
16542
16544
  name: "Governance Review",
16543
16545
  description: "Review open governance items and generate summaries",
16544
16546
  version: "1.0.0",
16547
+ format: "builtin-ts",
16545
16548
  personas: ["delivery-manager", "product-owner"],
16546
16549
  promptFragments: {
16547
16550
  "delivery-manager": `You have the **Governance Review** skill. You can proactively review all open governance items (decisions, actions, questions) and produce structured summaries with recommendations. Use the \`governance-review__summarize\` tool to run a comprehensive review.`,
@@ -16576,11 +16579,81 @@ Be thorough but concise. Focus on actionable insights.`,
16576
16579
  var BUILTIN_SKILLS = {
16577
16580
  "governance-review": governanceReviewSkill
16578
16581
  };
16582
+ function getBuiltinSkillsDir() {
16583
+ const thisFile = fileURLToPath(import.meta.url);
16584
+ return path7.join(path7.dirname(thisFile), "builtin");
16585
+ }
16586
+ function loadSkillFromDirectory(dirPath) {
16587
+ const skillMdPath = path7.join(dirPath, "SKILL.md");
16588
+ if (!fs7.existsSync(skillMdPath)) return void 0;
16589
+ try {
16590
+ const raw = fs7.readFileSync(skillMdPath, "utf-8");
16591
+ const { data, content } = matter2(raw);
16592
+ if (!data.name || !data.description) return void 0;
16593
+ const metadata = data.metadata ?? {};
16594
+ const version2 = metadata.version ?? "1.0.0";
16595
+ const personas = metadata.personas;
16596
+ const promptFragments = {};
16597
+ const wildcardPrompt = content.trim();
16598
+ if (wildcardPrompt) {
16599
+ promptFragments["*"] = wildcardPrompt;
16600
+ }
16601
+ const personasDir = path7.join(dirPath, "personas");
16602
+ if (fs7.existsSync(personasDir)) {
16603
+ try {
16604
+ for (const file2 of fs7.readdirSync(personasDir)) {
16605
+ if (!file2.endsWith(".md")) continue;
16606
+ const personaId = file2.replace(/\.md$/, "");
16607
+ const personaPrompt = fs7.readFileSync(path7.join(personasDir, file2), "utf-8").trim();
16608
+ if (personaPrompt) {
16609
+ promptFragments[personaId] = personaPrompt;
16610
+ }
16611
+ }
16612
+ } catch {
16613
+ }
16614
+ }
16615
+ let actions;
16616
+ const actionsPath = path7.join(dirPath, "actions.yaml");
16617
+ if (fs7.existsSync(actionsPath)) {
16618
+ try {
16619
+ const actionsRaw = fs7.readFileSync(actionsPath, "utf-8");
16620
+ actions = YAML5.parse(actionsRaw);
16621
+ } catch {
16622
+ }
16623
+ }
16624
+ return {
16625
+ id: data.name,
16626
+ name: data.name.replace(/-/g, " ").replace(/\b\w/g, (c) => c.toUpperCase()),
16627
+ description: data.description,
16628
+ version: version2,
16629
+ format: "skill-md",
16630
+ dirPath,
16631
+ personas,
16632
+ promptFragments: Object.keys(promptFragments).length > 0 ? promptFragments : void 0,
16633
+ actions
16634
+ };
16635
+ } catch {
16636
+ return void 0;
16637
+ }
16638
+ }
16579
16639
  function loadAllSkills(marvinDir) {
16580
16640
  const skills = /* @__PURE__ */ new Map();
16581
16641
  for (const [id, skill] of Object.entries(BUILTIN_SKILLS)) {
16582
16642
  skills.set(id, skill);
16583
16643
  }
16644
+ try {
16645
+ const builtinDir = getBuiltinSkillsDir();
16646
+ if (fs7.existsSync(builtinDir)) {
16647
+ for (const entry of fs7.readdirSync(builtinDir)) {
16648
+ const entryPath = path7.join(builtinDir, entry);
16649
+ if (!fs7.statSync(entryPath).isDirectory()) continue;
16650
+ if (skills.has(entry)) continue;
16651
+ const skill = loadSkillFromDirectory(entryPath);
16652
+ if (skill) skills.set(skill.id, skill);
16653
+ }
16654
+ }
16655
+ } catch {
16656
+ }
16584
16657
  if (marvinDir) {
16585
16658
  const skillsDir = path7.join(marvinDir, "skills");
16586
16659
  if (fs7.existsSync(skillsDir)) {
@@ -16590,10 +16663,20 @@ function loadAllSkills(marvinDir) {
16590
16663
  } catch {
16591
16664
  entries = [];
16592
16665
  }
16593
- for (const file2 of entries) {
16594
- if (!file2.endsWith(".yaml") && !file2.endsWith(".yml")) continue;
16666
+ for (const entry of entries) {
16667
+ const entryPath = path7.join(skillsDir, entry);
16668
+ try {
16669
+ if (fs7.statSync(entryPath).isDirectory()) {
16670
+ const skill = loadSkillFromDirectory(entryPath);
16671
+ if (skill) skills.set(skill.id, skill);
16672
+ continue;
16673
+ }
16674
+ } catch {
16675
+ continue;
16676
+ }
16677
+ if (!entry.endsWith(".yaml") && !entry.endsWith(".yml")) continue;
16595
16678
  try {
16596
- const raw = fs7.readFileSync(path7.join(skillsDir, file2), "utf-8");
16679
+ const raw = fs7.readFileSync(entryPath, "utf-8");
16597
16680
  const parsed = YAML5.parse(raw);
16598
16681
  if (!parsed?.id || !parsed?.name || !parsed?.version) continue;
16599
16682
  const skill = {
@@ -16601,6 +16684,7 @@ function loadAllSkills(marvinDir) {
16601
16684
  name: parsed.name,
16602
16685
  description: parsed.description ?? "",
16603
16686
  version: parsed.version,
16687
+ format: "yaml",
16604
16688
  personas: parsed.personas,
16605
16689
  promptFragments: parsed.promptFragments,
16606
16690
  actions: parsed.actions