Skills

How the built-in skill power scopes skills per Agent, reads SKILL.md, and exposes the agent skill catalog to the Desktop

skill is an Agent's skill catalog. Each Agent has its own skill directory, and that directory is the authoritative set of skills the Agent can use. The power discovers those skills, reads SKILL.md, and injects the inventory into the system prompt.

Skills live at ~/.downcity/agents/<agent-id>/skills. Every entry is a directory containing SKILL.md. An entry is either a copy installed into the Agent directory or a symlink pointing at a skill that lives elsewhere.

The directory sits inside the Agent's own data root, so removing the Agent removes its skills with it. Writing into it is granted to the Agent's shell, which means the Agent can install and link skills itself. The root path comes from the container (PowerContext.data_root_path / PowerLifecycleContext.data_root_path), not from a constructor option.

Scope

The Agent's own directory is the default and authoritative source. Two extra sources are readable on demand:

  • project reads <workspace>/.agents/skills
  • home reads ~/.agents/skills
  • all returns the union of the Agent directory, project, and home

When the same skill ID appears in more than one source, the Agent directory wins, then project, then home.

list and lookup accept the same scope argument, and both default to the Agent directory. The system prompt inventory lists the Agent directory only, so every skill name shown to the model is directly usable without a scope argument.

Actions

ActionPayloadPurpose
list{ scope?: "agent" | "project" | "home" | "all" }List skills in the given scope; defaults to the Agent directory
lookup{ name: string, scope?: ... }Read a skill's SKILL.md

lookup returns the skill body as a standard context message, so the content reaches the model on the next step. It does not persist any session state.

There are no find or install actions. Installation and linking happen either through the Agent's own shell or from the Desktop, because the skills CLI cannot install directly into an Agent skill directory and the copy step needs a decision about what lands there.

The Agent installs in two steps: run the skills CLI inside a temporary directory, then copy the resulting skill into its own directory. The system prompt carries the exact commands, including the npm_config_cache override that keeps npx working inside the sandbox.

Reading project or home through scope does not make those skills available. A skill that lives in the user directory or a workspace becomes usable only after it is copied or linked into the Agent directory, and that entry is what list reports by default.

Listing the Agent's skills:

const result = await city.powers.scope({ agent_id: agent.id, workspace_id: workspace.id }).run_action({
  power: "skill",
  action: "list",
  payload: {},
});

Reading a skill:

const result = await city.powers.scope({ agent_id: agent.id, workspace_id: workspace.id }).run_action({
  power: "skill",
  action: "lookup",
  payload: {
    name: "web-access",
  },
});

The model uses the same protocol inside a Session:

skill({
  action: "lookup",
  args: {
    name: "web-access",
  },
});

Configuration

Skill has no Config panel. Scope is determined by the Agent directory plus the scope argument, so the only constructor option is ignore:

const skill_power = new SkillPower({
  ignore: ["legacy-skill", /^internal-/],
});
  • A string matches both the skill ID and its name.
  • A RegExp filters in bulk.
  • A predicate returning true excludes the skill.

Desktop

The Skills page has two levels. The Sidebar has two peer entries:

  • Catalog lists the skills in the user directory ~/.agents/skills. Each entry shows whether it is already linked, and an Agent selector decides which Agent a link lands on.
  • Agents lists every registered Agent as a flat row, without expanding. Selecting one opens its skill list.

An Agent page shows only that Agent's bound skills, each removable and each openable as SKILL.md.

The only linkable source is the user directory. A workspace .agents/skills does not appear in the interface: to give a skill to an Agent, put it in the user directory first.

Removing a linked skill deletes only the symlink. Operations stay inside the Agent directory.