Merge: README lifecycle diagram + animated demo GIF
This commit is contained in:
@@ -26,16 +26,46 @@ A community-built library of professional skills for every field — product man
|
||||
|
||||
**🆕 Latest release (v20.2.0 — Community PRs & New Skill):** a new **YouTube Script Writer** skill (**174 total**), a stdlib **feature-prioritisation** helper, safer installs, and robust frontmatter parsing — all from community contributors. See the [changelog](#-changelog).
|
||||
|
||||
<!-- DEMO: replace web/docs-assets/playground.png below with web/docs-assets/playground-demo.gif
|
||||
once recorded (see web/docs-assets/README.md for how). The link goes to the live app. -->
|
||||
### ▶ See it in action — [try the live Skill Playground](https://mohitagw15856.github.io/pm-claude-skills/)
|
||||
|
||||
[](https://mohitagw15856.github.io/pm-claude-skills/)
|
||||
<!-- Demo GIF generated by web/docs-assets/record-demo.mjs (Playwright). The streamed
|
||||
output is a representative mock so no API key is needed; re-run with a live key
|
||||
for a real call. Static fallback: web/docs-assets/playground.png -->
|
||||
[](https://mohitagw15856.github.io/pm-claude-skills/)
|
||||
|
||||
<sub>👆 Pick any skill, fill a short form, and run it with your own key — no install required.</sub>
|
||||
|
||||
---
|
||||
|
||||
## 🔄 One library, the whole professional workflow
|
||||
|
||||
These 174 skills aren't a random catalog — they cover the **full arc of professional work**, end to end. Wherever you are in the loop, there's a skill for it:
|
||||
|
||||
```
|
||||
DISCOVER → DECIDE → BUILD → SHIP → MEASURE → COMMUNICATE
|
||||
────────── ────────── ────────── ────────── ────────── ─────────────
|
||||
frame the prioritise design & launch & track & report up
|
||||
problem, & spec the engineer release analyse & out
|
||||
research work the work the work results
|
||||
└────────────────────── feeds the next discovery ──────────────────────┘
|
||||
```
|
||||
|
||||
| Phase | What you're doing | Start with these skills |
|
||||
|-------|-------------------|--------------------------|
|
||||
| **🔍 Discover** | Frame the problem, research, validate | `ambiguity-resolver` · `user-research-synthesis` · `competitive-analysis` · `discovery-interview-guide` |
|
||||
| **🎯 Decide** | Prioritise, spec, set goals | `rice-prioritisation` · `prd-template` · `okr-builder` · `roadmap-narrative` |
|
||||
| **🔨 Build** | Design & engineer the work | `technical-spec-template` · `design-critique` · `sprint-planning` · `architecture-decision-record` |
|
||||
| **🚀 Ship** | Launch & release | `go-to-market` · `launch-readiness` · `product-launch-checklist` · `runbook-writer` |
|
||||
| **📊 Measure** | Track outcomes & analyse | `metrics-framework` · `cohort-analysis` · `ab-test-planner` · `churn-analysis` |
|
||||
| **📣 Communicate** | Report up and out | `executive-update` · `board-deck-narrative` · `stakeholder-update` · `qbr-deck` |
|
||||
|
||||
> New here? Start with the [**top-tier skills**](#️-skill-tiers--start-with-the-strongest), or jump straight to [**all 174 skills**](#️-all-174-skills) grouped by profession.
|
||||
|
||||
---
|
||||
|
||||
## Contents
|
||||
|
||||
- [🔄 One library, the whole professional workflow](#-one-library-the-whole-professional-workflow)
|
||||
- [🚀 Quick Install](#-quick-install-2-minutes)
|
||||
- [🔌 Works With — Cross-Tool Compatibility](#-works-with--cross-tool-compatibility)
|
||||
- [🤖 Subagents & Slash Commands](#-subagents--slash-commands)
|
||||
|
||||
@@ -2,9 +2,40 @@
|
||||
|
||||
Images used in the main README.
|
||||
|
||||
- `playground.png` — current Skill Playground screenshot (shown in the README hero).
|
||||
- `playground-demo.gif` — animated hero demo (shown in the README).
|
||||
- `playground.png` — static screenshot / fallback.
|
||||
|
||||
## Recording the hero demo GIF
|
||||
## Re-recording the hero demo GIF (automated)
|
||||
|
||||
`record-demo.mjs` drives the live Playground with Playwright and records a video.
|
||||
The navigation, skill selection, and form-fill are real; the streamed model output
|
||||
is a representative mock, so **no API key is needed**.
|
||||
|
||||
```bash
|
||||
# 1. Serve the playground locally
|
||||
cd web && python3 -m http.server 8080 &
|
||||
|
||||
# 2. Build the skills data if it is stale
|
||||
node web/build-skills.mjs
|
||||
|
||||
# 3. Record (Playwright + a matching Chromium must be installed)
|
||||
# npx playwright install chromium # one-time, if needed
|
||||
node web/docs-assets/record-demo.mjs # writes a .webm into this folder
|
||||
|
||||
# 4. Convert the .webm to an optimized GIF (two-pass palette)
|
||||
cd web/docs-assets
|
||||
V=$(ls *.webm | head -1)
|
||||
ffmpeg -y -i "$V" -vf "fps=13,scale=1080:-1:flags=lanczos,palettegen=stats_mode=diff" /tmp/palette.png
|
||||
ffmpeg -y -i "$V" -i /tmp/palette.png \
|
||||
-lavfi "fps=13,scale=1080:-1:flags=lanczos[x];[x][1:v]paletteuse=dither=bayer:bayer_scale=3:diff_mode=rectangle" \
|
||||
playground-demo.gif
|
||||
rm -f *.webm
|
||||
```
|
||||
|
||||
For a **fully live** recording (real Claude call instead of the mock), comment out the
|
||||
`window.fetch` override in `record-demo.mjs` and set a key via `localStorage` first.
|
||||
|
||||
## Recording manually (alternative)
|
||||
|
||||
To replace the static screenshot with a short looping demo:
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 2.6 MiB |
@@ -0,0 +1,124 @@
|
||||
// Records the Skill Playground hero demo as a video, driving the real UI with
|
||||
// Playwright. The navigation, skill selection, and form-fill are genuine; only
|
||||
// the streamed model output is mocked (a representative Executive Update) so the
|
||||
// recording needs no API key. Re-run with a live key to capture a real call.
|
||||
//
|
||||
// Usage: node web/docs-assets/record-demo.mjs
|
||||
// Then convert the .webm to playground-demo.gif (see record-demo.sh).
|
||||
|
||||
import { fileURLToPath } from 'url';
|
||||
import path from 'path';
|
||||
import { createRequire } from 'module';
|
||||
|
||||
// Playwright may be installed locally or only in the npx cache; resolve either.
|
||||
const require = createRequire(import.meta.url);
|
||||
const pwPath = process.env.PLAYWRIGHT_PATH || 'playwright';
|
||||
const pw = await import(pwPath).catch(() =>
|
||||
import(require.resolve('playwright', { paths: [process.env.PLAYWRIGHT_DIR].filter(Boolean) }))
|
||||
);
|
||||
const chromium = pw.chromium || (pw.default && pw.default.chromium);
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const BASE = process.env.DEMO_URL || 'http://localhost:8080/';
|
||||
const VIEWPORT = { width: 1180, height: 760 };
|
||||
|
||||
// Representative output, streamed in small chunks for a natural typing effect.
|
||||
const OUTPUT = `# Executive Update — Q2, for the CEO
|
||||
|
||||
**Headline:** Activation is up 14% after the onboarding redesign; we are on track for the Q2 target with one staffing risk to flag.
|
||||
|
||||
## Key metrics
|
||||
- **Weekly active accounts:** 12,400 (+18% QoQ)
|
||||
- **Activation rate:** 61% (+14 pts) — best quarter on record
|
||||
- **Net revenue retention:** 112% (flat)
|
||||
|
||||
## Progress
|
||||
We shipped the redesigned onboarding flow to 100% of new accounts. Early cohorts show faster time-to-value (median 2.1 days, down from 4.6).
|
||||
|
||||
## Risks & decisions needed
|
||||
- **Risk:** Backend hiring is two roles behind plan, putting the billing revamp at risk for Q3.
|
||||
- **Decision:** Approve contractor budget to hold the Q3 date.
|
||||
|
||||
## Next steps
|
||||
- Roll the activation experiment into the core product (next sprint).
|
||||
- Bring a Q3 staffing plan to the next leadership review.`;
|
||||
|
||||
function chunk(text) {
|
||||
// Split into word-ish pieces so the stream renders progressively.
|
||||
return text.match(/\S+\s*/g) || [text];
|
||||
}
|
||||
|
||||
const initScript = ({ chunks }) => {
|
||||
try { localStorage.setItem('anthropic_api_key', 'sk-ant-demo-key-not-real'); } catch (e) {}
|
||||
const realFetch = window.fetch.bind(window);
|
||||
window.fetch = (url, opts) => {
|
||||
const u = typeof url === 'string' ? url : (url && url.url) || '';
|
||||
if (!u.includes('api.anthropic.com')) return realFetch(url, opts);
|
||||
const enc = new TextEncoder();
|
||||
let i = 0;
|
||||
const stream = new ReadableStream({
|
||||
start(controller) {
|
||||
const push = () => {
|
||||
if (i >= chunks.length) {
|
||||
controller.enqueue(enc.encode('data: {"type":"message_stop"}\n\n'));
|
||||
controller.close();
|
||||
return;
|
||||
}
|
||||
const evt = { type: 'content_block_delta', delta: { type: 'text_delta', text: chunks[i++] } };
|
||||
controller.enqueue(enc.encode('data: ' + JSON.stringify(evt) + '\n\n'));
|
||||
setTimeout(push, 45);
|
||||
};
|
||||
setTimeout(push, 200);
|
||||
},
|
||||
});
|
||||
return Promise.resolve(new Response(stream, { status: 200, headers: { 'content-type': 'text/event-stream' } }));
|
||||
};
|
||||
};
|
||||
|
||||
const pause = (ms) => new Promise((r) => setTimeout(r, ms));
|
||||
|
||||
const run = async () => {
|
||||
const browser = await chromium.launch();
|
||||
const context = await browser.newContext({
|
||||
viewport: VIEWPORT,
|
||||
deviceScaleFactor: 2,
|
||||
recordVideo: { dir: __dirname, size: VIEWPORT },
|
||||
});
|
||||
const page = await context.newPage();
|
||||
await page.addInitScript(initScript, { chunks: chunk(OUTPUT) });
|
||||
|
||||
await page.goto(BASE, { waitUntil: 'networkidle' });
|
||||
await page.waitForSelector('.skill-card');
|
||||
await pause(700);
|
||||
|
||||
// Search to surface the featured skill.
|
||||
await page.fill('#search', 'executive update');
|
||||
await pause(600);
|
||||
|
||||
// Open it.
|
||||
await page.click('.skill-card:has(.card-title:text-is("Executive Update"))');
|
||||
await page.waitForSelector('#inputForm input, #inputForm textarea');
|
||||
await pause(500);
|
||||
|
||||
// Fill the form like a real user would.
|
||||
await page.locator('#f_0').type(
|
||||
'Shipped onboarding redesign to all new accounts. Activation up sharply. Backend hiring behind plan, billing revamp at risk for Q3.',
|
||||
{ delay: 8 }
|
||||
);
|
||||
await pause(150);
|
||||
await page.locator('#f_1').type('CEO', { delay: 25 });
|
||||
await page.locator('#f_2').type('Q2', { delay: 25 });
|
||||
await page.locator('#f_3').type('WAA, activation rate, NRR', { delay: 18 });
|
||||
await pause(500);
|
||||
|
||||
// Run — the intercepted stream renders progressively.
|
||||
await page.click('#runBtn');
|
||||
await page.waitForFunction(() => document.querySelector('#status')?.textContent?.includes('Done'), { timeout: 15000 });
|
||||
await pause(1600); // hold on the finished result
|
||||
|
||||
await context.close(); // flushes the video file
|
||||
await browser.close();
|
||||
console.log('Recorded video into', __dirname);
|
||||
};
|
||||
|
||||
run().catch((e) => { console.error(e); process.exit(1); });
|
||||
Reference in New Issue
Block a user