feat(skills): rebuild the skill system for the multi-user model
Nightly Build / build (push) Successful in 8m6s
Nightly Build / build (push) Successful in 8m6s
Per blueprint/skill-project.md: the old single-namespace, hand-maintained
index is gone, replaced by a read-only, two-scope tree whose index is a
runtime function of its content.
- skills/ index generated at runtime (crates/skald-core/src/skills/:
inventory, install, validate, watch), injected through the new
<!-- SKILLS_LIST --> placeholder in AGENT.md (agents/common/skills.md);
meta.json inject_skills flag removed. 11 chat/task agents carry the
include, the 4 system agents do not.
- Two trees, both read-only in both directions: skills/shared/{id} (the
group's) and skills/{username}/{id} (one member's own, on the stable
userid). The root is closed too: UserFs::SkillMounts + RouteError (alias
probe, plain-denied paths, no home fallback) and a per-user
.skills-root/{userid} container mount with the two scope mounts nested
inside, plus the fifth self-heal axis (skills_mounted).
- Agent verbs: skill_register/skill_delete (Config group, global scope
behind the new skill.manage capability), fetch_repo for public repos,
list_items(type="skills"); reads are plain read_file on the printed
path. Seeded @fs_read skills/* allow.
- Freshness: a digest-gated watcher on the two trees emits
SystemEvent::SkillsChanged, whose subscriber rebuilds the frozen prompt
prefix via Skald::invalidate_prompt_prefix; in-process writers invalidate
directly.
- The build ships no skills: the three bundled skills (ics2json,
mcp-builder, skill-creator) and skills/index.md are removed, skills/ is
instance data (gitignored, not packaged, no longer pruned by update.sh).
- Docs: skills.md, agents.md, shared-folders.md added; docs/index.md and
agents/README.md updated.
This commit is contained in:
@@ -237,6 +237,21 @@ impl Tools {
|
||||
tool_registry.register(crate::tools::set_secret::SetSecret(Arc::clone(&models.secrets)));
|
||||
tool_registry.register(crate::tools::list_secrets::ListSecrets(Arc::clone(&models.secrets)));
|
||||
tool_registry.register(crate::tools::configure_plugin::ConfigurePlugin(Arc::clone(&integrations.plugin_manager)));
|
||||
// The whole write surface of the read-only skills trees (blueprint §7.3):
|
||||
// `Config`-category, so neither appears in a request's schema until
|
||||
// `activate_tools(["config"])` asks. They take the registry to read the
|
||||
// caller's role (`skill.manage` gates the group's scope) and the cell
|
||||
// `Skald::new` later fills, through which an installation reaches
|
||||
// conversations that are already running.
|
||||
tool_registry.register(crate::tools::skills::SkillRegister::new(
|
||||
Arc::clone(&rt.db), Arc::clone(&rt.prompt_prefixes)));
|
||||
tool_registry.register(crate::tools::skills::SkillDelete::new(
|
||||
Arc::clone(&rt.db), Arc::clone(&rt.prompt_prefixes)));
|
||||
// The download half of the skills lifecycle (blueprint §7.5): same
|
||||
// `Config` category, so it too stays out of every request's schema
|
||||
// until `activate_tools(["config"])`. It needs no state of its own —
|
||||
// the container it runs git in comes from each caller's `ToolContext`.
|
||||
tool_registry.register(crate::tools::fetch_repo::FetchRepo);
|
||||
|
||||
// Tools contributed by plugins (plugin.md §11), via `Plugin::tools()`.
|
||||
// The core never names a plugin crate: each one hands over whatever tools
|
||||
|
||||
Reference in New Issue
Block a user