--- name: parse_issue_md kind: function lang: go domain: infra version: "0.1.0" purity: impure signature: "func ParseIssueMd(path string) (Issue, []byte, error)" description: "Lee un archivo Markdown de issue (dev/issues/*.md), extrae el frontmatter YAML en un struct Issue y devuelve el body tal como esta en disco. Rellena FilePath, MtimeNs y Completed (deduce de si el path contiene /completed/)." tags: [issue, parser, frontmatter, yaml, kanban, dev-ux, kanban] uses_functions: [] uses_types: [issue_go_infra] returns: [issue_go_infra] returns_optional: false error_type: "error_go_core" imports: ["bytes", "fmt", "os", "strings", "gopkg.in/yaml.v3"] params: - name: path desc: "Ruta absoluta o relativa al archivo .md del issue (ej: dev/issues/0130-kanban-cpp-v2.md)" output: "Struct Issue con todos los campos del frontmatter, byte slice con el body MD, y error si el archivo no existe o el YAML es invalido" tested: true tests: - "parsea 0130-kanban-cpp-v2 correctamente" - "completed flag se deduce del path" - "error en archivo inexistente" - "fixture preserva campos" test_file_path: "functions/infra/parse_issue_md_test.go" file_path: "functions/infra/parse_issue_md.go" --- ## Ejemplo ```go iss, body, err := infra.ParseIssueMd("dev/issues/0130-kanban-cpp-v2.md") if err != nil { log.Fatal(err) } fmt.Printf("ID=%s Status=%s Domain=%v\n", iss.ID, iss.Status, iss.Domain) // body contiene el Markdown despues del segundo --- ``` ## Cuando usarla Cuando necesites leer el frontmatter de un issue del registry para mostrarlo, modificarlo o indexarlo. Usar como base de `scan_issues_dir_go_infra` (que la llama por cada archivo) o cuando necesites acceso al body MD ademas del struct. ## Gotchas - El body devuelto incluye el `\n` inmediatamente posterior al segundo `---`. No se normaliza. - Si el archivo tiene un solo `---` (sin segundo delimitador), retorna error. Issues sin frontmatter no son validos. - `Completed` se infiere del path, no del campo `status` del YAML — un issue con `status: completado` que vive en `dev/issues/` (no en `completed/`) tendra `Completed=false`. - Los campos `Depends`, `Blocks`, `Related`, `Tags`, `Domain` son `[]string` — si el YAML los omite quedan como `nil`, no slice vacio.