feat: add OpenCode/Codex outputs and update changelog (#104)

* Add OpenCode converter coverage and specs

* Add Codex target support and spec docs

* Generate Codex command skills and refresh spec docs

* Add global Codex install path

* fix: harden plugin path loading and codex descriptions

* feat: ensure codex agents block on convert/install

* docs: clarify target branch usage for review

* chore: prep npm package metadata and release notes

* docs: mention opencode and codex in changelog

* docs: update CLI usage and remove stale todos

* feat: install from GitHub with global outputs
This commit is contained in:
Kieran Klaassen
2026-01-21 17:00:30 -08:00
committed by GitHub
parent c50208d413
commit e97f85bd53
61 changed files with 3303 additions and 5 deletions

65
src/utils/frontmatter.ts Normal file
View File

@@ -0,0 +1,65 @@
import { load } from "js-yaml"
export type FrontmatterResult = {
data: Record<string, unknown>
body: string
}
export function parseFrontmatter(raw: string): FrontmatterResult {
const lines = raw.split(/\r?\n/)
if (lines.length === 0 || lines[0].trim() !== "---") {
return { data: {}, body: raw }
}
let endIndex = -1
for (let i = 1; i < lines.length; i += 1) {
if (lines[i].trim() === "---") {
endIndex = i
break
}
}
if (endIndex === -1) {
return { data: {}, body: raw }
}
const yamlText = lines.slice(1, endIndex).join("\n")
const body = lines.slice(endIndex + 1).join("\n")
const parsed = load(yamlText)
const data = (parsed && typeof parsed === "object") ? (parsed as Record<string, unknown>) : {}
return { data, body }
}
export function formatFrontmatter(data: Record<string, unknown>, body: string): string {
const yaml = Object.entries(data)
.filter(([, value]) => value !== undefined)
.map(([key, value]) => formatYamlLine(key, value))
.join("\n")
if (yaml.trim().length === 0) {
return body
}
return [`---`, yaml, `---`, "", body].join("\n")
}
function formatYamlLine(key: string, value: unknown): string {
if (Array.isArray(value)) {
const items = value.map((item) => ` - ${formatYamlValue(item)}`)
return [key + ":", ...items].join("\n")
}
return `${key}: ${formatYamlValue(value)}`
}
function formatYamlValue(value: unknown): string {
if (value === null || value === undefined) return ""
if (typeof value === "number" || typeof value === "boolean") return String(value)
const raw = String(value)
if (raw.includes("\n")) {
return `|\n${raw.split("\n").map((line) => ` ${line}`).join("\n")}`
}
if (raw.includes(":") || raw.startsWith("[") || raw.startsWith("{")) {
return JSON.stringify(raw)
}
return raw
}