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.
65 lines
2.3 KiB
Rust
65 lines
2.3 KiB
Rust
//! Claude Code SKILL.md parser tests.
|
|
|
|
use kei_skill_importer::{import, AtomCallKind, SourceFormat};
|
|
use std::path::PathBuf;
|
|
|
|
fn fixture(name: &str) -> PathBuf {
|
|
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
|
|
.join("tests/fixtures")
|
|
.join(name)
|
|
}
|
|
|
|
#[test]
|
|
fn parses_name_description_and_category() {
|
|
let skill = import(&fixture("claude-pet-init.md"), SourceFormat::ClaudeCode)
|
|
.expect("parse");
|
|
assert_eq!(skill.name, "pet-init");
|
|
assert!(skill.description.contains("AI pet"));
|
|
assert!(skill.tags.iter().any(|t| t == "category:pet"),
|
|
"expect category:pet tag, got {:?}", skill.tags);
|
|
}
|
|
|
|
#[test]
|
|
fn classifier_resolves_kei_pet_keygen_and_validate() {
|
|
let skill = import(&fixture("claude-pet-init.md"), SourceFormat::ClaudeCode)
|
|
.expect("parse");
|
|
// Find any phase that contains kei-pet calls
|
|
let kei_pet_calls: Vec<_> = skill
|
|
.phases
|
|
.iter()
|
|
.flat_map(|p| p.atom_calls.iter())
|
|
.filter(|c| c.raw_command.starts_with("kei-pet"))
|
|
.collect();
|
|
assert!(kei_pet_calls.len() >= 2,
|
|
"expect ≥2 kei-pet calls, got {:?}", kei_pet_calls);
|
|
let keygen = kei_pet_calls.iter()
|
|
.find(|c| c.raw_command.starts_with("kei-pet keygen"))
|
|
.expect("keygen");
|
|
assert_eq!(keygen.atom_id.as_deref(), Some("kei-pet::keygen"));
|
|
assert_eq!(keygen.kind, AtomCallKind::KeiPrimitive);
|
|
}
|
|
|
|
#[test]
|
|
fn slash_command_detected() {
|
|
let skill = import(&fixture("claude-pet-init.md"), SourceFormat::ClaudeCode)
|
|
.expect("parse");
|
|
let slashes: Vec<_> = skill
|
|
.phases
|
|
.iter()
|
|
.flat_map(|p| p.atom_calls.iter())
|
|
.filter(|c| c.kind == AtomCallKind::UserPrompt)
|
|
.collect();
|
|
assert!(slashes.iter().any(|c| c.raw_command == "/escalate-recurrence"),
|
|
"expect /escalate-recurrence slash, got {:?}", slashes);
|
|
}
|
|
|
|
#[test]
|
|
fn h2_sections_become_phases() {
|
|
let skill = import(&fixture("claude-pet-init.md"), SourceFormat::ClaudeCode)
|
|
.expect("parse");
|
|
let names: Vec<&str> = skill.phases.iter().map(|p| p.name.as_str()).collect();
|
|
assert!(names.iter().any(|n| n.starts_with("Phase 1")),
|
|
"expect 'Phase 1' section, got {:?}", names);
|
|
assert!(names.iter().any(|n| n.starts_with("Phase 4")),
|
|
"expect 'Phase 4' section, got {:?}", names);
|
|
}
|