Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,47 @@

### Breaking Changes

- **CLI command-surface redesign: four commands removed (issue #183).**
`fastskill resolve`, `fastskill sync`, `fastskill disable`, and `fastskill show` have been
removed with no hidden aliases. Migration table:

| Removed command | Replacement |
|---|---|
| `fastskill resolve <query>` | `fastskill search <query> --local --paths --json` |
| `fastskill show [id]` | `fastskill read <id> --meta` (by id) or `fastskill list` (all) |
| `fastskill show <id> --tree` | `fastskill read <id> --tree` |
| `fastskill sync` | No replacement — agents read the skills directory directly |
| `fastskill disable <id>` | `fastskill remove <id>` |

Shell completion scripts auto-derive from the registered command tree and no longer suggest
the removed commands.

- **`reindex` exits 0 when no embedding provider is configured** (previously exited 1).
If your CI pipeline relied on `reindex` failing to detect missing configuration, switch to
`fastskill doctor` instead.

- **`add`, `install`, `update`, and `remove` now auto-trigger `reindex`** after a successful
run when an embedding provider is configured. Pass `--no-reindex` or set
`auto_reindex = false` in `[tool.fastskill]` of `skill-project.toml` to opt out.

### Added

- **`fastskill doctor`**: new diagnostics command that reports environment readiness
(skills directory, `skill-project.toml`, embedding provider, API key, auth token). Exits 0
when no hard failures; exits 1 when the skills directory is inaccessible. `--json` flag emits
a JSON array of `{check, status, message}` objects.

- **`fastskill read --meta` / `--tree`**: `read` now accepts `--meta` (structured metadata),
`--tree` (dependency tree), `--locked`, `--format`, and `--json`. These flags replace
`fastskill show` entirely.

- **`fastskill search --paths` / `--content`**: local search gains `--paths` (emit absolute
SKILL.md path per result, forces JSON) and `--content <none|preview|full>` (include skill
content). Both flags require `--local`.

- **`auto_reindex` config field**: `[tool.fastskill]` in `skill-project.toml` accepts
`auto_reindex = false` to disable the new automatic reindex side-effect globally.

- **All internal API routes moved from `/api/<path>` to `/api/v1/<path>`.**
Affected endpoints include `/api/skills`, `/api/project`, `/api/status`, `/api/search`,
`/api/resolve`, `/api/reindex`, `/api/registry/…`, and `/api/manifest/…`.
Expand Down
4 changes: 4 additions & 0 deletions crates/fastskill-cli/src/commands/add/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,8 @@ skills_directory = ".claude/skills"
editable: true,
group: None,
recursive: false,
reindex: false,
no_reindex: false,
};

let result = super::super::execute_add(&service, args, false).await;
Expand Down Expand Up @@ -486,6 +488,8 @@ skills_directory = ".claude/skills"
editable: false,
group: None,
recursive: false,
reindex: false,
no_reindex: false,
};

let result = super::super::execute_add(&service, args, false).await;
Expand Down
58 changes: 54 additions & 4 deletions crates/fastskill-cli/src/commands/add/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,14 @@ pub struct AddArgs {
/// Add all skills found under the directory (only for local folders)
#[arg(short = 'r', long)]
pub recursive: bool,

/// Trigger reindex after adding (overrides config)
#[arg(long)]
pub reindex: bool,

/// Skip reindex after adding
#[arg(long)]
pub no_reindex: bool,
}

impl IntoCommandSpec for AddArgs {
Expand Down Expand Up @@ -229,6 +237,24 @@ impl IntoCommandSpec for AddArgs {
help: "Add all skills found under the directory (only for local folders)",
..Default::default()
},
ArgSpec {
name: "reindex",
kind: ArgKind::Flag,
long: Some("reindex"),
value_type: ArgValueType::Bool,
cardinality: Cardinality::Optional,
help: "Trigger reindex after adding (overrides config)",
..Default::default()
},
ArgSpec {
name: "no-reindex",
kind: ArgKind::Flag,
long: Some("no-reindex"),
value_type: ArgValueType::Bool,
cardinality: Cardinality::Optional,
help: "Skip reindex after adding",
..Default::default()
},
],
..Default::default()
}
Expand Down Expand Up @@ -279,6 +305,8 @@ impl FromArgValueMap for AddArgs {
}
}),
recursive: matches!(map.get("recursive"), Some(ArgValue::Bool(true))),
reindex: matches!(map.get("reindex"), Some(ArgValue::Bool(true))),
no_reindex: matches!(map.get("no-reindex"), Some(ArgValue::Bool(true))),
}
}
}
Expand Down Expand Up @@ -332,6 +360,14 @@ fn validate_folder_has_skill(path: &Path) -> CliResult<()> {
}

pub async fn execute_add(service: &FastSkillService, args: AddArgs, global: bool) -> CliResult<()> {
if args.reindex && args.no_reindex {
return Err(CliError::Validation(
"--reindex and --no-reindex cannot be used together".to_string(),
));
}
let reindex = args.reindex;
let no_reindex = args.no_reindex;

let source = resolve_source(&args);

if args.editable {
Expand Down Expand Up @@ -372,16 +408,26 @@ pub async fn execute_add(service: &FastSkillService, args: AddArgs, global: bool
}

match source {
SkillSource::ZipFile(path) => sources::add_from_zip(&ctx, &path).await,
SkillSource::ZipFile(path) => sources::add_from_zip(&ctx, &path).await?,
SkillSource::Folder(path) => {
validate_folder_has_skill(&path)?;
sources::add_from_folder(&ctx, &path).await
sources::add_from_folder(&ctx, &path).await?
}
SkillSource::GitUrl(url) => {
sources::add_from_git(&ctx, &url, args.branch.as_deref(), args.tag.as_deref()).await
sources::add_from_git(&ctx, &url, args.branch.as_deref(), args.tag.as_deref()).await?
}
SkillSource::SkillId(skill_id) => sources::add_from_registry(&ctx, &skill_id).await,
SkillSource::SkillId(skill_id) => sources::add_from_registry(&ctx, &skill_id).await?,
}
let auto_reindex = crate::config_file::load_auto_reindex_config();
crate::utils::reindex_utils::maybe_auto_reindex(
service,
"add",
reindex,
no_reindex,
auto_reindex,
false,
)
.await
}

#[cfg(test)]
Expand Down Expand Up @@ -413,6 +459,8 @@ mod tests {
editable: false,
group: None,
recursive: false,
reindex: false,
no_reindex: false,
};
let result = execute_add(&service, args, false).await;
assert!(result.is_err());
Expand Down Expand Up @@ -468,6 +516,8 @@ mod tests {
editable: false,
group: None,
recursive: false,
reindex: false,
no_reindex: false,
};

let result = execute_add(&service, args, false).await;
Expand Down
7 changes: 4 additions & 3 deletions crates/fastskill-cli/src/commands/analyze/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,10 @@ pub struct AnalysisContext {
}

pub async fn load_analysis_context(svc: &FastSkillService) -> CliResult<Option<AnalysisContext>> {
let vector_svc = svc.vector_index_service().ok_or_else(|| {
CliError::Config("Vector index not available. Run 'fastskill reindex' first.".to_string())
})?;
let Some(vector_svc) = svc.vector_index_service() else {
println!("Note: semantic analysis requires an embedding provider. Results may be limited to structural analysis.");
return Ok(None);
};
let skills = vector_svc
.get_all_skills()
.await
Expand Down
153 changes: 0 additions & 153 deletions crates/fastskill-cli/src/commands/disable.rs

This file was deleted.

Loading
Loading