From 4934dd2dd93ab80feb0bc59bb01e728264de23ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Pe=C3=B1a?= Date: Mon, 1 Jun 2026 19:29:14 -0600 Subject: [PATCH] =?UTF-8?q?feat(idtk):=20commands/path-visualize.md=20?= =?UTF-8?q?=E2=80=94=20standalone=20HTML=20syllabus=20viewer=20for=20paths?= =?UTF-8?q?=20(DOJ-4784)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reads a dojo-academy path slug + emits paths/{slug}/syllabus.html showing per-course modules + per-module artifact table (✅/❌). Authoring debug tool, NOT student-facing. Brand consumed from dojo-academy/instruction-bundle-spec.yaml when present; graceful-degrade to neutral defaults + visible WARNING when missing (unblocks ship if DOJ-4785 not yet merged). Created by Claude Code on behalf of @andres@dojocoding.io Co-Authored-By: Claude Opus 4.7 --- commands/path-visualize.md | 293 +++++++++++++++++++++++++++++++++++++ 1 file changed, 293 insertions(+) create mode 100644 commands/path-visualize.md diff --git a/commands/path-visualize.md b/commands/path-visualize.md new file mode 100644 index 0000000..24863d5 --- /dev/null +++ b/commands/path-visualize.md @@ -0,0 +1,293 @@ +--- +description: "Genera syllabus.html standalone para un path — header de metadata + per-milestone course list + per-course modules + per-module artifact-coverage table (✅/❌ por text/video/slides/quiz/challenge). Tool de QA de authoring, NO student-facing." +argument-hint: "[path-slug | absolute-path-to-path-dir]" +--- + +# /path-visualize — Path Syllabus Viewer (HTML standalone) + +Dispatcher que invoca el skill `instructional-design-toolkit:path-visualize`. + +Lee la estructura de un path (slug o ruta absoluta a un directorio de path) y +emite un único HTML auto-contenido al lado del `path-overview.md` del path: + +``` +/syllabus.html +``` + +El HTML es un visor de **cobertura estructural cross-course** — distinto del +sibling `course-visualize` (curvas pedagógicas de UN curso). Audiencia: path +owner + admin haciendo authoring QA, NO student-facing y NO instructor in-class +(para eso existen `workbook` y `slides-generate` respectivamente). + +--- + +## Phase 1 — Resolve input + +1. **Resolvé el argumento.** `$ARGUMENTS` puede ser: + - Un slug (e.g. `agentic-ai`) — resolvelo a + `/content/paths//`. + - Una ruta absoluta a un directorio de path que contiene un + `path-overview.md`. + Si está vacío, pedile al usuario el slug o la ruta. Si el directorio o el + `path-overview.md` no existen, abortá con un mensaje claro nombrando el + path probado. +2. **Detectá el consumer root.** Caminá desde `cwd` hacia arriba buscando un + `.claude-plugin/plugin.json` o un `content/paths/` sibling. Ese root es el + ancla para resolver slugs de cursos en Phase 2 (debe contener + `content/courses//`). +3. **Idempotencia.** Si `/syllabus.html` ya existe, sobrescribilo + sin preguntar — es un archivo derivado, regenerable. Reportá la + sobrescritura al usuario. + +--- + +## Phase 2 — Read structure + +1. **Parseá el frontmatter de `path-overview.md`.** Campos esperados: + `slug`, `title`, `status`, `level`, `emblem`, `badge`, `faculty`, + `description`, `cert_name`, `skills_demonstrated[]`, `earning_criteria[]`, + `tech_pills[]`, `reward_points`, `milestones[]`. Cada `milestone` tiene + `title`, `description`, `courses[]` (array de slugs ordenados). +2. **Tolerá variantes.** Si el path no tiene `milestones[]` (e.g. un path + plano con `courses[]` al root del frontmatter), degradalo a un único + milestone virtual con `title: "Courses"` y `courses` = ese array. Si el + path tampoco tiene `courses[]`, emití warning visible en el HTML y un + render con cero courses (no abortes). +3. **Para cada course slug:** + - Resolvé `/content/courses//`. + - Si no existe, emití warning visible en el HTML para ese course + (marcalo `MISSING` en la tabla) y continuá con el siguiente. + - Leé `course-overview.md` si existe — extraé `title` para mostrar nombre + legible. Si no, usá el slug. + - Enumerá subdirectorios `module-*/` ordenados lexicográficamente + (`module-01-*`, `module-02-*`, …). + - Para cada módulo, leé `classes/` y clasificá cada archivo por prefijo: + - `text-*.md` → bucket `text` + - `video-*.md` → bucket `video` + - `slides-*.html` → bucket `slides` + - `quiz-*.md` → bucket `quiz` + - `challenge-*.md` → bucket `challenge` + Un bucket cuenta como `✅` si tiene ≥1 archivo, `❌` si está vacío. +4. **Agregá totales.** Computá el %-by-type cross-path: + `coverage_pct[type] = modules_with_type / total_modules`. Mostralo en el + header. +5. **Read-only.** No mutes ningún archivo de `content/`. Esto es un viewer. + +--- + +## Phase 3 — Resolve design tokens (overlay-aware) + +Buscá `/instruction-bundle-spec.yaml`. + +- **Si existe:** leé las secciones top-level `design` (palette, typography, + voice) y `path_visualizer` (tree layout, `card_pattern` con `artifact_grid` + order + `status_glyphs`). Usalas para componer el CSS y el JSON de + configuración del HTML. +- **Si NO existe:** usá tokens **neutrales** + emití un comentario HTML + visible (``) **y** un banner amarillo en la UI + (`
`) explicando que el visual está en modo + default y mencionando el path esperado. NO crashees. NO hardcodees "Dojo". + +### Neutral defaults (sin YAML) + +- Palette: `#111` foreground, `#fafafa` background, `#666` muted, `#22c55e` + success (✅), `#ef4444` danger (❌), `#f59e0b` warning. +- Typography: Inter (Google Fonts CDN — única dep externa permitida) con + fallback `system-ui, -apple-system, sans-serif`. +- Voice: copy en EN-only neutral ("Path Syllabus", "Coverage", "Modules + missing X"). Sin nombres de marca. + +### Defaults aplicados al `card_pattern` cuando no hay YAML + +- `artifact_grid` order: `[text, video, slides, quiz, challenge]`. +- `status_glyphs`: `{ present: "✅", missing: "❌" }`. + +--- + +## Phase 4 — Emit `syllabus.html` + +Escribí un único archivo HTML standalone en `/syllabus.html`. Reglas +duras: + +- **Self-contained.** Todo el CSS y JS inline. NO `` + excepto Google Fonts para Inter (convención aceptada por el target). +- **Tamaño ≤500KB.** Imágenes opcionales solo si el path declara `badge` y el + archivo existe localmente — referencialo por path relativo (`./badge.png`), + no embebido en base64. +- **Mobile-responsive.** Mínimo 375px sin scroll horizontal. Optimizá 768px+ + con grid de cards más amplio. +- **Accesibilidad básica.** `` con `
` para artifact + columns; `
` para per-course expand (keyboard-nativo); `aria-label` + en filter chips e icon buttons. + +### Estructura del documento + +1. **``** — título `" — Syllabus"`, meta viewport, Google + Fonts link para Inter, `