How Skills Are Installed and Model Invocation Is Toggled in pi-web

Pi-web treats skills as reusable plugins managed via SKILL.md files, using an npx-based CLI for installation and a front-matter flag to toggle LLM invocation.

In the agegr/pi-web framework, skills function as modular extensions that enhance project capabilities through markdown-based configuration. Understanding how skills are installed and how model invocation is toggled reveals the architecture behind pi-web's extensible agent system. This guide examines the specific API endpoints, file operations, and source code implementations that manage these workflows.

Skill Installation Architecture

Pi-web installs skills by treating each one as a standalone package that gets written into the project's local file system. The installation process relies on the Node.js package runner to execute CLI commands that fetch and configure skill definitions.

The npx Execution Flow

When you trigger an installation, pi-web delegates package management to the npx runner. The system invokes the skills CLI through the internal runNpx() function defined in lib/npx.ts. This executes the command npx skills add … --agent pi, which downloads the skill package and generates the corresponding SKILL.md file within ./.agents/.

After the CLI completes successfully, pi-web calls DefaultResourceLoader.reload() to refresh the resource loader. This ensures the newly installed skill appears immediately in the user interface without requiring a page refresh.

Installation API Endpoint

The entry point for skill installation is the POST /api/skills/install route, implemented in app/api/skills/install/route.ts. This endpoint receives the package identifier and orchestrates the npx execution chain through lib/npx.ts.

Controlling Model Invocation

Beyond installation, pi-web provides granular control over whether a skill can invoke language models through a simple configuration toggle.

The disable-model-invocation Flag

Model invocation is governed by a YAML front-matter key inside each skill's markdown file:

disable-model-invocation: true

When this flag is present and set to true, the backend logic in lib/skill-lock.ts intercepts skill execution and strips model-related prompts before sending requests to the LLM. This effectively prevents the skill from consuming model resources while keeping the skill itself installed and functional for other operations.

Toggling via PATCH Requests

The UI modifies this flag through the skills API at PATCH /api/skills/[skillId], handled by app/api/skills/[id]/route.ts. The system updates the SKILL.md front-matter and relies on loadSkillsWithInstallInfo() from lib/skills-service.ts to reread the file and reflect the updated configuration state.

Implementation Examples

The following snippets demonstrate how to interact with these systems programmatically.

Installing a Skill

To install a skill such as @example/hello-world:

await fetch('/api/skills/install', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ package: '@example/hello-world' })
});

Disabling Model Invocation

To prevent a skill from calling the LLM:

await fetch('/api/skills/hello-world', {
  method: 'PATCH',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ disableModelInvocation: true })
});

Re-enabling Model Access

To restore model invocation capabilities:

await fetch('/api/skills/hello-world', {
  method: 'PATCH',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ disableModelInvocation: false })
});

Key Source Files

Understanding these components requires familiarity with the specific files that handle skill lifecycle management:

  • lib/skills-service.ts: Contains loadSkillsWithInstallInfo(), which loads skills and annotates them with installation metadata.
  • lib/skill-lock.ts: Manages the disable-model-invocation front-matter flag and synchronizes UI state with file system changes.
  • lib/npx.ts: Provides the runNpx() utility that executes npx commands for skill installation.
  • app/api/skills/install/route.ts: The API route handling POST requests to install new skills.
  • app/api/skills/[id]/route.ts: The API route handling PATCH requests to update skill configuration, including model invocation settings.

Summary

  • Pi-web installs skills via the npx skills CLI, writing SKILL.md files to ./.agents/skills/ and refreshing the DefaultResourceLoader to update the UI.
  • The POST /api/skills/install endpoint in app/api/skills/install/route.ts triggers installation through lib/npx.ts.
  • Model invocation is controlled by the disable-model-invocation front-matter flag in skill markdown files.
  • The PATCH /api/skills/[skillId] endpoint updates this flag, with lib/skill-lock.ts handling the file system operations and prompt stripping.
  • Both workflows maintain state through SKILL.md files and reflect changes immediately without page reloads.

Frequently Asked Questions

Where are skill files stored after installation?

After installation, pi-web writes skill definitions to SKILL.md files within the ./.agents/skills/ directory of your project. These markdown files contain both the skill configuration in YAML front-matter and the operational logic or prompts in the body.

Can I install skills without using the web interface?

Yes. You can call the POST /api/skills/install endpoint directly with the package name, or execute the underlying npx skills add … --agent pi command manually. However, using the API ensures that DefaultResourceLoader.reload() is called to refresh the UI state automatically.

What happens when model invocation is disabled for a skill?

When disable-model-invocation is set to true in a skill's front-matter, lib/skill-lock.ts intercepts execution and strips all model-related prompts before they reach the LLM. The skill remains installed and can perform non-model operations, but it cannot consume language model tokens or generate AI responses.

Is the skill installation persistent across sessions?

Yes. Because skills are written to the file system as SKILL.md files in ./.agents/skills/, they persist across application restarts and browser sessions. The loadSkillsWithInstallInfo() function in lib/skills-service.ts reads these files on startup to reconstruct the available skill set.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →