guide

Plugins & Skills

Extensions come in three layers with a shared idea: everything is a directory with a manifest, nothing executes just by being present.

Skills: a directory with a SKILL.md

A skill is a written procedure for one kind of task — plain instructions the model reads and follows. It is discovered from its frontmatter, and its body is only loaded when the task actually matches.

<data>/skills/<name>/SKILL.md                 ← installed by you
<root>/.agents/skills/<name>/SKILL.md          ← shipped in a repository (cross-agent standard)
<root>/.zlogic/skills/<name>/SKILL.md          ← shipped in a repository (zlogic-specific)

The file needs a ----delimited YAML frontmatter with a description — the model uses it to decide when to read the body, so a skill without a description does not exist (it is skipped and reported). The optional name defaults to the directory name. Frontmatter that zlogic cannot honor yet (allowed_tools, context: fork, model, effort) is reported rather than silently ignored.

---
name: release-notes
description: Draft release notes from the changelog between two git tags.
---

# Body

(Procedure the model follows — written in markdown, loaded on demand.)

Discovery reads only the frontmatter and a one-line description into the system prompt (progressive disclosure); the body is snapshotted into the object store when the skill tool actually loads it. Skills never embed shell execution — if the procedure needs a command, the model decides to run shell, and that call still goes through the normal approval gate. Inside the body, ${SKILL_DIR} and ${SESSION_ID} are expanded when loaded; $ARGUMENTS / $1 are interpreted per invocation.

Name conflicts: the repository wins. A skill in the workspace (.zlogic/ skills or .agents/skills) overrides the user's same-named install — and the conflict is reported, never silent. Enabled plugins contribute skills too, namespaced <plugin>:<skill>.

Installed skills take effect on the next turn; no restart needed.

Plugins: a directory with a manifest

A plugin is a directory containing a manifest, optionally bundling MCP servers (mcpServers in the manifest or a .mcp.json / mcp.json inside the plugin), plus skills/ and agents/ directories:

<data>/extensions/plugins/<name>/              ← installed by you
<root>/.zlogic/extensions/plugins/<name>/      ← shipped in a repository
    plugin.json | plugin.yaml                  ← manifest
    .mcp.json                                  ← or servers in their own file
    skills/<skill-name>/SKILL.md               ← bundled skills
    agents/<agent>.md                          ← bundled sub-agent definitions

Manifest names, in lookup order: plugin.json, plugin.yaml, plugin.yml, zlogic-plugin.json, zlogic-plugin.yaml. A manifest writes ${pluginRoot} / ${ZLOGIC_PLUGIN_ROOT} for paths inside the plugin.

Contributed MCP servers are namespaced <plugin>.<server> so two plugins can each ship a search server, and a plugin can never shadow a server you configured yourself. Plugins may also carry optional tool runtimes that are downloaded on demand (see the Marketplace below).

The identity of a plugin is its directory name; the manifest name is just a label. enabled: false in the manifest (or a .zlogic-disabled marker file in the directory, or a switch in the UI) disables it; agents/commands/hooks directories that zlogic has nowhere to load yet are reported to the person who installed it, never ignored silently.

Plugins ship with the repository arrive with a git clone, and a manifest can name any command on the machine — so the loader only ever reports what it found, carrying an origin that distinguishes repository-supplied definitions (workspace) from your own installs. Trust decisions are made elsewhere: servers that came with the repository are not started until confirmed.

MCP servers declared per workspace

Beyond plugins, a workspace can declare MCP servers directly in the project root .mcp.json (or mcp.json):

{
  "mcpServers": {
    "my-server": {
      "command": "node",
      "args": ["server.js"],
      "env": { "MY_VAR": "value" }
    }
  }
}

HTTP servers use a url field instead. Tool definitions from MCP servers are charged against the context window on every round; when they would exceed ~10% of the window, a notice names the servers instead of silently trimming them — trim with the definition's tool allowlist or the enable switch.

Where things live

What Location (default)
Installed skills ~/.local/share/zlogic/skills/
Installed plugins ~/.local/share/zlogic/extensions/plugins/
Managed MCP servers ~/.local/share/zlogic/extensions/mcp/
Optional runtimes ~/.local/share/zlogic/extensions/runtimes/
Repository skills <project>/.agents/skills/ or <project>/.zlogic/skills/
Repository plugins <project>/.zlogic/extensions/plugins/
Workspace MCP servers <project>/.mcp.json
Global MCP servers ~/.config/zlogic/mcp.json

(Paths use the four XDG-style roots — config / data / state / cache — see Configuration Reference. The site convention ~/.zlogic/… shown in the desktop Marketplace UI strings maps to these same roots.)

The Marketplace (desktop) and installing

The desktop Marketplace view manages plugins, skills, MCP servers and optional runtimes. It offers a curated registry index when one is configured, and two universal install paths:

  • Install from GitHub — paste a repository:
    • owner/repo
    • owner/repo@tag-or-branch (or a full URL)
    • owner/repo#subdir / owner/repo/tree/<ref>/subdir — install one folder from a monorepo
  • Install from local folder — pick a directory:
    • contains plugin.json / plugin.yaml → a plugin
    • contains SKILL.md → a skill
    • contains .mcp.json / mcp.json → an MCP bundle

Installation is a filesystem operation, not plugin execution: GitHub inputs are parsed into owner/repo/ref first, archives are stripped of links and path traversal, and replacement is staged in the managed directory before an atomic rename. A .zlogic-source.json marker records where each install came from.

Capabilities are approved before install. Every source is inspected first and its potentially executable MCP declarations are surfaced as explicit capabilities (process to launch / network endpoint). The install only proceeds when you accept them (accept_capabilities); there is no hidden "install and run". After install you can enable / disable / uninstall at any time; MCP servers contributed by extensions carry their own token credentials (API-key header, bearer token or OAuth, stored in the OS keyring).

Under a remote daemon, local-folder installs are unavailable — the folder would be on the daemon host. Use the GitHub source, or a path that exists on the daemon host.

Managing installed skills and plugins from the CLI

The engine treats skills as first-class in the model's own tooling: the system prompt lists every available skill as a one-line index, the model loads a body with the skill tool, and you invoke one directly as a slash command. Skills discovered on disk are re-read on every turn, so what the prompt lists and what the tool can load can never diverge — and a newly installed skill is available without a restart:

zlogic      # then: /<skill-name> <arguments>

Plugins and their bundled MCP servers are managed from the desktop Marketplace; MCP credentials are managed per server there too (or in config, see Configuration Reference).