mirror of
https://github.com/openai/codex.git
synced 2026-11-08 20:40:33 +00:00
Migrate plugin commands into skills on install (#33411)
## What changed - Convert supported plugin command Markdown into generated skills when a plugin is installed. - Read command sources from the manifest's `commands` field, falling back to the plugin's `commands/` directory. - Load generated command skills alongside native plugin skills while preferring native skills with the same name. - Skip commands with unsupported templates, missing descriptions, name collisions, or generated skills larger than 4 KB, and keep migration failures from blocking plugin installation. ## Testing - Cover default and manifest-configured command paths, stale generated skill cleanup, size limits, native-skill precedence, invalid manifest fields, and non-fatal migration errors. GitOrigin-RevId: 67d910048544b160b191066569bca69b2b951ebc
This commit is contained in:
committed by
copyberry
parent
38b064c31b
commit
2cd6ed7509
@@ -0,0 +1,95 @@
|
||||
use super::RewriteProfile;
|
||||
|
||||
pub(super) fn rewrite_terms(content: &str, profile: RewriteProfile) -> String {
|
||||
let mut rewritten =
|
||||
replace_case_insensitive_with_boundaries(content, profile.doc_file_name, "AGENTS.md");
|
||||
for from in profile.term_variants {
|
||||
rewritten = replace_case_insensitive_with_boundaries(&rewritten, from, "Codex");
|
||||
}
|
||||
for from in profile.case_sensitive_term_variants {
|
||||
rewritten = replace_with_boundaries(&rewritten, from, "Codex");
|
||||
}
|
||||
rewritten
|
||||
}
|
||||
|
||||
fn replace_with_boundaries(input: &str, needle: &str, replacement: &str) -> String {
|
||||
if needle.is_empty() {
|
||||
return input.to_string();
|
||||
}
|
||||
|
||||
replace_with_boundaries_impl(input, needle, replacement, input)
|
||||
}
|
||||
|
||||
fn replace_case_insensitive_with_boundaries(
|
||||
input: &str,
|
||||
needle: &str,
|
||||
replacement: &str,
|
||||
) -> String {
|
||||
let needle_lower = needle.to_ascii_lowercase();
|
||||
if needle_lower.is_empty() {
|
||||
return input.to_string();
|
||||
}
|
||||
let haystack_lower = input.to_ascii_lowercase();
|
||||
replace_with_boundaries_impl(input, &needle_lower, replacement, &haystack_lower)
|
||||
}
|
||||
|
||||
fn replace_with_boundaries_impl(
|
||||
input: &str,
|
||||
needle: &str,
|
||||
replacement: &str,
|
||||
searchable_input: &str,
|
||||
) -> String {
|
||||
let bytes = input.as_bytes();
|
||||
let mut output = String::with_capacity(input.len());
|
||||
let mut last_emitted = 0usize;
|
||||
let mut search_start = 0usize;
|
||||
|
||||
while let Some(relative_pos) = searchable_input[search_start..].find(needle) {
|
||||
let start = search_start + relative_pos;
|
||||
let end = start + needle.len();
|
||||
let boundary_before = start == 0 || !is_word_byte(bytes[start - 1]);
|
||||
let boundary_after = end == bytes.len() || !is_word_byte(bytes[end]);
|
||||
|
||||
if boundary_before && boundary_after {
|
||||
output.push_str(&input[last_emitted..start]);
|
||||
output.push_str(replacement);
|
||||
last_emitted = end;
|
||||
}
|
||||
search_start = start + 1;
|
||||
}
|
||||
|
||||
if last_emitted == 0 {
|
||||
return input.to_string();
|
||||
}
|
||||
output.push_str(&input[last_emitted..]);
|
||||
output
|
||||
}
|
||||
|
||||
pub(super) fn yaml_string(value: &str) -> String {
|
||||
format!("\"{}\"", value.replace('\\', "\\\\").replace('"', "\\\""))
|
||||
}
|
||||
|
||||
pub(super) fn slugify_name(value: &str) -> String {
|
||||
let mut slug = String::new();
|
||||
let mut last_was_dash = false;
|
||||
for ch in value.chars() {
|
||||
if ch.is_ascii_alphanumeric() {
|
||||
slug.push(ch.to_ascii_lowercase());
|
||||
last_was_dash = false;
|
||||
} else if !last_was_dash {
|
||||
slug.push('-');
|
||||
last_was_dash = true;
|
||||
}
|
||||
}
|
||||
|
||||
let slug = slug.trim_matches('-').to_string();
|
||||
if slug.is_empty() {
|
||||
"migrated".to_string()
|
||||
} else {
|
||||
slug
|
||||
}
|
||||
}
|
||||
|
||||
fn is_word_byte(byte: u8) -> bool {
|
||||
byte.is_ascii_alphanumeric() || byte == b'_'
|
||||
}
|
||||
Reference in New Issue
Block a user