Skip to main content
ClaudeWave
Skill341 repo starsupdated today

install-skill

The install-skill feature validates and installs SKILL.md files from pasted text, URLs, or file paths into the user-skills directory. Use it when a user requests skill installation, specifying the source; the tool verifies the skill against specification standards, reviews security implications including command execution and credential requirements, and surfaces any missing connectors or credentials needed for operation.

Install in Claude Code
Copy
git clone --depth 1 https://github.com/Lilac-Labs/gini-agent /tmp/install-skill && cp -r /tmp/install-skill/skills/meta/install-skill ~/.claude/skills/install-skill
Then start a new Claude Code session; the skill loads automatically.

SKILL.md

# Install Skill

You install a SKILL.md the user supplied — pasted text, a URL, or a
file path — into the runtime's user-skills directory. You also review risk
and surface the credentials the new skill will need.

## When To Use

- User says "install this skill" with content attached.
- User says "add this skill from this URL".
- User asks you to import a Hermes / OpenClaw / Claude-Code skill.

## Procedure

1. Acquire the SKILL.md text:
   - If the user pasted it, use the pasted content verbatim.
   - If they supplied a URL, fetch with `curl -fsSL <url>`. Refuse if
     the host is not HTTPS unless it's `localhost`.
   - If they supplied a file path, read the file.

2. Validate the SKILL.md against the spec without writing to disk:

   ```bash
   bun run gini skill validate /tmp/incoming-skill.md
   ```

   - Exit code 0 → spec-compliant; continue.
   - Exit code non-zero → repair the obvious issues (kebab-case the
     name, trim the description, move legacy fields under
     `metadata.gini.*`). If the issues are substantive (referencing a
     credential that isn't configured), see step 4.

3. Review the scripts and the body for risk. Read every sidecar file
   the user provided. Summarize for the user:

   - Which commands the skill runs (`bash`, `curl`, `psql`, …).
   - Which env vars / secrets it reads.
   - Whether it can write outside its workspace.
   - Whether it makes outbound network calls and to which hosts.

4. Resolve the credential requirements declared under
   `metadata.gini.requires.credentials` (a list of credential names). An
   incoming skill may instead carry the legacy
   `metadata.gini.requires.connectors` (with `provider:` items); that form
   is still accepted, but rewrite it to `requires.credentials` names
   (e.g. `linear` → `LINEAR_API_KEY`, `google-oauth-desktop` →
   `google-workspace-oauth`) when you install:

   - For each credential name, check `GET /api/connectors` to see whether
     the user already has a healthy credential with that name.
   - If the skill only needs local commands or an already-authenticated CLI
     and does not need a credential-managed account, credential, remote API,
     or local integration, remove the credential requirement. Record
     command requirements under `metadata.gini.prerequisites.commands`.
   - If a required credential is NOT yet configured:
     **Default to forward motion** — but forward motion means "install,
     then prompt," not "install, then stop." Keep the requirement and
     install the skill (step 6). You MUST then prompt for the missing
     credential(s) in chat at step 7 (which is mandatory); do not present
     an install / hold-off binary choice, and do not treat installation as
     the finish line.

5. Surface the `allowed-tools` declaration to the user. Read the
   skill's frontmatter `allowed-tools` value (space-separated) and
   summarize for the user: "This skill declares it will use:
   `<tool list>`. The audit trail records every invocation."

6. Install via the API:

   ```bash
   curl -sS -X POST http://localhost:<runtime-port>/api/skills \
     -H "authorization: Bearer $GINI_TOKEN" \
     -H "content-type: application/json" \
     -d "$(jq -nc \
       --arg body "$(cat /tmp/incoming-skill.md)" \
       '{ body: $body }')"
   ```

   The endpoint writes the file flat under
   `~/.gini/instances/<instance>/skills/<name>/SKILL.md`, triggers a
   loader reload, and returns the new enabled SkillRecord. User-installed
   skills never nest under a category subfolder.

7. **MANDATORY — prompt for every missing credential before you report
   the skill ready. Installing the skill is NOT the end of the task.**
   The install response (step 6) returns the new SkillRecord — use its
   `id` as the `skillId`. Then:

   1. Re-read the installed skill's `metadata.gini.requires.credentials`
      list.
   2. For EACH credential name in that list, check `GET /api/connectors`
      for an existing healthy credential with that name.
   3. For EACH credential that is still missing, you MUST call
      `request_connector` so the user enters it securely. Do this for
      every missing credential — do not skip any, do not batch them into
      prose, do not defer to "the next time the skill runs":
      - Registered provider (the credential name maps to a known module,
        e.g. `LINEAR_API_KEY` → linear): `request_connector` with that
        `provider` id plus `skillId`.
      - No registered provider (a brand-new service): `request_connector`
        with `{name: "<CREDENTIAL_NAME>", type: "<api-key|oauth2>",
        skillId: "<installed skill id>", reason: "<what the credential is
        for and where to get it>"}`. Infer `type` from the name: an
        UPPER_SNAKE env-var token (e.g. `SOME_SERVICE_API_KEY`) is
        `api-key`; a kebab handle is `oauth2`.

   **Do not stop after "installed."** A skill with a missing required
   credential is NOT ready to use — it stays inactive until the credential
   is granted. You may report the skill as ready ONLY when either every
   required credential has been provided (each `request_connector` card
   completed) OR the user has explicitly declined to provide it. If the
   user has not yet responded to a card, the task is still in progress;
   wait for it, do not declare completion.

   Completing the card stores the credential as a typed record AND grants
   it to the installed skill — the skill activates once all its
   credentials are granted, so there is no separate grant step and no
   `/skills` trip. The secure card captures the secret server-side; the
   value never enters the chat transcript.

   The `/skills` page (find the installed skill's row, click the inline
   `[Set up <Credential>]` button) is a fallback only — use it if the
   secure card cannot render (e.g. the conversation is not in the web
   chat).

## Rules

- Always validate before writing. Never install an invalid SKILL.md.
- Always review the scripts for risk before installing.