feat: workflow recipes, eval badges, one-click MCP, playground upgrades, sample gallery, skill-of-the-week

Signature features that turn breadth (174 skills) into a differentiated product:

- Workflow recipes: 5 cross-profession chains (workflows.json) that pass each
  output forward — slash commands (/ship-a-feature etc.), WORKFLOWS.md generated
  by scripts/build-workflows.mjs, README + MCP (list_workflows/get_workflow) wired
- Eval-backed quality: real per-skill scores from evals/results.json surfaced as
  badges in the playground and an honest README section (6 scored skills)
- One-click MCP: 'claude mcp add' install + workflow tools, works in any MCP client
- Playground: 'which skill?' recommender, with/without compare toggle, shareable
  ?skill= deep-links with prefilled inputs
- Sample-output gallery: hand-written examples for the hero five + generator
  (scripts/build-samples.mjs) + web/examples.html
- Skill-of-the-week: scheduled workflow + script that composes X/LinkedIn posts
  and posts to an optional webhook

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Mohit
2026-06-19 09:56:11 +01:00
parent 7f06f0a993
commit 54f76456ab
30 changed files with 1168 additions and 67 deletions
+34 -1
View File
@@ -71,6 +71,15 @@ function loadSkills() {
const SKILLS = loadSkills();
const byName = new Map(SKILLS.map((s) => [s.name, s]));
// Workflow recipes (chains of skills). Optional — absent in older installs.
function loadWorkflows() {
const f = join(PKG_ROOT, 'workflows.json');
if (!existsSync(f)) return [];
try { return JSON.parse(readFileSync(f, 'utf8')).workflows || []; } catch { return []; }
}
const WORKFLOWS = loadWorkflows();
const wfById = new Map(WORKFLOWS.map((w) => [w.id, w]));
// ── Tools ───────────────────────────────────────────────────────────────────
const TOOLS = [
{
@@ -95,6 +104,16 @@ const TOOLS = [
description: 'Get the full instructions (the SKILL.md body) for one skill by name. Apply these instructions to the user\'s task.',
inputSchema: { type: 'object', properties: { name: { type: 'string', description: 'The exact skill name, e.g. "rice-prioritisation".' } }, required: ['name'] },
},
{
name: 'list_workflows',
description: 'List workflow recipes — named chains that run several skills in sequence, passing each output forward (e.g. ship-a-feature, close-the-quarter). Use when a task spans multiple steps end to end.',
inputSchema: { type: 'object', properties: {} },
},
{
name: 'get_workflow',
description: 'Get one workflow recipe by id: the ordered list of skills to run and what each produces. Run each step in order with get_skill, carrying every output forward as context for the next.',
inputSchema: { type: 'object', properties: { id: { type: 'string', description: 'The workflow id, e.g. "ship-a-feature".' } }, required: ['id'] },
},
];
function runTool(name, args = {}) {
@@ -125,6 +144,20 @@ function runTool(name, args = {}) {
if (!s) throw new Error(`Unknown skill "${args.name}". Use search_skills or list_skills to find one.`);
return s.body;
}
if (name === 'list_workflows') {
if (!WORKFLOWS.length) return 'No workflow recipes are available in this install.';
return WORKFLOWS.map((w) =>
`- ${w.id} (${w.lifecycle}) — ${w.summary}\n chain: ${w.steps.map((s) => s.skill).join(' → ')}`
).join('\n');
}
if (name === 'get_workflow') {
const w = wfById.get(String(args.id || '').trim());
if (!w) throw new Error(`Unknown workflow "${args.id}". Use list_workflows to see available recipes.`);
const steps = w.steps.map((s, i) =>
`${i + 1}. get_skill("${s.skill}") → produces ${s.produces}.${s.passes ? ` Pass forward: ${s.passes}.` : ''}`
).join('\n');
return `Workflow: ${w.name} (${w.lifecycle})\n${w.summary}\n\nRun these in order, carrying each output forward as context for the next:\n${steps}`;
}
throw new Error(`Unknown tool: ${name}`);
}
@@ -165,7 +198,7 @@ function handle(msg) {
}
}
process.stderr.write(`[${SERVER_NAME}] MCP server ready — ${SKILLS.length} skills, ${TOOLS.length} tools.\n`);
process.stderr.write(`[${SERVER_NAME}] MCP server ready — ${SKILLS.length} skills, ${WORKFLOWS.length} workflow recipes, ${TOOLS.length} tools.\n`);
process.stderr.write(`[${SERVER_NAME}] ⭐ Star the repo: https://github.com/mohitagw15856/pm-claude-skills\n`);
const rl = createInterface({ input: process.stdin });
rl.on('line', (line) => {