From 72bf9f8e3b64a2fac3b05fe522b4afd899b01c62 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 19 Jul 2026 09:01:27 +0000 Subject: [PATCH 1/3] feat: update WorkshopExperience to filter steps by journey/adventure frontmatter Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- docs/scripts/sync-workshop-content.js | 35 ++- .../workshop/WorkshopExperience.astro | 66 ++++- docs/src/generated/workshop-content.ts | 280 ++++++++++++++++-- docs/src/lib/workshop/manifest.ts | 81 ++++- 4 files changed, 395 insertions(+), 67 deletions(-) diff --git a/docs/scripts/sync-workshop-content.js b/docs/scripts/sync-workshop-content.js index 39a5c2a10db..ba7a763744e 100644 --- a/docs/scripts/sync-workshop-content.js +++ b/docs/scripts/sync-workshop-content.js @@ -74,6 +74,20 @@ function loadLocalWorkshopEntries(sourceDir) { })); } +function parseFrontmatter(body) { + const match = body.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?/u); + if (!match) return { frontmatter: {}, body }; + const yaml = match[1]; + const frontmatter = /** @type {Record} */ ({}); + for (const line of yaml.split('\n')) { + const colonIdx = line.indexOf(':'); + if (colonIdx > 0) { + frontmatter[line.slice(0, colonIdx).trim()] = line.slice(colonIdx + 1).trim(); + } + } + return { frontmatter, body: body.slice(match[0].length) }; +} + function stripMarkdown(value) { return String(value) .replace(/!\[([^\]]*)\]\([^)]+\)/gu, '$1') @@ -117,11 +131,17 @@ function extractSummary(body) { } function addEntryMetadata(entries) { - return entries.map((entry) => ({ - ...entry, - title: extractTitle(entry.body, entry.id), - summary: extractSummary(entry.body), - })); + return entries.map((entry) => { + const { frontmatter, body } = parseFrontmatter(entry.body); + return { + ...entry, + body, + journey: frontmatter['journey'] || 'all', + adventure: frontmatter['adventure'] || 'core', + title: extractTitle(body, entry.id), + summary: extractSummary(body), + }; + }); } function rewriteWorkshopMarkdownForAstro(body, rawBaseUrl = publicWorkshopRawBaseUrl) { @@ -210,7 +230,8 @@ rmSync(markdownOutputDir, { recursive: true, force: true }); mkdirSync(markdownOutputDir, { recursive: true }); for (const entry of entries) { - writeFileSync(join(markdownOutputDir, entry.id), rewriteWorkshopMarkdownForAstro(entry.body, effectiveRawBaseUrl), 'utf8'); + const { body } = parseFrontmatter(entry.body); + writeFileSync(join(markdownOutputDir, entry.id), rewriteWorkshopMarkdownForAstro(body, effectiveRawBaseUrl), 'utf8'); } const output = `${[ @@ -228,6 +249,8 @@ const output = `${[ '', 'export type WorkshopContentEntry = {', "\tid: string;", + "\tjourney: string;", + "\tadventure: string;", "\ttitle: string;", "\tsummary: string;", "\tbody: string;", diff --git a/docs/src/components/workshop/WorkshopExperience.astro b/docs/src/components/workshop/WorkshopExperience.astro index f4c8d9c0ddf..66eb3c83ef7 100644 --- a/docs/src/components/workshop/WorkshopExperience.astro +++ b/docs/src/components/workshop/WorkshopExperience.astro @@ -6,13 +6,15 @@ import { workshopDefaults, workshopEntryPaths, workshopJourneys, - workshopRoutes, + workshopScenarioAdventures, workshopScenarios, } from '../../lib/workshop/manifest'; import { workshopContent, workshopSource, type WorkshopContentEntry } from '../../generated/workshop-content.ts'; type WorkshopEntry = { id: string; + journey: string; + adventure: string; title: string; summary: string; body: string; @@ -21,6 +23,8 @@ type WorkshopEntry = { type WorkshopStep = { key: string; file: string; + journey: string; + adventure: string; title: string; summary: string; githubUrl: string; @@ -330,6 +334,8 @@ function normalizeKey(value: string) { const workshopEntries: WorkshopEntry[] = workshopContent.map((entry: WorkshopContentEntry) => ({ id: entry.id, + journey: entry.journey, + adventure: entry.adventure, title: entry.title, summary: entry.summary, body: entry.body, @@ -341,6 +347,8 @@ const workshopSteps: WorkshopStep[] = await Promise.all(workshopEntries.map(asyn return { key, file: `${key}.md`, + journey: entry.journey, + adventure: entry.adventure, title: entry.title, summary: entry.summary, githubUrl: new URL(`${key}.md`, workshopGithubBase).toString(), @@ -509,6 +517,8 @@ const initialStep = workshopSteps.find((item) => item.key === initialStepKey) ?? set:html={safeJson(workshopSteps.map((step) => ({ key: step.key, file: step.file, + journey: step.journey, + adventure: step.adventure, title: step.title, summary: step.summary, githubUrl: step.githubUrl, @@ -524,8 +534,8 @@ const initialStep = workshopSteps.find((item) => item.key === initialStepKey) ?? defaults: workshopDefaults, entryPaths: workshopEntryPaths, journeys: workshopJourneys, - routes: workshopRoutes, scenarios: workshopScenarios, + scenarioAdventures: workshopScenarioAdventures, })} />