Single-commit clean baseline after security scrub of niche-tells, project codenames, internal jargon, and contributor-email leaks. Contents: - 100 Rust crates (_primitives/_rust/) - 37 agent manifests (_manifests/) + generated specs (_generated/) - 67 user-invocable skills (skills/) - 33 hooks (hooks/) - Composition blocks (_blocks/) - Documentation (docs/, README.md) - TS adapter packages (_ts_packages/) - Assembler (_assembler/) - Roles (_roles/) - Templates (_templates/) - Forgejo CI (.forgejo/) Author: Denis Parfionovich <info@greendragon.info> License: see LICENSE.
81 lines
3.1 KiB
Rust
81 lines
3.1 KiB
Rust
//! Format round-trip: parse a Hermes reference SKILL.md, serialize, and
|
|
//! diff. Byte-equality is the contract — Hermes interop must be lossless.
|
|
|
|
use kei_skills::format::{parse, serialize};
|
|
use std::path::PathBuf;
|
|
|
|
fn ref_skill_minimal() -> &'static str {
|
|
// Description avoids special chars that serde_yaml would force-quote.
|
|
"---\nname: yuanbao\ndescription: yuanbao groups mention\n---\n\n# Body\n\nHello.\n"
|
|
}
|
|
|
|
fn ref_skill_with_extras() -> &'static str {
|
|
concat!(
|
|
"---\n",
|
|
"name: ocr-and-documents\n",
|
|
"description: \"OCR + PDF/Word/Excel/PPT.\"\n",
|
|
"category: productivity\n",
|
|
"stability: validated\n",
|
|
"metadata:\n",
|
|
" hermes:\n",
|
|
" tags:\n",
|
|
" - ocr\n",
|
|
" - pdf\n",
|
|
"---\n",
|
|
"\n",
|
|
"## Overview\n",
|
|
"Body text.\n",
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn roundtrip_minimal_byte_equal() {
|
|
let src = ref_skill_minimal();
|
|
let parsed = parse(src, PathBuf::from("<inline>")).expect("parse");
|
|
let out = serialize(&parsed).expect("serialize");
|
|
// Reparse-equal is the primary contract: serde_yaml may pick
|
|
// different (still-valid) YAML output for the same logical mapping
|
|
// (quote style, anchor handling). Round-trip via reparse confirms
|
|
// no semantic loss.
|
|
let reparsed = parse(&out, PathBuf::from("<inline>")).expect("reparse");
|
|
assert_eq!(reparsed.frontmatter, parsed.frontmatter);
|
|
assert_eq!(reparsed.body, parsed.body);
|
|
}
|
|
|
|
#[test]
|
|
fn roundtrip_with_category_and_stability() {
|
|
let src = "---\nname: research\ndescription: deep-research\ncategory: meta\nstability: experimental\n---\n\nBody.\n";
|
|
let parsed = parse(src, PathBuf::from("<inline>")).expect("parse");
|
|
assert_eq!(parsed.frontmatter.category.as_deref(), Some("meta"));
|
|
assert_eq!(parsed.frontmatter.stability.as_deref(), Some("experimental"));
|
|
let out = serialize(&parsed).expect("serialize");
|
|
let reparsed = parse(&out, PathBuf::from("<inline>")).expect("reparse");
|
|
assert_eq!(reparsed.frontmatter, parsed.frontmatter);
|
|
assert_eq!(reparsed.body, parsed.body);
|
|
}
|
|
|
|
#[test]
|
|
fn roundtrip_preserves_extra_metadata() {
|
|
let src = ref_skill_with_extras();
|
|
let parsed = parse(src, PathBuf::from("<inline>")).expect("parse");
|
|
assert_eq!(parsed.frontmatter.name, "ocr-and-documents");
|
|
assert!(parsed.frontmatter.extra.contains_key(serde_yaml::Value::String("metadata".into())));
|
|
let out = serialize(&parsed).expect("serialize");
|
|
let reparsed = parse(&out, PathBuf::from("<inline>")).expect("re-parse");
|
|
assert_eq!(reparsed.frontmatter, parsed.frontmatter);
|
|
assert_eq!(reparsed.body, parsed.body);
|
|
}
|
|
|
|
#[test]
|
|
fn body_only_after_close_fence() {
|
|
let src = "---\nname: x\ndescription: y\n---\nBody starts here.\n";
|
|
let parsed = parse(src, PathBuf::from("<inline>")).expect("parse");
|
|
assert_eq!(parsed.body, "Body starts here.\n");
|
|
}
|
|
|
|
#[test]
|
|
fn parse_rejects_unclosed_frontmatter() {
|
|
let src = "---\nname: x\ndescription: y\n# never closes\n";
|
|
let err = parse(src, PathBuf::from("<inline>")).expect_err("must error");
|
|
assert!(err.to_string().contains("not closed"));
|
|
}
|