mirror of
https://github.com/openai/codex.git
synced 2026-11-06 20:20:34 +00:00
Testing replacing skill trigger for automation (do not land - test PR only)
This commit is contained in:
@@ -923,7 +923,7 @@ impl ChatComposer {
|
||||
if !self.skills_enabled() {
|
||||
return None;
|
||||
}
|
||||
Self::current_prefixed_token(&self.textarea, '$', true)
|
||||
Self::current_prefixed_token(&self.textarea, '%', true)
|
||||
}
|
||||
|
||||
/// Replace the active `@token` (the one under the cursor) with `path`.
|
||||
@@ -998,7 +998,7 @@ impl ChatComposer {
|
||||
.unwrap_or(after_cursor.len());
|
||||
let end_idx = safe_cursor + end_rel_idx;
|
||||
|
||||
let inserted = format!("${skill_name}");
|
||||
let inserted = format!("%{skill_name}");
|
||||
|
||||
let mut new_text =
|
||||
String::with_capacity(text.len() - (end_idx - start_idx) + inserted.len() + 1);
|
||||
|
||||
@@ -1604,7 +1604,7 @@ impl ChatWidget {
|
||||
self.insert_str("@");
|
||||
}
|
||||
SlashCommand::Skills => {
|
||||
self.insert_str("$");
|
||||
self.insert_str("%");
|
||||
}
|
||||
SlashCommand::Status => {
|
||||
self.add_status_output();
|
||||
@@ -3513,7 +3513,8 @@ fn find_skill_mentions(text: &str, skills: &[SkillMetadata]) -> Vec<SkillMetadat
|
||||
if seen.contains(&skill.name) {
|
||||
continue;
|
||||
}
|
||||
let needle = format!("${}", skill.name);
|
||||
let name = &skill.name;
|
||||
let needle = format!("%{name}");
|
||||
if text.contains(&needle) {
|
||||
seen.insert(skill.name.clone());
|
||||
matches.push(skill.clone());
|
||||
|
||||
@@ -58,6 +58,7 @@ use codex_protocol::plan_tool::PlanItemArg;
|
||||
use codex_protocol::plan_tool::StepStatus;
|
||||
use codex_protocol::plan_tool::UpdatePlanArgs;
|
||||
use codex_protocol::protocol::CodexErrorInfo;
|
||||
use codex_protocol::protocol::SkillScope;
|
||||
use codex_utils_absolute_path::AbsolutePathBuf;
|
||||
use crossterm::event::KeyCode;
|
||||
use crossterm::event::KeyEvent;
|
||||
@@ -3350,3 +3351,26 @@ fn chatwidget_tall() {
|
||||
.unwrap();
|
||||
assert_snapshot!(term.backend().vt100().screen().contents());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn skill_mentions_use_percent_prefix() {
|
||||
let deploy = SkillMetadata {
|
||||
name: "deploy".to_string(),
|
||||
description: "deploy skill".to_string(),
|
||||
path: PathBuf::from("/tmp/deploy"),
|
||||
scope: SkillScope::User,
|
||||
};
|
||||
let lint = SkillMetadata {
|
||||
name: "lint".to_string(),
|
||||
description: "lint skill".to_string(),
|
||||
path: PathBuf::from("/tmp/lint"),
|
||||
scope: SkillScope::User,
|
||||
};
|
||||
let skills = vec![deploy.clone(), lint.clone()];
|
||||
|
||||
let matches = find_skill_mentions("Use %deploy and %lint", &skills);
|
||||
assert_eq!(matches, vec![deploy.clone(), lint.clone()]);
|
||||
|
||||
let matches = find_skill_mentions("Use $deploy only", &skills);
|
||||
assert_eq!(matches, Vec::new());
|
||||
}
|
||||
|
||||
@@ -929,7 +929,7 @@ impl ChatComposer {
|
||||
if !self.skills_enabled() {
|
||||
return None;
|
||||
}
|
||||
Self::current_prefixed_token(&self.textarea, '$', true)
|
||||
Self::current_prefixed_token(&self.textarea, '%', true)
|
||||
}
|
||||
|
||||
/// Replace the active `@token` (the one under the cursor) with `path`.
|
||||
@@ -1004,7 +1004,7 @@ impl ChatComposer {
|
||||
.unwrap_or(after_cursor.len());
|
||||
let end_idx = safe_cursor + end_rel_idx;
|
||||
|
||||
let inserted = format!("${skill_name}");
|
||||
let inserted = format!("%{skill_name}");
|
||||
|
||||
let mut new_text =
|
||||
String::with_capacity(text.len() - (end_idx - start_idx) + inserted.len() + 1);
|
||||
|
||||
@@ -1604,7 +1604,7 @@ impl ChatWidget {
|
||||
self.insert_str("@");
|
||||
}
|
||||
SlashCommand::Skills => {
|
||||
self.insert_str("$");
|
||||
self.insert_str("%");
|
||||
}
|
||||
SlashCommand::Status => {
|
||||
self.add_status_output();
|
||||
@@ -3518,7 +3518,8 @@ fn find_skill_mentions(text: &str, skills: &[SkillMetadata]) -> Vec<SkillMetadat
|
||||
if seen.contains(&skill.name) {
|
||||
continue;
|
||||
}
|
||||
let needle = format!("${}", skill.name);
|
||||
let name = &skill.name;
|
||||
let needle = format!("%{name}");
|
||||
if text.contains(&needle) {
|
||||
seen.insert(skill.name.clone());
|
||||
matches.push(skill.clone());
|
||||
|
||||
@@ -58,6 +58,7 @@ use codex_protocol::plan_tool::PlanItemArg;
|
||||
use codex_protocol::plan_tool::StepStatus;
|
||||
use codex_protocol::plan_tool::UpdatePlanArgs;
|
||||
use codex_protocol::protocol::CodexErrorInfo;
|
||||
use codex_protocol::protocol::SkillScope;
|
||||
use codex_utils_absolute_path::AbsolutePathBuf;
|
||||
use crossterm::event::KeyCode;
|
||||
use crossterm::event::KeyEvent;
|
||||
@@ -3350,3 +3351,26 @@ fn chatwidget_tall() {
|
||||
.unwrap();
|
||||
assert_snapshot!(term.backend().vt100().screen().contents());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn skill_mentions_use_percent_prefix() {
|
||||
let deploy = SkillMetadata {
|
||||
name: "deploy".to_string(),
|
||||
description: "deploy skill".to_string(),
|
||||
path: PathBuf::from("/tmp/deploy"),
|
||||
scope: SkillScope::User,
|
||||
};
|
||||
let lint = SkillMetadata {
|
||||
name: "lint".to_string(),
|
||||
description: "lint skill".to_string(),
|
||||
path: PathBuf::from("/tmp/lint"),
|
||||
scope: SkillScope::User,
|
||||
};
|
||||
let skills = vec![deploy.clone(), lint.clone()];
|
||||
|
||||
let matches = find_skill_mentions("Use %deploy and %lint", &skills);
|
||||
assert_eq!(matches, vec![deploy.clone(), lint.clone()]);
|
||||
|
||||
let matches = find_skill_mentions("Use $deploy only", &skills);
|
||||
assert_eq!(matches, Vec::new());
|
||||
}
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@ Skills are behind the experimental `skills` feature flag and are disabled by def
|
||||
|
||||
## Using skills
|
||||
|
||||
- Mention a skill by name in a message using `$<skill-name>`.
|
||||
- Mention a skill by name in a message using `%<skill-name>`.
|
||||
- In the TUI, you can also use `/skills` to browse and insert skills.
|
||||
|
||||
## Validation and errors
|
||||
|
||||
Reference in New Issue
Block a user