# `Agentic.Skill.Service`

Workspace-scoped skill management.

Skills are folders in `workspace/skills/<name>/` containing a SKILL.md file
(YAML frontmatter + markdown body) and optional `scripts/`, `references/`,
and `assets/` directories.

Supports installing skills from GitHub repos in `owner/repo` or
`owner/repo/subpath` format, and searching via the GitHub code search API.

## GitHub Authentication

GitHub API calls work without authentication for public repos (with lower
rate limits). To use authenticated requests, pass a `:get_secret` callback
in opts:

    Service.search("query", get_secret: fn service, key -> {:ok, token} end)

The callback receives `("github", "api_key")` and should return
`{:ok, token}` or `:error`.

# `analyze_model_tier`

```elixir
@spec analyze_model_tier(String.t(), String.t(), keyword()) ::
  {:ok, %{tier: atom(), reasons: [String.t()]}} | {:error, String.t()}
```

Analyze a skill's model tier requirements.

If the skill already has `model_tier` in frontmatter, returns that.
Otherwise runs static analysis and returns the recommended tier with reasons.

Options:
- `:storage` — a `%Storage.Context{}`

# `info`

```elixir
@spec info(
  String.t(),
  keyword()
) :: {:ok, map()} | {:error, String.t()}
```

Fetch detailed information about a skill from GitHub without installing it.

The `repo_spec` can be:
- `"owner/repo"` — looks for SKILL.md at root
- `"owner/repo/path/to/skill"` — skill in a subdirectory

Returns skill metadata (name, description, license, compatibility), full
instructions, GitHub repo stats (stars, description, last push date, license,
language), and the skills.sh audit URL.

Options:
- `:get_secret` — callback for GitHub API authentication
- Other options forwarded to `Req` for testing.

# `install`

```elixir
@spec install(String.t(), String.t(), keyword()) ::
  {:ok, map()} | {:error, String.t()}
```

Install a skill from a GitHub repository into the workspace.

The `repo_spec` can be:
- `"owner/repo"` — installs from repo root (expects SKILL.md at root)
- `"owner/repo/path/to/skill"` — installs from a subdirectory

Options:
- `:storage` — a `%Storage.Context{}`
- `:get_secret` — callback for GitHub API authentication
- Other options forwarded to `Req` for testing.

# `list`

```elixir
@spec list(
  String.t(),
  keyword()
) :: {:ok, [%{name: String.t(), description: String.t()}]}
```

List installed skills with name and description summaries.

Options:
- `:storage` — a `%Storage.Context{}` (default: local backend for workspace_root)

# `read`

```elixir
@spec read(String.t(), String.t(), keyword()) ::
  {:ok, Agentic.Skill.Parser.parsed_skill()} | {:error, String.t()}
```

Read the full parsed SKILL.md content for an installed skill.

Options:
- `:storage` — a `%Storage.Context{}`

# `remove`

```elixir
@spec remove(String.t(), String.t(), keyword()) :: :ok | {:error, String.t()}
```

Remove an installed skill from the workspace.

Options:
- `:storage` — a `%Storage.Context{}`

# `search`

```elixir
@spec search(
  String.t(),
  keyword()
) :: {:ok, [map()]} | {:error, String.t()}
```

Search for skills using the skills CLI (`bun x skills find`).

Falls back to GitHub code search API if `bun` is not available.
The skills CLI does not require authentication.

Options:
- `:get_secret` — callback `fn(service, key) -> {:ok, token} | :error end`
  for GitHub API authentication. Falls back to `GITHUB_TOKEN` env var.
- Other options forwarded to `Req` for testing.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
