mirror of
https://github.com/steel-dev/cli.git
synced 2026-09-14 20:47:34 +08:00
feat(skills): add --all option and interactive catalog flow
This commit is contained in:
@@ -209,11 +209,12 @@ steel skills list [--offline]
|
||||
|
||||
## steel skills install
|
||||
|
||||
Install one or more Steel Skills through `npx skills`.
|
||||
Install all Steel Skills, or one or more selected Steel Skills, through `npx skills`.
|
||||
|
||||
### Usage
|
||||
|
||||
```
|
||||
steel skills install --all [-a <agent>] [-g] [-y]
|
||||
steel skills install <name>... [-a <agent>] [-g] [-y]
|
||||
```
|
||||
|
||||
|
||||
+21
-14
@@ -10,9 +10,8 @@ pub struct Args {
|
||||
#[arg(long)]
|
||||
pub agent: bool,
|
||||
|
||||
/// Install selected Steel skills via the skills installer. With no value,
|
||||
/// installs the recommended bootstrap set
|
||||
#[arg(long, num_args = 0..=1, value_delimiter = ',', default_missing_value = "steel-browser,steel-developer")]
|
||||
/// Open the Steel skills installer flow. With no value, lets you choose skills interactively
|
||||
#[arg(long, num_args = 0..=1, value_delimiter = ',', default_missing_value = "__all__")]
|
||||
pub skills: Option<Vec<String>>,
|
||||
|
||||
/// Skip Steel skill installation
|
||||
@@ -63,24 +62,32 @@ async fn install_skills(args: &Args) -> anyhow::Result<()> {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let selected = args
|
||||
.skills
|
||||
.clone()
|
||||
.unwrap_or_else(|| vec!["steel-browser".to_string(), "steel-developer".to_string()]);
|
||||
let install_result = match &args.skills {
|
||||
Some(selected) if selected.is_empty() => return Ok(()),
|
||||
Some(selected) if is_all_selection(selected) => skills::install_catalog_flow().await,
|
||||
Some(selected) => skills::install_names(selected, false).await,
|
||||
None => skills::install_catalog_flow().await,
|
||||
};
|
||||
|
||||
if selected.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
match skills::install_names(&selected, args.agent).await {
|
||||
match install_result {
|
||||
Ok(()) => Ok(()),
|
||||
Err(error) => {
|
||||
status!("Could not install Steel skills through npx skills: {error:#}");
|
||||
status!("Install manually with:");
|
||||
for name in &selected {
|
||||
status!(" npx skills add steel-dev/skills --skill {name}");
|
||||
if let Some(selected) = &args.skills
|
||||
&& !is_all_selection(selected)
|
||||
{
|
||||
for name in selected {
|
||||
status!(" npx skills add steel-dev/skills --skill {name}");
|
||||
}
|
||||
} else {
|
||||
status!(" npx skills add steel-dev/skills");
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn is_all_selection(selected: &[String]) -> bool {
|
||||
selected.len() == 1 && matches!(selected[0].as_str(), "__all__" | "all")
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ Getting Started:
|
||||
steel init Log in, verify, and install Steel skills into detected agents
|
||||
--agent Print the agent onboarding guide to stdout and exit
|
||||
steel skills list List available Steel Skills
|
||||
steel skills install --all Install all Steel Skills through npx skills
|
||||
steel skills install <name> Install a Steel Skill through npx skills
|
||||
steel skills doctor Check skills installer, auth, manifest, and paths
|
||||
|
||||
|
||||
@@ -128,11 +128,14 @@ pub enum SkillsCommand {
|
||||
#[arg(long)]
|
||||
offline: bool,
|
||||
},
|
||||
/// Install one or more Steel skills through npx skills
|
||||
/// Install all or selected Steel skills through npx skills
|
||||
Install {
|
||||
/// Skill name(s) to install
|
||||
#[arg(required = true)]
|
||||
#[arg(required_unless_present = "all")]
|
||||
names: Vec<String>,
|
||||
/// Install all Steel skills from the catalog
|
||||
#[arg(long)]
|
||||
all: bool,
|
||||
/// Target agent passed to npx skills (-a)
|
||||
#[arg(short = 'a', long)]
|
||||
agent: Option<String>,
|
||||
@@ -236,10 +239,20 @@ pub async fn run(command: SkillsCommand) -> anyhow::Result<()> {
|
||||
SkillsCommand::List { offline } => list(offline).await,
|
||||
SkillsCommand::Install {
|
||||
names,
|
||||
all,
|
||||
agent,
|
||||
global,
|
||||
yes,
|
||||
} => install_names_with_options(&names, agent.as_deref(), global, yes).await,
|
||||
} => {
|
||||
if all {
|
||||
if !names.is_empty() {
|
||||
anyhow::bail!("cannot combine --all with explicit skill names");
|
||||
}
|
||||
install_all_with_options(agent.as_deref(), global, yes).await
|
||||
} else {
|
||||
install_names_with_options(&names, agent.as_deref(), global, yes).await
|
||||
}
|
||||
}
|
||||
SkillsCommand::Update { names, yes } => update(names, yes).await,
|
||||
SkillsCommand::Doctor { offline } => doctor(offline).await,
|
||||
SkillsCommand::Open { name } => open_skill(&name).await,
|
||||
@@ -248,7 +261,18 @@ pub async fn run(command: SkillsCommand) -> anyhow::Result<()> {
|
||||
}
|
||||
|
||||
pub async fn install_names(names: &[String], yes: bool) -> anyhow::Result<()> {
|
||||
install_names_with_options(names, None, true, yes).await
|
||||
install_names_with_options(names, None, false, yes).await
|
||||
}
|
||||
|
||||
pub async fn install_all(yes: bool) -> anyhow::Result<()> {
|
||||
install_all_with_options(None, false, yes).await
|
||||
}
|
||||
|
||||
pub async fn install_catalog_flow() -> anyhow::Result<()> {
|
||||
run_npx(&["skills", "add", REPO_SPEC])
|
||||
.context("starting Steel skills installer. You can also run manually: npx skills add steel-dev/skills")?;
|
||||
output::success_silent();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn list(offline: bool) -> anyhow::Result<()> {
|
||||
@@ -286,6 +310,10 @@ async fn install_names_with_options(
|
||||
global: bool,
|
||||
yes: bool,
|
||||
) -> anyhow::Result<()> {
|
||||
if names.is_empty() {
|
||||
anyhow::bail!("provide a skill name or use --all");
|
||||
}
|
||||
|
||||
let manifest = load_manifest(false).await?;
|
||||
for name in names {
|
||||
ensure_known_skill(&manifest, name)?;
|
||||
@@ -312,6 +340,28 @@ async fn install_names_with_options(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn install_all_with_options(
|
||||
agent: Option<&str>,
|
||||
global: bool,
|
||||
yes: bool,
|
||||
) -> anyhow::Result<()> {
|
||||
let mut args = vec!["skills", "add", REPO_SPEC, "--all"];
|
||||
if let Some(agent) = agent {
|
||||
args.push("-a");
|
||||
args.push(agent);
|
||||
}
|
||||
if global {
|
||||
args.push("-g");
|
||||
}
|
||||
if yes {
|
||||
args.push("-y");
|
||||
}
|
||||
run_npx(&args).context("installing all Steel skills. You can also run manually: npx skills add steel-dev/skills --all")?;
|
||||
status!("Installed all Steel skills");
|
||||
output::success_silent();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn update(names: Vec<String>, yes: bool) -> anyhow::Result<()> {
|
||||
let manifest = load_manifest(false).await?;
|
||||
let selected = if names.is_empty() {
|
||||
|
||||
Reference in New Issue
Block a user